import 'package:asciineverdie/src/core/model/combat_event.dart';
import 'package:asciineverdie/src/core/model/combat_stats.dart';
import 'package:asciineverdie/src/core/model/monster_combat_stats.dart';
import 'package:asciineverdie/src/core/model/skill.dart';

/// 현재 전투 상태
///
/// 킬 태스크 진행 중 전투 정보를 담는 클래스.
/// Idle 게임 특성상 태스크 바와 동기화되어 진행됨.
class CombatState {
  const CombatState({
    required this.playerStats,
    required this.monsterStats,
    required this.playerAttackAccumulatorMs,
    required this.monsterAttackAccumulatorMs,
    required this.totalDamageDealt,
    required this.totalDamageTaken,
    required this.turnsElapsed,
    required this.isActive,
    this.recentEvents = const [],
    this.activeDoTs = const [],
    this.lastPotionUsedMs = 0,
    this.activeDebuffs = const [],
    this.isFirstPlayerAttack = true,
  });

  /// 플레이어 전투 스탯
  final CombatStats playerStats;

  /// 몬스터 전투 스탯
  final MonsterCombatStats monsterStats;

  /// 플레이어 공격 누적 시간 (밀리초)
  final int playerAttackAccumulatorMs;

  /// 몬스터 공격 누적 시간 (밀리초)
  final int monsterAttackAccumulatorMs;

  /// 플레이어가 입힌 총 데미지
  final int totalDamageDealt;

  /// 플레이어가 받은 총 데미지
  final int totalDamageTaken;

  /// 진행된 턴 수
  final int turnsElapsed;

  /// 전투 활성화 여부
  final bool isActive;

  /// 최근 전투 이벤트 목록 (최대 10개)
  final List<CombatEvent> recentEvents;

  /// 활성 DOT 효과 목록
  final List<DotEffect> activeDoTs;

  /// 마지막 물약 사용 시간 (글로벌 쿨타임용)
  final int lastPotionUsedMs;

  /// 몬스터에 적용된 활성 디버프 목록
  final List<ActiveBuff> activeDebuffs;

  /// 첫 번째 플레이어 공격 여부 (firstStrikeBonus 적용용)
  final bool isFirstPlayerAttack;

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

  /// 전투 종료 여부 (어느 한 쪽이 사망)
  bool get isCombatOver => playerStats.isDead || monsterStats.isDead;

  /// 플레이어 승리 여부
  bool get isPlayerVictory => monsterStats.isDead && playerStats.isAlive;

  /// 플레이어 패배 여부
  bool get isPlayerDefeat => playerStats.isDead;

  /// 플레이어 HP 비율
  double get playerHpRatio => playerStats.hpRatio;

  /// 몬스터 HP 비율
  double get monsterHpRatio => monsterStats.hpRatio;

  /// 물약 사용 가능 여부 (글로벌 쿨타임 체크)
  bool canUsePotion(int currentMs, int cooldownMs) {
    return currentMs - lastPotionUsedMs >= cooldownMs;
  }

  /// 활성 DOT 존재 여부
  bool get hasActiveDoTs => activeDoTs.isNotEmpty;

  /// DOT 총 예상 데미지
  int get totalDotDamageRemaining {
    return activeDoTs.fold(0, (sum, dot) {
      return sum + (dot.damagePerTick * dot.remainingTicks);
    });
  }

  /// 활성 디버프 존재 여부
  bool get hasActiveDebuffs => activeDebuffs.isNotEmpty;

  /// 몬스터에 적용된 총 디버프 효과 계산
  ///
  /// 디버프 효과는 몬스터 ATK/DEF에 부정적 배율로 적용됨
  ({double atkMod, double defMod}) get totalDebuffModifiers {
    double atkMod = 0;
    double defMod = 0;

    for (final debuff in activeDebuffs) {
      atkMod += debuff.effect.atkModifier;
      defMod += debuff.effect.defModifier;
    }

    return (atkMod: atkMod, defMod: defMod);
  }

  CombatState copyWith({
    CombatStats? playerStats,
    MonsterCombatStats? monsterStats,
    int? playerAttackAccumulatorMs,
    int? monsterAttackAccumulatorMs,
    int? totalDamageDealt,
    int? totalDamageTaken,
    int? turnsElapsed,
    bool? isActive,
    List<CombatEvent>? recentEvents,
    List<DotEffect>? activeDoTs,
    int? lastPotionUsedMs,
    List<ActiveBuff>? activeDebuffs,
    bool? isFirstPlayerAttack,
  }) {
    return CombatState(
      playerStats: playerStats ?? this.playerStats,
      monsterStats: monsterStats ?? this.monsterStats,
      playerAttackAccumulatorMs:
          playerAttackAccumulatorMs ?? this.playerAttackAccumulatorMs,
      monsterAttackAccumulatorMs:
          monsterAttackAccumulatorMs ?? this.monsterAttackAccumulatorMs,
      totalDamageDealt: totalDamageDealt ?? this.totalDamageDealt,
      totalDamageTaken: totalDamageTaken ?? this.totalDamageTaken,
      turnsElapsed: turnsElapsed ?? this.turnsElapsed,
      isActive: isActive ?? this.isActive,
      recentEvents: recentEvents ?? this.recentEvents,
      activeDoTs: activeDoTs ?? this.activeDoTs,
      lastPotionUsedMs: lastPotionUsedMs ?? this.lastPotionUsedMs,
      activeDebuffs: activeDebuffs ?? this.activeDebuffs,
      isFirstPlayerAttack: isFirstPlayerAttack ?? this.isFirstPlayerAttack,
    );
  }

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

  /// 새 전투 시작
  factory CombatState.start({
    required CombatStats playerStats,
    required MonsterCombatStats monsterStats,
  }) {
    return CombatState(
      playerStats: playerStats,
      monsterStats: monsterStats,
      playerAttackAccumulatorMs: 0,
      monsterAttackAccumulatorMs: 0,
      totalDamageDealt: 0,
      totalDamageTaken: 0,
      turnsElapsed: 0,
      isActive: true,
    );
  }

  /// 비활성 상태 (전투 없음)
  factory CombatState.inactive() {
    return CombatState(
      playerStats: CombatStats.empty(),
      monsterStats: MonsterCombatStats.empty(),
      playerAttackAccumulatorMs: 0,
      monsterAttackAccumulatorMs: 0,
      totalDamageDealt: 0,
      totalDamageTaken: 0,
      turnsElapsed: 0,
      isActive: false,
    );
  }
}
