/// 세션 통계 (Session Statistics)
///
/// GameStatistics에서 분리된 현재 게임 세션의 통계 모델.
class SessionStatistics {
  const SessionStatistics({
    required this.playTimeMs,
    required this.monstersKilled,
    required this.goldEarned,
    required this.goldSpent,
    required this.skillsUsed,
    required this.criticalHits,
    required this.maxCriticalStreak,
    required this.currentCriticalStreak,
    required this.totalDamageDealt,
    required this.totalDamageTaken,
    required this.potionsUsed,
    required this.itemsSold,
    required this.questsCompleted,
    required this.deathCount,
    required this.bossesDefeated,
    required this.levelUps,
  });

  /// 플레이 시간 (밀리초)
  final int playTimeMs;

  /// 처치한 몬스터 수
  final int monstersKilled;

  /// 획득한 골드 총량
  final int goldEarned;

  /// 소비한 골드 총량
  final int goldSpent;

  /// 사용한 스킬 횟수
  final int skillsUsed;

  /// 크리티컬 히트 횟수
  final int criticalHits;

  /// 최대 연속 크리티컬
  final int maxCriticalStreak;

  /// 현재 연속 크리티컬 (내부 추적용)
  final int currentCriticalStreak;

  /// 총 입힌 데미지
  final int totalDamageDealt;

  /// 총 받은 데미지
  final int totalDamageTaken;

  /// 사용한 물약 수
  final int potionsUsed;

  /// 판매한 아이템 수
  final int itemsSold;

  /// 완료한 퀘스트 수
  final int questsCompleted;

  /// 사망 횟수
  final int deathCount;

  /// 처치한 보스 수
  final int bossesDefeated;

  /// 레벨업 횟수
  final int levelUps;

  /// 플레이 시간 Duration
  Duration get playTime => Duration(milliseconds: playTimeMs);

  /// 플레이 시간 포맷 (HH:MM:SS)
  String get formattedPlayTime {
    final hours = playTime.inHours;
    final minutes = playTime.inMinutes % 60;
    final seconds = playTime.inSeconds % 60;
    return '${hours.toString().padLeft(2, '0')}:'
        '${minutes.toString().padLeft(2, '0')}:'
        '${seconds.toString().padLeft(2, '0')}';
  }

  /// 평균 DPS (damage per second)
  double get averageDps {
    if (playTimeMs <= 0) return 0;
    return totalDamageDealt / (playTimeMs / 1000);
  }

  /// 킬당 평균 골드
  double get goldPerKill {
    if (monstersKilled <= 0) return 0;
    return goldEarned / monstersKilled;
  }

  /// 크리티컬 비율
  double get criticalRate {
    if (skillsUsed <= 0) return 0;
    return criticalHits / skillsUsed;
  }

  /// 빈 세션 통계
  factory SessionStatistics.empty() => const SessionStatistics(
    playTimeMs: 0,
    monstersKilled: 0,
    goldEarned: 0,
    goldSpent: 0,
    skillsUsed: 0,
    criticalHits: 0,
    maxCriticalStreak: 0,
    currentCriticalStreak: 0,
    totalDamageDealt: 0,
    totalDamageTaken: 0,
    potionsUsed: 0,
    itemsSold: 0,
    questsCompleted: 0,
    deathCount: 0,
    bossesDefeated: 0,
    levelUps: 0,
  );

  // ============================================================================
  // 이벤트 기록 메서드
  // ============================================================================

  /// 몬스터 처치 기록
  SessionStatistics recordKill({bool isBoss = false}) {
    return copyWith(
      monstersKilled: monstersKilled + 1,
      bossesDefeated: isBoss ? bossesDefeated + 1 : bossesDefeated,
    );
  }

  /// 골드 획득 기록
  SessionStatistics recordGoldEarned(int amount) {
    return copyWith(goldEarned: goldEarned + amount);
  }

  /// 골드 소비 기록
  SessionStatistics recordGoldSpent(int amount) {
    return copyWith(goldSpent: goldSpent + amount);
  }

  /// 스킬 사용 기록
  SessionStatistics recordSkillUse({required bool isCritical}) {
    final newCriticalStreak = isCritical ? currentCriticalStreak + 1 : 0;
    final newMaxStreak = newCriticalStreak > maxCriticalStreak
        ? newCriticalStreak
        : maxCriticalStreak;

    return copyWith(
      skillsUsed: skillsUsed + 1,
      criticalHits: isCritical ? criticalHits + 1 : criticalHits,
      currentCriticalStreak: newCriticalStreak,
      maxCriticalStreak: newMaxStreak,
    );
  }

