/// 아이템 희귀도
enum ItemRarity {
  common,
  uncommon,
  rare,
  epic,
  legendary;

  /// 희귀도 배율 (스탯 계산용)
  double get multiplier => switch (this) {
    common => 1.0,
    uncommon => 1.3,
    rare => 1.7,
    epic => 2.2,
    legendary => 3.0,
  };

  /// 가중치 보너스
  int get weightBonus => switch (this) {
    common => 0,
    uncommon => 50,
    rare => 150,
    epic => 400,
    legendary => 1000,
  };
}

/// 아이템 스탯 보정치
///
/// 장비 아이템이 제공하는 스탯 보너스.
/// 모든 값은 기본 0이며, 장착 시 플레이어 스탯에 가산됨.
class ItemStats {
  const ItemStats({
    this.atk = 0,
    this.def = 0,
    this.magAtk = 0,
    this.magDef = 0,
    this.criRate = 0.0,
    this.evasion = 0.0,
    this.blockRate = 0.0,
    this.parryRate = 0.0,
    this.hpBonus = 0,
    this.mpBonus = 0,
    this.strBonus = 0,
    this.conBonus = 0,
    this.dexBonus = 0,
    this.intBonus = 0,
    this.wisBonus = 0,
    this.chaBonus = 0,
    this.attackSpeed = 0,
  });

  /// 물리 공격력 보정
  final int atk;

  /// 물리 방어력 보정
  final int def;

  /// 마법 공격력 보정
  final int magAtk;

  /// 마법 방어력 보정
  final int magDef;

  /// 크리티컬 확률 보정 (0.0 ~ 1.0)
  final double criRate;

  /// 회피율 보정 (0.0 ~ 1.0)
  final double evasion;

  /// 방패 방어율 (방패 전용, 0.0 ~ 1.0)
  final double blockRate;

  /// 무기 쳐내기 확률 (무기 전용, 0.0 ~ 1.0)
  final double parryRate;

  /// HP 보너스
  final int hpBonus;

  /// MP 보너스
  final int mpBonus;

  /// STR 보너스
  final int strBonus;

  /// CON 보너스
  final int conBonus;

  /// DEX 보너스
  final int dexBonus;

  /// INT 보너스
  final int intBonus;

  /// WIS 보너스
  final int wisBonus;

  /// CHA 보너스
  final int chaBonus;

  /// 무기 공격속도 (밀리초, 무기 전용)
  ///
  /// 0이면 기본값(1000ms) 사용, 값이 클수록 느린 공격.
  /// 느린 무기는 높은 기본 데미지를 가짐.
  final int attackSpeed;

  /// 스탯 합계 (가중치 계산용)
  int get totalStatValue {
    return atk +
        def +
        magAtk +
        magDef +
        (criRate * 100).round() +
        (evasion * 100).round() +
        (blockRate * 100).round() +
        (parryRate * 100).round() +
        hpBonus +
        mpBonus +
        strBonus * 5 +
        conBonus * 5 +
        dexBonus * 5 +
        intBonus * 5 +
        wisBonus * 5 +
        chaBonus * 5;
  }

  /// 빈 스탯 (보너스 없음)
  static const empty = ItemStats();

  /// JSON으로 직렬화
  Map<String, dynamic> toJson() {
    return {
      'atk': atk,
      'def': def,
      'magAtk': magAtk,
      'magDef': magDef,
      'criRate': criRate,
      'evasion': evasion,
      'blockRate': blockRate,
      'parryRate': parryRate,
      'hpBonus': hpBonus,
      'mpBonus': mpBonus,
      'strBonus': strBonus,
      'conBonus': conBonus,
      'dexBonus': dexBonus,
      'intBonus': intBonus,
      'wisBonus': wisBonus,
      'chaBonus': chaBonus,
      'attackSpeed': attackSpeed,
    };
  }

  /// JSON에서 역직렬화
  factory ItemStats.fromJson(Map<String, dynamic> json) {
    return ItemStats(
      atk: json['atk'] as int? ?? 0,
      def: json['def'] as int? ?? 0,
      magAtk: json['magAtk'] as int? ?? 0,
      magDef: json['magDef'] as int? ?? 0,
      criRate: (json['criRate'] as num?)?.toDouble() ?? 0.0,
      evasion: (json['evasion'] as num?)?.toDouble() ?? 0.0,
      blockRate: (json['blockRate'] as num?)?.toDouble() ?? 0.0,
      parryRate: (json['parryRate'] as num?)?.toDouble() ?? 0.0,
      hpBonus: json['hpBonus'] as int? ?? 0,
      mpBonus: json['mpBonus'] as int? ?? 0,
      strBonus: json['strBonus'] as int? ?? 0,
      conBonus: json['conBonus'] as int? ?? 0,
      dexBonus: json['dexBonus'] as int? ?? 0,
      intBonus: json['intBonus'] as int? ?? 0,
      wisBonus: json['wisBonus'] as int? ?? 0,
      chaBonus: json['chaBonus'] as int? ?? 0,
      attackSpeed: json['attackSpeed'] as int? ?? 0,
    );
  }

  /// 두 스탯 합산
  ///
  /// attackSpeed는 합산 대상 아님 (무기 슬롯 단일 값)
  ItemStats operator +(ItemStats other) {
    return ItemStats(
      atk: atk + other.atk,
      def: def + other.def,
      magAtk: magAtk + other.magAtk,
      magDef: magDef + other.magDef,
      criRate: criRate + other.criRate,
      evasion: evasion + other.evasion,
      blockRate: blockRate + other.blockRate,
      parryRate: parryRate + other.parryRate,
      hpBonus: hpBonus + other.hpBonus,
      mpBonus: mpBonus + other.mpBonus,
      strBonus: strBonus + other.strBonus,
      conBonus: conBonus + other.conBonus,
      dexBonus: dexBonus + other.dexBonus,
      intBonus: intBonus + other.intBonus,
      wisBonus: wisBonus + other.wisBonus,
      chaBonus: chaBonus + other.chaBonus,
      // attackSpeed는 무기에서만 직접 참조
    );
  }

  ItemStats copyWith({
    int? atk,
    int? def,
    int? magAtk,
    int? magDef,
    double? criRate,
    double? evasion,
    double? blockRate,
    double? parryRate,
    int? hpBonus,
    int? mpBonus,
    int? strBonus,
    int? conBonus,
    int? dexBonus,
    int? intBonus,
    int? wisBonus,
    int? chaBonus,
    int? attackSpeed,
  }) {
    return ItemStats(
      atk: atk ?? this.atk,
      def: def ?? this.def,
      magAtk: magAtk ?? this.magAtk,
      magDef: magDef ?? this.magDef,
      criRate: criRate ?? this.criRate,
      evasion: evasion ?? this.evasion,
      blockRate: blockRate ?? this.blockRate,
      parryRate: parryRate ?? this.parryRate,
      hpBonus: hpBonus ?? this.hpBonus,
      mpBonus: mpBonus ?? this.mpBonus,
      strBonus: strBonus ?? this.strBonus,
      conBonus: conBonus ?? this.conBonus,
      dexBonus: dexBonus ?? this.dexBonus,
      intBonus: intBonus ?? this.intBonus,
      wisBonus: wisBonus ?? this.wisBonus,
      chaBonus: chaBonus ?? this.chaBonus,
      attackSpeed: attackSpeed ?? this.attackSpeed,
    );
  }
}
