import 'package:asciineverdie/src/core/model/combat_stats.dart';
import 'package:asciineverdie/src/core/util/balance_constants.dart';

/// 몬스터 공격 속도 타입
enum MonsterSpeedType {
  /// 빠름 (600ms)
  fast,

  /// 보통 (1000ms)
  normal,

  /// 느림 (1400ms)
  slow,
}

/// 몬스터 전투 스탯
///
/// 플레이어 레벨과 몬스터 기본 레벨을 기반으로 계산되는 전투 관련 수치.
class MonsterCombatStats {
  const MonsterCombatStats({
    required this.name,
    required this.level,
    required this.atk,
    required this.def,
    required this.magDef,
    required this.hpMax,
    required this.hpCurrent,
    required this.criRate,
    required this.criDamage,
    required this.evasion,
    required this.accuracy,
    required this.attackDelayMs,
    required this.expReward,
  });

  /// 몬스터 표시 이름 (형용사 포함)
  final String name;

  /// 몬스터 레벨
  final int level;

  /// 공격력
  final int atk;

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

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

  /// 최대 HP
  final int hpMax;

  /// 현재 HP
  final int hpCurrent;

  /// 크리티컬 확률 (0.0 ~ 0.3)
  final double criRate;

  /// 크리티컬 데미지 배율 (1.3 ~ 2.0)
  final double criDamage;

  /// 회피율 (0.0 ~ 0.3)
  final double evasion;

  /// 명중률 (0.7 ~ 0.95)
  final double accuracy;

  /// 공격 딜레이 (밀리초)
  final int attackDelayMs;

  /// 처치 시 경험치 보상
  final int expReward;

  // ============================================================================
  // 유틸리티
  // ============================================================================

  /// HP 비율 (0.0 ~ 1.0)
  double get hpRatio => hpMax > 0 ? hpCurrent / hpMax : 0.0;

  /// 생존 여부
  bool get isAlive => hpCurrent > 0;

  /// 사망 여부
  bool get isDead => hpCurrent <= 0;

  /// HP 변경된 새 인스턴스 반환
  MonsterCombatStats withHp(int newHp) {
    return copyWith(hpCurrent: newHp.clamp(0, hpMax));
  }

  /// 데미지 적용된 새 인스턴스 반환
  MonsterCombatStats applyDamage(int damage) {
    return withHp(hpCurrent - damage);
  }

  MonsterCombatStats copyWith({
    String? name,
    int? level,
    int? atk,
    int? def,
    int? magDef,
    int? hpMax,
    int? hpCurrent,
    double? criRate,
    double? criDamage,
    double? evasion,
    double? accuracy,
    int? attackDelayMs,
    int? expReward,
  }) {
    return MonsterCombatStats(
      name: name ?? this.name,
      level: level ?? this.level,
      atk: atk ?? this.atk,
      def: def ?? this.def,
      magDef: magDef ?? this.magDef,
      hpMax: hpMax ?? this.hpMax,
      hpCurrent: hpCurrent ?? this.hpCurrent,
      criRate: criRate ?? this.criRate,
      criDamage: criDamage ?? this.criDamage,
      evasion: evasion ?? this.evasion,
      accuracy: accuracy ?? this.accuracy,
      attackDelayMs: attackDelayMs ?? this.attackDelayMs,
      expReward: expReward ?? this.expReward,
    );
  }

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

