import 'package:asciineverdie/src/core/model/equipment_item.dart';
import 'package:asciineverdie/src/core/model/equipment_slot.dart';
import 'package:asciineverdie/src/core/model/item_stats.dart';

/// 장비 (원본 Main.dfm Equips ListView, 11개 슬롯)
///
/// Phase 2에서 EquipmentItem 기반으로 확장됨.
/// 기존 문자열 API(weapon, shield 등)는 호환성을 위해 유지.
class Equipment {
  Equipment({required this.items, required this.bestIndex})
    : assert(items.length == slotCount, 'Equipment must have $slotCount items');

  /// 장비 아이템 목록 (11개 슬롯)
  final List<EquipmentItem> items;

  /// 최고 아이템 슬롯 인덱스 (원본 Equips.Tag, 0-10)
  final int bestIndex;

  /// 슬롯 개수
  static const slotCount = 11;

  // ==========================================================================
  // 문자열 API (기존 코드 호환성)
  // ==========================================================================

  String get weapon => items[0].name; // 0: 무기
  String get shield => items[1].name; // 1: 방패
  String get helm => items[2].name; // 2: 투구
  String get hauberk => items[3].name; // 3: 사슬갑옷
  String get brassairts => items[4].name; // 4: 상완갑
  String get vambraces => items[5].name; // 5: 전완갑
  String get gauntlets => items[6].name; // 6: 건틀릿
  String get gambeson => items[7].name; // 7: 갬비슨
  String get cuisses => items[8].name; // 8: 허벅지갑
  String get greaves => items[9].name; // 9: 정강이갑
  String get sollerets => items[10].name; // 10: 철제신발

  // ==========================================================================
  // EquipmentItem API
  // ==========================================================================

  EquipmentItem get weaponItem => items[0];
  EquipmentItem get shieldItem => items[1];
  EquipmentItem get helmItem => items[2];
  EquipmentItem get hauberkItem => items[3];
  EquipmentItem get brassairtsItem => items[4];
  EquipmentItem get vambracesItem => items[5];
  EquipmentItem get gauntletsItem => items[6];
  EquipmentItem get gambesonItem => items[7];
  EquipmentItem get cuissesItem => items[8];
  EquipmentItem get greavesItem => items[9];
  EquipmentItem get solleretsItem => items[10];

  /// 모든 장비 스탯 합산
  ItemStats get totalStats {
    return items.fold(ItemStats.empty, (sum, item) => sum + item.stats);
  }

  /// 모든 장비 무게 합산
  int get totalWeight {
    return items.fold(0, (sum, item) => sum + item.weight);
  }

  /// 장착된 아이템 목록 (빈 슬롯 제외)
  List<EquipmentItem> get equippedItems {
    return items.where((item) => item.isNotEmpty).toList();
  }

  // ==========================================================================
  // 팩토리 메서드
  // ==========================================================================

  factory Equipment.empty() {
    return Equipment(
      items: [
        EquipmentItem.defaultWeapon(), // 0: 무기 (Keyboard)
        EquipmentItem.empty(EquipmentSlot.shield), // 1: 방패
        EquipmentItem.empty(EquipmentSlot.helm), // 2: 투구
        EquipmentItem.empty(EquipmentSlot.hauberk), // 3: 사슬갑옷
        EquipmentItem.empty(EquipmentSlot.brassairts), // 4: 상완갑
        EquipmentItem.empty(EquipmentSlot.vambraces), // 5: 전완갑
        EquipmentItem.empty(EquipmentSlot.gauntlets), // 6: 건틀릿
        EquipmentItem.empty(EquipmentSlot.gambeson), // 7: 갬비슨
        EquipmentItem.empty(EquipmentSlot.cuisses), // 8: 허벅지갑
        EquipmentItem.empty(EquipmentSlot.greaves), // 9: 정강이갑
        EquipmentItem.empty(EquipmentSlot.sollerets), // 10: 철제신발
      ],
      bestIndex: 0,
    );
  }

