import 'package:asciineverdie/src/core/model/skill.dart';
import 'package:asciineverdie/src/core/model/skill_slots.dart';

/// 스킬 시스템 상태 (Phase 3)
///
/// 스킬 쿨타임, 활성 버프, 게임 경과 시간, 장착 스킬 등을 관리
class SkillSystemState {
  const SkillSystemState({
    required this.skillStates,
    required this.activeBuffs,
    required this.elapsedMs,
    this.equippedSkills = const SkillSlots(),
    this.globalCooldownEndMs = 0,
  });

  /// 글로벌 쿨타임 (GCD) 상수: 1500ms
  static const int globalCooldownDuration = 1500;

  /// 스킬별 쿨타임 상태
  final List<SkillState> skillStates;

  /// 현재 활성화된 버프 목록
  final List<ActiveBuff> activeBuffs;

  /// 게임 진행 경과 시간 (밀리초, 스킬 쿨타임 계산용)
  final int elapsedMs;

  /// 장착된 스킬 슬롯 (타입별 제한 있음)
  final SkillSlots equippedSkills;

  /// 글로벌 쿨타임 종료 시점 (elapsedMs 기준)
  final int globalCooldownEndMs;

  /// GCD가 활성화 중인지 확인
  bool get isGlobalCooldownActive => elapsedMs < globalCooldownEndMs;

  /// 남은 GCD 시간 (ms)
  int get remainingGlobalCooldown =>
      isGlobalCooldownActive ? globalCooldownEndMs - elapsedMs : 0;

  factory SkillSystemState.empty() => const SkillSystemState(
    skillStates: [],
    activeBuffs: [],
    elapsedMs: 0,
    equippedSkills: SkillSlots(),
    globalCooldownEndMs: 0,
  );

  /// 특정 스킬 상태 가져오기
  SkillState? getSkillState(String skillId) {
    for (final state in skillStates) {
      if (state.skillId == skillId) return state;
    }
    return null;
  }

  /// 버프 효과 합산 (동일 버프는 중복 적용 안 됨)
  ({double atkMod, double defMod, double criMod, double evasionMod})
  get totalBuffModifiers {
    double atkMod = 0;
    double defMod = 0;
    double criMod = 0;
    double evasionMod = 0;

    final seenBuffIds = <String>{};
    for (final buff in activeBuffs) {
      if (seenBuffIds.contains(buff.effect.id)) continue;
      seenBuffIds.add(buff.effect.id);

      if (!buff.isExpired(elapsedMs)) {
        atkMod += buff.effect.atkModifier;
        defMod += buff.effect.defModifier;
        criMod += buff.effect.criRateModifier;
        evasionMod += buff.effect.evasionModifier;
      }
    }

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

  SkillSystemState copyWith({
    List<SkillState>? skillStates,
    List<ActiveBuff>? activeBuffs,
    int? elapsedMs,
    SkillSlots? equippedSkills,
    int? globalCooldownEndMs,
  }) {
    return SkillSystemState(
      skillStates: skillStates ?? this.skillStates,
      activeBuffs: activeBuffs ?? this.activeBuffs,
      elapsedMs: elapsedMs ?? this.elapsedMs,
      equippedSkills: equippedSkills ?? this.equippedSkills,
      globalCooldownEndMs: globalCooldownEndMs ?? this.globalCooldownEndMs,
    );
  }

  /// GCD 시작 (스킬 사용 후 호출)
  SkillSystemState startGlobalCooldown() {
    return copyWith(globalCooldownEndMs: elapsedMs + globalCooldownDuration);
  }
}