  /// 몬스터 레벨에서 전투 스탯 생성
  ///
  /// [name] 몬스터 표시 이름
  /// [level] 몬스터 레벨 (원본 데이터 기준)
  /// [speedType] 공격 속도 타입 (기본: normal)
  /// [monsterType] 몬스터 타입 (기본: normal)
  /// [plotStageCount] 현재 Act (1=Prologue, 2=Act I, 3=Act II, ...)
  factory MonsterCombatStats.fromLevel({
    required String name,
    required int level,
    MonsterSpeedType speedType = MonsterSpeedType.normal,
    MonsterType monsterType = MonsterType.normal,
    int plotStageCount = 1,
  }) {
    // balance_constants.dart의 MonsterBaseStats 사용
    final baseStats = MonsterBaseStats.generate(level, monsterType);

    // Act II 이후 (plotStageCount >= 3) HP 10% 상승
    final hpMultiplier = plotStageCount >= 3 ? 1.1 : 1.0;
    final adjustedHp = (baseStats.hp * hpMultiplier).round();

    // Act별 경험치 배율 (후반부 레벨업 가속)
    final expMultiplier = switch (plotStageCount) {
      5 => 1.3, // Act IV: 30% 보너스
      6 => 1.8, // Act V: 80% 보너스 (보스전 대비)
      _ => 1.0, // 기본
    };
    final adjustedExp = (baseStats.exp * expMultiplier).round();

    // 크리티컬 확률: 레벨에 따라 천천히 증가 (0.02 ~ 0.3)
    final criRate = (0.02 + level * 0.003).clamp(0.02, 0.3);

    // 크리티컬 데미지: 고정 1.5배 (몬스터는 플레이어보다 낮음)
    const criDamage = 1.5;

    // 회피율: 레벨에 따라 천천히 증가 (0.0 ~ 0.3)
    final evasion = (level * 0.003).clamp(0.0, 0.3);

    // 명중률: 레벨에 따라 증가 (0.7 ~ 0.95)
    final accuracy = (0.7 + level * 0.003).clamp(0.7, 0.95);

    // 공격 딜레이: 타입에 따라 결정
    final attackDelayMs = switch (speedType) {
      MonsterSpeedType.fast => 600,
      MonsterSpeedType.normal => 1000,
      MonsterSpeedType.slow => 1400,
    };

    // 마법 방어력: 물리 방어력의 70~130% (레벨에 따라 변동)
    final magDefRatio = 0.7 + (level % 60) * 0.01; // 0.7 ~ 1.3
    final magDef = (baseStats.def * magDefRatio).round();

    return MonsterCombatStats(
      name: name,
      level: level,
      atk: baseStats.atk,
      def: baseStats.def,
      magDef: magDef,
      hpMax: adjustedHp,
      hpCurrent: adjustedHp,
      criRate: criRate,
      criDamage: criDamage,
      evasion: evasion,
      accuracy: accuracy,
      attackDelayMs: attackDelayMs,
      expReward: adjustedExp,
    );
  }

  /// 최종 보스 (Glitch God) 생성
  ///
  /// Act V 완료 시 등장하는 최종 보스.
  /// balance_constants.dart의 BossStats.glitchGod 기반.
  factory MonsterCombatStats.glitchGod() {
    const bossLevel = 100;
    final bossStats = BossStats.glitchGod(bossLevel);

    return MonsterCombatStats(
      name: 'The Primordial Glitch',
      level: bossLevel,
      atk: bossStats.atk,
      def: bossStats.def,
      magDef: (bossStats.def * 1.2).round(), // 보스는 마법 방어력 20% 증가
      hpMax: bossStats.hp,
      hpCurrent: bossStats.hp,
      criRate: 0.25, // 보스 크리티컬 확률 25%
      criDamage: 2.0, // 보스 크리티컬 데미지 200%
      evasion: 0.15, // 보스 회피율 15%
      accuracy: 0.95, // 보스 명중률 95%
      attackDelayMs: 800, // 보스 공격 속도 (빠름)
      expReward: bossStats.exp,
    );
  }

  /// 몬스터 이름에서 속도 타입 추론
  ///
  /// 특정 키워드 기반으로 속도 결정 (향후 확장 가능)
  static MonsterSpeedType inferSpeedType(String monsterName) {
    final lowerName = monsterName.toLowerCase();

    // 빠른 몬스터 키워드
    if (lowerName.contains('ghost') ||
        lowerName.contains('phantom') ||
        lowerName.contains('wisp') ||
        lowerName.contains('sprite')) {
      return MonsterSpeedType.fast;
    }

    // 느린 몬스터 키워드
    if (lowerName.contains('golem') ||
        lowerName.contains('giant') ||
        lowerName.contains('titan') ||
        lowerName.contains('dragon')) {
      return MonsterSpeedType.slow;
    }

    return MonsterSpeedType.normal;
  }

  /// 테스트/디버그용 기본값
  factory MonsterCombatStats.empty() => const MonsterCombatStats(
    name: 'Test Monster',
    level: 1,
    atk: 8,
    def: 3,
    magDef: 3,
    hpMax: 35,
    hpCurrent: 35,
    criRate: 0.02,
    criDamage: 1.5,
    evasion: 0.0,
    accuracy: 0.7,
    attackDelayMs: 1000,
    expReward: 15,
  );

  /// CombatStats에서 MonsterCombatStats 생성 (아레나 PvP용)
  ///
  /// 플레이어의 CombatStats를 몬스터 형태로 변환하여
  /// 기존 CombatCalculator를 재사용할 수 있게 함.
  factory MonsterCombatStats.fromCombatStats(CombatStats stats, String name) {
    return MonsterCombatStats(
      name: name,
      level: 0, // PvP에서는 레벨 페널티 없음
      atk: stats.atk,
      def: stats.def,
      magDef: stats.magDef,
      hpMax: stats.hpMax,
      hpCurrent: stats.hpMax, // 풀 HP로 시작
      criRate: stats.criRate,
      criDamage: stats.criDamage,
      evasion: stats.evasion,
      accuracy: stats.accuracy,
      attackDelayMs: stats.attackDelayMs,
      expReward: 0, // PvP에서는 경험치 없음
    );
  }
}
