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

/// 장비 아이템
///
/// 개별 장비의 이름, 슬롯, 레벨, 스탯 등을 포함하는 클래스.
/// 불변(immutable) 객체로 설계됨.
class EquipmentItem {
  const EquipmentItem({
    required this.name,
    required this.slot,
    required this.level,
    required this.weight,
    required this.stats,
    required this.rarity,
  });

  /// 아이템 이름 (예: "Flaming Sword of Doom")
  final String name;

  /// 장착 슬롯
  final EquipmentSlot slot;

  /// 아이템 레벨
  final int level;

  /// 무게 (STR 기반 휴대 제한용)
  final int weight;

  /// 아이템 스탯 보정치
  final ItemStats stats;

  /// 희귀도
  final ItemRarity rarity;

  /// 가중치 (자동 장착 비교용)
  ///
  /// 가중치 = 기본값 + (레벨 * 10) + (희귀도 보너스) + (스탯 합계)
  int get itemWeight {
    const baseValue = 10;
    return baseValue + (level * 10) + rarity.weightBonus + stats.totalStatValue;
  }

  /// 빈 아이템 여부
  bool get isEmpty => name.isEmpty;

  /// 유효한 아이템 여부
  bool get isNotEmpty => name.isNotEmpty;

  /// 빈 아이템 생성 (특정 슬롯)
  factory EquipmentItem.empty(EquipmentSlot slot) {
    return EquipmentItem(
      name: '',
      slot: slot,
      level: 0,
      weight: 0,
      stats: ItemStats.empty,
      rarity: ItemRarity.common,
    );
  }

  /// 기본 무기 (Keyboard)
  factory EquipmentItem.defaultWeapon() {
    return const EquipmentItem(
      name: 'Keyboard',
      slot: EquipmentSlot.weapon,
      level: 1,
      weight: 5,
      stats: ItemStats(atk: 1, attackSpeed: 1000),
      rarity: ItemRarity.common,
    );
  }

  EquipmentItem copyWith({
    String? name,
    EquipmentSlot? slot,
    int? level,
    int? weight,
    ItemStats? stats,
    ItemRarity? rarity,
  }) {
    return EquipmentItem(
      name: name ?? this.name,
      slot: slot ?? this.slot,
      level: level ?? this.level,
      weight: weight ?? this.weight,
      stats: stats ?? this.stats,
      rarity: rarity ?? this.rarity,
    );
  }

  /// JSON으로 직렬화
  Map<String, dynamic> toJson() {
    return {
      'name': name,
      'slot': slot.name,
      'level': level,
      'weight': weight,
      'stats': stats.toJson(),
      'rarity': rarity.name,
    };
  }

  /// JSON에서 역직렬화
  factory EquipmentItem.fromJson(Map<String, dynamic> json) {
    final slotName = json['slot'] as String? ?? 'weapon';
    final rarityName = json['rarity'] as String? ?? 'common';

    return EquipmentItem(
      name: json['name'] as String? ?? '',
      slot: EquipmentSlot.values.firstWhere(
        (s) => s.name == slotName,
        orElse: () => EquipmentSlot.weapon,
      ),
      level: json['level'] as int? ?? 0,
      weight: json['weight'] as int? ?? 0,
      stats: json['stats'] != null
          ? ItemStats.fromJson(json['stats'] as Map<String, dynamic>)
          : ItemStats.empty,
      rarity: ItemRarity.values.firstWhere(
        (r) => r.name == rarityName,
        orElse: () => ItemRarity.common,
      ),
    );
  }

  @override
  String toString() => name.isEmpty ? '(empty)' : name;
}
