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

/// 누적 통계 (Cumulative Statistics)
///
/// GameStatistics에서 분리된 모든 게임 세션의 누적 통계 모델.
class CumulativeStatistics {
  const CumulativeStatistics({
    required this.totalPlayTimeMs,
    required this.totalMonstersKilled,
    required this.totalGoldEarned,
    required this.totalGoldSpent,
    required this.totalSkillsUsed,
    required this.totalCriticalHits,
    required this.bestCriticalStreak,
    required this.totalDamageDealt,
    required this.totalDamageTaken,
    required this.totalPotionsUsed,
    required this.totalItemsSold,
    required this.totalQuestsCompleted,
    required this.totalDeaths,
    required this.totalBossesDefeated,
    required this.totalLevelUps,
    required this.highestLevel,
    required this.highestGoldHeld,
    required this.gamesCompleted,
    required this.gamesStarted,
  });

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

  /// 총 처치한 몬스터 수
  final int totalMonstersKilled;

  /// 총 획득한 골드
  final int totalGoldEarned;

  /// 총 소비한 골드
  final int totalGoldSpent;

  /// 총 스킬 사용 횟수
  final int totalSkillsUsed;

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

  /// 최고 연속 크리티컬
  final int bestCriticalStreak;

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

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

  /// 총 사용한 물약 수
  final int totalPotionsUsed;

  /// 총 판매한 아이템 수
  final int totalItemsSold;

  /// 총 완료한 퀘스트 수
  final int totalQuestsCompleted;

  /// 총 사망 횟수
  final int totalDeaths;

  /// 총 처치한 보스 수
  final int totalBossesDefeated;

  /// 총 레벨업 횟수
  final int totalLevelUps;

  /// 최고 달성 레벨
  final int highestLevel;

  /// 최대 보유 골드
  final int highestGoldHeld;

  /// 클리어한 게임 수
  final int gamesCompleted;

  /// 시작한 게임 수
  final int gamesStarted;

  /// 총 플레이 시간 Duration
  Duration get totalPlayTime => Duration(milliseconds: totalPlayTimeMs);

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

  /// 평균 게임당 플레이 시간
  Duration get averagePlayTimePerGame {
    if (gamesStarted <= 0) return Duration.zero;
    return Duration(milliseconds: totalPlayTimeMs ~/ gamesStarted);
  }

  /// 게임 완료율
  double get completionRate {
    if (gamesStarted <= 0) return 0;
    return gamesCompleted / gamesStarted;
  }

  /// 빈 누적 통계
  factory CumulativeStatistics.empty() => const CumulativeStatistics(
    totalPlayTimeMs: 0,
    totalMonstersKilled: 0,
    totalGoldEarned: 0,
    totalGoldSpent: 0,
    totalSkillsUsed: 0,
    totalCriticalHits: 0,
    bestCriticalStreak: 0,
    totalDamageDealt: 0,
    totalDamageTaken: 0,
    totalPotionsUsed: 0,
    totalItemsSold: 0,
    totalQuestsCompleted: 0,
    totalDeaths: 0,
    totalBossesDefeated: 0,
    totalLevelUps: 0,
    highestLevel: 0,
    highestGoldHeld: 0,
    gamesCompleted: 0,
    gamesStarted: 0,
  );

  /// 세션 통계 병합
  CumulativeStatistics mergeSession(SessionStatistics session) {
    return CumulativeStatistics(
      totalPlayTimeMs: totalPlayTimeMs + session.playTimeMs,
      totalMonstersKilled: totalMonstersKilled + session.monstersKilled,
      totalGoldEarned: totalGoldEarned + session.goldEarned,
      totalGoldSpent: totalGoldSpent + session.goldSpent,
      totalSkillsUsed: totalSkillsUsed + session.skillsUsed,
      totalCriticalHits: totalCriticalHits + session.criticalHits,
      bestCriticalStreak: session.maxCriticalStreak > bestCriticalStreak
          ? session.maxCriticalStreak
          : bestCriticalStreak,
      totalDamageDealt: totalDamageDealt + session.totalDamageDealt,
      totalDamageTaken: totalDamageTaken + session.totalDamageTaken,
      totalPotionsUsed: totalPotionsUsed + session.potionsUsed,
      totalItemsSold: totalItemsSold + session.itemsSold,
      totalQuestsCompleted: totalQuestsCompleted + session.questsCompleted,
      totalDeaths: totalDeaths + session.deathCount,
      totalBossesDefeated: totalBossesDefeated + session.bossesDefeated,
      totalLevelUps: totalLevelUps + session.levelUps,
      highestLevel: highestLevel,
      highestGoldHeld: highestGoldHeld,
      gamesCompleted: gamesCompleted,
      gamesStarted: gamesStarted,
    );
  }

  /// 최고 레벨 업데이트
  CumulativeStatistics updateHighestLevel(int level) {
    if (level <= highestLevel) return this;
    return copyWith(highestLevel: level);
  }

  /// 최대 골드 업데이트
  CumulativeStatistics updateHighestGold(int gold) {
    if (gold <= highestGoldHeld) return this;
    return copyWith(highestGoldHeld: gold);
  }

  /// 새 게임 시작 기록
  CumulativeStatistics recordGameStart() {
    return copyWith(gamesStarted: gamesStarted + 1);
  }