  /// 데미지 기록
  SessionStatistics recordDamage({int dealt = 0, int taken = 0}) {
    return copyWith(
      totalDamageDealt: totalDamageDealt + dealt,
      totalDamageTaken: totalDamageTaken + taken,
    );
  }

  /// 물약 사용 기록
  SessionStatistics recordPotionUse() {
    return copyWith(potionsUsed: potionsUsed + 1);
  }

  /// 아이템 판매 기록
  SessionStatistics recordItemSold(int count) {
    return copyWith(itemsSold: itemsSold + count);
  }

  /// 퀘스트 완료 기록
  SessionStatistics recordQuestComplete() {
    return copyWith(questsCompleted: questsCompleted + 1);
  }

  /// 사망 기록
  SessionStatistics recordDeath() {
    return copyWith(deathCount: deathCount + 1);
  }

  /// 레벨업 기록
  SessionStatistics recordLevelUp() {
    return copyWith(levelUps: levelUps + 1);
  }

  /// 플레이 시간 업데이트
  SessionStatistics updatePlayTime(int elapsedMs) {
    return copyWith(playTimeMs: elapsedMs);
  }

  SessionStatistics copyWith({
    int? playTimeMs,
    int? monstersKilled,
    int? goldEarned,
    int? goldSpent,
    int? skillsUsed,
    int? criticalHits,
    int? maxCriticalStreak,
    int? currentCriticalStreak,
    int? totalDamageDealt,
    int? totalDamageTaken,
    int? potionsUsed,
    int? itemsSold,
    int? questsCompleted,
    int? deathCount,
    int? bossesDefeated,
    int? levelUps,
  }) {
    return SessionStatistics(
      playTimeMs: playTimeMs ?? this.playTimeMs,
      monstersKilled: monstersKilled ?? this.monstersKilled,
      goldEarned: goldEarned ?? this.goldEarned,
      goldSpent: goldSpent ?? this.goldSpent,
      skillsUsed: skillsUsed ?? this.skillsUsed,
      criticalHits: criticalHits ?? this.criticalHits,
      maxCriticalStreak: maxCriticalStreak ?? this.maxCriticalStreak,
      currentCriticalStreak:
          currentCriticalStreak ?? this.currentCriticalStreak,
      totalDamageDealt: totalDamageDealt ?? this.totalDamageDealt,
      totalDamageTaken: totalDamageTaken ?? this.totalDamageTaken,
      potionsUsed: potionsUsed ?? this.potionsUsed,
      itemsSold: itemsSold ?? this.itemsSold,
      questsCompleted: questsCompleted ?? this.questsCompleted,
      deathCount: deathCount ?? this.deathCount,
      bossesDefeated: bossesDefeated ?? this.bossesDefeated,
      levelUps: levelUps ?? this.levelUps,
    );
  }

  /// JSON 직렬화
  Map<String, dynamic> toJson() {
    return {
      'playTimeMs': playTimeMs,
      'monstersKilled': monstersKilled,
      'goldEarned': goldEarned,
      'goldSpent': goldSpent,
      'skillsUsed': skillsUsed,
      'criticalHits': criticalHits,
      'maxCriticalStreak': maxCriticalStreak,
      'totalDamageDealt': totalDamageDealt,
      'totalDamageTaken': totalDamageTaken,
      'potionsUsed': potionsUsed,
      'itemsSold': itemsSold,
      'questsCompleted': questsCompleted,
      'deathCount': deathCount,
      'bossesDefeated': bossesDefeated,
      'levelUps': levelUps,
    };
  }

  /// JSON 역직렬화
  factory SessionStatistics.fromJson(Map<String, dynamic> json) {
    return SessionStatistics(
      playTimeMs: json['playTimeMs'] as int? ?? 0,
      monstersKilled: json['monstersKilled'] as int? ?? 0,
      goldEarned: json['goldEarned'] as int? ?? 0,
      goldSpent: json['goldSpent'] as int? ?? 0,
      skillsUsed: json['skillsUsed'] as int? ?? 0,
      criticalHits: json['criticalHits'] as int? ?? 0,
      maxCriticalStreak: json['maxCriticalStreak'] as int? ?? 0,
      currentCriticalStreak: 0, // 세션간 유지 안 함
      totalDamageDealt: json['totalDamageDealt'] as int? ?? 0,
      totalDamageTaken: json['totalDamageTaken'] as int? ?? 0,
      potionsUsed: json['potionsUsed'] as int? ?? 0,
      itemsSold: json['itemsSold'] as int? ?? 0,
      questsCompleted: json['questsCompleted'] as int? ?? 0,
      deathCount: json['deathCount'] as int? ?? 0,
      bossesDefeated: json['bossesDefeated'] as int? ?? 0,
      levelUps: json['levelUps'] as int? ?? 0,
    );
  }
}