  /// 초보자 장비 세트 (모든 슬롯에 기본 방어구 지급)
  ///
  /// 원본 PQ에서는 초기 장비가 없지만, 밸런스 개선을 위해
  /// Act 1 완료 전에도 기본 방어력을 제공.
  factory Equipment.withStarterGear() {
    return Equipment(
      items: [
        EquipmentItem.defaultWeapon(), // 0: 무기 (Keyboard)
        _starterArmor('Old Mouse', EquipmentSlot.shield, def: 2),
        _starterArmor('Cardboard Box', EquipmentSlot.helm, def: 1),
        _starterArmor('Worn T-Shirt', EquipmentSlot.hauberk, def: 3),
        _starterArmor('Rubber Band', EquipmentSlot.brassairts, def: 1),
        _starterArmor('Wristwatch', EquipmentSlot.vambraces, def: 1),
        _starterArmor('Fingerless Gloves', EquipmentSlot.gauntlets, def: 1),
        _starterArmor('Hoodie', EquipmentSlot.gambeson, def: 2),
        _starterArmor('Jeans', EquipmentSlot.cuisses, def: 2),
        _starterArmor('Knee Pads', EquipmentSlot.greaves, def: 1),
        _starterArmor('Sneakers', EquipmentSlot.sollerets, def: 1),
      ],
      bestIndex: 0,
    );
  }

  /// 초보자 방어구 생성 헬퍼
  static EquipmentItem _starterArmor(
    String name,
    EquipmentSlot slot, {
    required int def,
  }) {
    return EquipmentItem(
      name: name,
      slot: slot,
      level: 1,
      weight: 1,
      stats: ItemStats(def: def),
      rarity: ItemRarity.common,
    );
  }

  /// 레거시 문자열 기반 생성자 (세이브 파일 호환용)
  factory Equipment.fromStrings({
    required String weapon,
    required String shield,
    required String helm,
    required String hauberk,
    required String brassairts,
    required String vambraces,
    required String gauntlets,
    required String gambeson,
    required String cuisses,
    required String greaves,
    required String sollerets,
    required int bestIndex,
  }) {
    return Equipment(
      items: [
        _itemFromString(weapon, EquipmentSlot.weapon),
        _itemFromString(shield, EquipmentSlot.shield),
        _itemFromString(helm, EquipmentSlot.helm),
        _itemFromString(hauberk, EquipmentSlot.hauberk),
        _itemFromString(brassairts, EquipmentSlot.brassairts),
        _itemFromString(vambraces, EquipmentSlot.vambraces),
        _itemFromString(gauntlets, EquipmentSlot.gauntlets),
        _itemFromString(gambeson, EquipmentSlot.gambeson),
        _itemFromString(cuisses, EquipmentSlot.cuisses),
        _itemFromString(greaves, EquipmentSlot.greaves),
        _itemFromString(sollerets, EquipmentSlot.sollerets),
      ],
      bestIndex: bestIndex,
    );
  }

  /// 문자열에서 기본 EquipmentItem 생성 (레거시 호환)
  static EquipmentItem _itemFromString(String name, EquipmentSlot slot) {
    if (name.isEmpty) {
      return EquipmentItem.empty(slot);
    }
    // 레거시 아이템: 레벨 1, Common, 기본 스탯
    return EquipmentItem(
      name: name,
      slot: slot,
      level: 1,
      weight: 5,
      stats: ItemStats.empty,
      rarity: ItemRarity.common,
    );
  }

  // ==========================================================================
  // 유틸리티 메서드
  // ==========================================================================

  /// 인덱스로 슬롯 이름 가져오기 (기존 API 호환)
  String getByIndex(int index) {
    if (index < 0 || index >= slotCount) return '';
    return items[index].name;
  }

  /// 인덱스로 EquipmentItem 가져오기
  EquipmentItem getItemByIndex(int index) {
    if (index < 0 || index >= slotCount) {
      return EquipmentItem.empty(EquipmentSlot.weapon);
    }
    return items[index];
  }

  /// 인덱스로 슬롯 값 설정 (문자열, 기존 API 호환)
  Equipment setByIndex(int index, String value) {
    if (index < 0 || index >= slotCount) return this;
    final slot = EquipmentSlot.values[index];
    final newItem = _itemFromString(value, slot);
    return setItemByIndex(index, newItem);
  }

  /// 인덱스로 EquipmentItem 설정
  Equipment setItemByIndex(int index, EquipmentItem item) {
    if (index < 0 || index >= slotCount) return this;
    final newItems = List<EquipmentItem>.from(items);
    newItems[index] = item;
    return Equipment(items: newItems, bestIndex: bestIndex);
  }

  Equipment copyWith({List<EquipmentItem>? items, int? bestIndex}) {
    return Equipment(
      items: items ?? List<EquipmentItem>.from(this.items),
      bestIndex: bestIndex ?? this.bestIndex,
    );
  }
}