  /// 게임 클리어 기록
  CumulativeStatistics recordGameComplete() {
    return copyWith(gamesCompleted: gamesCompleted + 1);
  }

  CumulativeStatistics copyWith({
    int? totalPlayTimeMs,
    int? totalMonstersKilled,
    int? totalGoldEarned,
    int? totalGoldSpent,
    int? totalSkillsUsed,
    int? totalCriticalHits,
    int? bestCriticalStreak,
    int? totalDamageDealt,
    int? totalDamageTaken,
    int? totalPotionsUsed,
    int? totalItemsSold,
    int? totalQuestsCompleted,
    int? totalDeaths,
    int? totalBossesDefeated,
    int? totalLevelUps,
    int? highestLevel,
    int? highestGoldHeld,
    int? gamesCompleted,
    int? gamesStarted,
  }) {
    return CumulativeStatistics(
      totalPlayTimeMs: totalPlayTimeMs ?? this.totalPlayTimeMs,
      totalMonstersKilled: totalMonstersKilled ?? this.totalMonstersKilled,
      totalGoldEarned: totalGoldEarned ?? this.totalGoldEarned,
      totalGoldSpent: totalGoldSpent ?? this.totalGoldSpent,
      totalSkillsUsed: totalSkillsUsed ?? this.totalSkillsUsed,
      totalCriticalHits: totalCriticalHits ?? this.totalCriticalHits,
      bestCriticalStreak: bestCriticalStreak ?? this.bestCriticalStreak,
      totalDamageDealt: totalDamageDealt ?? this.totalDamageDealt,
      totalDamageTaken: totalDamageTaken ?? this.totalDamageTaken,
      totalPotionsUsed: totalPotionsUsed ?? this.totalPotionsUsed,
      totalItemsSold: totalItemsSold ?? this.totalItemsSold,
      totalQuestsCompleted: totalQuestsCompleted ?? this.totalQuestsCompleted,
      totalDeaths: totalDeaths ?? this.totalDeaths,
      totalBossesDefeated: totalBossesDefeated ?? this.totalBossesDefeated,
      totalLevelUps: totalLevelUps ?? this.totalLevelUps,
      highestLevel: highestLevel ?? this.highestLevel,
      highestGoldHeld: highestGoldHeld ?? this.highestGoldHeld,
      gamesCompleted: gamesCompleted ?? this.gamesCompleted,
      gamesStarted: gamesStarted ?? this.gamesStarted,
    );
  }

  /// JSON 직렬화
  Map<String, dynamic> toJson() {
    return {
      'totalPlayTimeMs': totalPlayTimeMs,
      'totalMonstersKilled': totalMonstersKilled,
      'totalGoldEarned': totalGoldEarned,
      'totalGoldSpent': totalGoldSpent,
      'totalSkillsUsed': totalSkillsUsed,
      'totalCriticalHits': totalCriticalHits,
      'bestCriticalStreak': bestCriticalStreak,
      'totalDamageDealt': totalDamageDealt,
      'totalDamageTaken': totalDamageTaken,
      'totalPotionsUsed': totalPotionsUsed,
      'totalItemsSold': totalItemsSold,
      'totalQuestsCompleted': totalQuestsCompleted,
      'totalDeaths': totalDeaths,
      'totalBossesDefeated': totalBossesDefeated,
      'totalLevelUps': totalLevelUps,
      'highestLevel': highestLevel,
      'highestGoldHeld': highestGoldHeld,
      'gamesCompleted': gamesCompleted,
      'gamesStarted': gamesStarted,
    };
  }

  /// JSON 역직렬화
  factory CumulativeStatistics.fromJson(Map<String, dynamic> json) {
    return CumulativeStatistics(
      totalPlayTimeMs: json['totalPlayTimeMs'] as int? ?? 0,
      totalMonstersKilled: json['totalMonstersKilled'] as int? ?? 0,
      totalGoldEarned: json['totalGoldEarned'] as int? ?? 0,
      totalGoldSpent: json['totalGoldSpent'] as int? ?? 0,
      totalSkillsUsed: json['totalSkillsUsed'] as int? ?? 0,
      totalCriticalHits: json['totalCriticalHits'] as int? ?? 0,
      bestCriticalStreak: json['bestCriticalStreak'] as int? ?? 0,
      totalDamageDealt: json['totalDamageDealt'] as int? ?? 0,
      totalDamageTaken: json['totalDamageTaken'] as int? ?? 0,
      totalPotionsUsed: json['totalPotionsUsed'] as int? ?? 0,
      totalItemsSold: json['totalItemsSold'] as int? ?? 0,
      totalQuestsCompleted: json['totalQuestsCompleted'] as int? ?? 0,
      totalDeaths: json['totalDeaths'] as int? ?? 0,
      totalBossesDefeated: json['totalBossesDefeated'] as int? ?? 0,
      totalLevelUps: json['totalLevelUps'] as int? ?? 0,
      highestLevel: json['highestLevel'] as int? ?? 0,
      highestGoldHeld: json['highestGoldHeld'] as int? ?? 0,
      gamesCompleted: json['gamesCompleted'] as int? ?? 0,
      gamesStarted: json['gamesStarted'] as int? ?? 0,
    );
  }
}
