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

/// 방어구 무게 등급 (armor weight class)
enum ArmorWeight {
  /// 경갑 (light armor)
  light,

  /// 중갑 (heavy armor)
  heavy,

  /// 전체 가능 (all armor)
  all,
}

/// 클래스 패시브 타입 (class passive type)
enum ClassPassiveType {
  /// 물리 공격력 배율 보너스
  physicalDamageBonus,

  /// 방어력 배율 보너스
  defenseBonus,

  /// 회복력 배율 보너스
  healingBonus,

  /// 마법 데미지 배율 보너스
  magicDamageBonus,

  /// 회피율 보너스
  evasionBonus,

  /// 연속 공격 가능
  multiAttack,

  /// 크리티컬 확률 보너스
  criticalBonus,

  /// 첫 공격 배율 보너스
  firstStrikeBonus,

  /// HP 배율 보너스
  hpBonus,

  /// 전투 후 HP 회복 비율
  postCombatHeal,
}

/// 클래스 패시브 능력 (class passive ability)
class ClassPassive {
  const ClassPassive({
    required this.type,
    required this.value,
    this.description = '',
  });

  /// 패시브 타입
  final ClassPassiveType type;

  /// 효과 값 (배율의 경우 0.1 = 10%)
  final double value;

  /// 설명
  final String description;
}

/// 장비 제한 사항 (equipment restriction)
class EquipmentRestriction {
  const EquipmentRestriction({
    this.armorWeight = ArmorWeight.all,
    this.allowedWeaponSlots = const {},
    this.disallowedSlots = const {},
  });

  /// 허용 방어구 무게
  final ArmorWeight armorWeight;

  /// 허용 무기 슬롯 (비어있으면 모두 허용)
  final Set<EquipmentSlot> allowedWeaponSlots;

  /// 금지된 슬롯
  final Set<EquipmentSlot> disallowedSlots;

  /// 전체 허용 (제한 없음)
  static const none = EquipmentRestriction();

  /// 특정 슬롯이 허용되는지 확인
  bool isSlotAllowed(EquipmentSlot slot) {
    if (disallowedSlots.contains(slot)) return false;

    // 무기 슬롯 제한 확인
    if (slot == EquipmentSlot.weapon && allowedWeaponSlots.isNotEmpty) {
      return allowedWeaponSlots.contains(slot);
    }

    return true;
  }
}

/// 클래스 특성 (class traits)
///
/// 각 클래스가 가진 고유한 스탯 보정, 스킬, 장비 제한
class ClassTraits {
  const ClassTraits({
    required this.classId,
    required this.name,
    required this.statModifiers,
    this.startingSkills = const [],
    this.classSkills = const [],
    this.passives = const [],
    this.restriction = EquipmentRestriction.none,
  });

  /// 클래스 식별자
  final String classId;

  /// 클래스 이름 (표시용)
  final String name;

  /// 스탯 보정치 맵
  final Map<StatType, int> statModifiers;

  /// 시작 스킬 ID 목록
  final List<String> startingSkills;

  /// 클래스 전용 스킬 ID 목록
  final List<String> classSkills;

  /// 패시브 능력 목록
  final List<ClassPassive> passives;

  /// 장비 제한
  final EquipmentRestriction restriction;

  /// 특정 스탯의 보정치 반환
  int getModifier(StatType type) => statModifiers[type] ?? 0;

  /// 특정 패시브 타입의 값 반환 (없으면 0)
  double getPassiveValue(ClassPassiveType type) {
    for (final passive in passives) {
      if (passive.type == type) return passive.value;
    }
    return 0.0;
  }

  /// 특정 패시브 보유 여부
  bool hasPassive(ClassPassiveType type) {
    return passives.any((p) => p.type == type);
  }
}
