import 'dart:async';

import 'package:asciineverdie/src/core/model/game_state.dart';
import 'package:asciineverdie/src/core/model/game_statistics.dart';
import 'package:asciineverdie/src/core/storage/statistics_storage.dart';

/// 게임 통계 추적 및 관리를 담당하는 매니저
///
/// 세션 통계와 누적 통계를 관리하고, 게임 상태 변화에 따라
/// 통계를 자동 업데이트합니다.
class GameStatisticsManager {
  GameStatisticsManager({StatisticsStorage? statisticsStorage})
    : _statisticsStorage = statisticsStorage ?? StatisticsStorage();

  final StatisticsStorage _statisticsStorage;

  // 현재 세션 통계
  SessionStatistics _sessionStats = SessionStatistics.empty();

  // 누적 통계
  CumulativeStatistics _cumulativeStats = CumulativeStatistics.empty();

  // 이전 값 (변화 감지용)
  int _previousLevel = 0;
  int _previousGold = 0;
  int _previousMonstersKilled = 0;
  int _previousQuestsCompleted = 0;

  /// 현재 세션 통계
  SessionStatistics get sessionStats => _sessionStats;

  /// 누적 통계
  CumulativeStatistics get cumulativeStats => _cumulativeStats;

  /// 새 게임 시작 시 통계 초기화
  Future<void> initializeForNewGame() async {
    _sessionStats = SessionStatistics.empty();
    await _statisticsStorage.recordGameStart();
  }

  /// 게임 로드 시 통계 복원
  void restoreFromLoadedGame(GameState state) {
    _sessionStats = _sessionStats.copyWith(
      deathCount: state.progress.deathCount,
      questsCompleted: state.progress.questCount,
      monstersKilled: state.progress.monstersKilled,
      playTimeMs: state.skillSystem.elapsedMs,
    );
  }

  /// 이전 값 초기화 (통계 변화 추적용)
  void initPreviousValues(GameState state) {
    _previousLevel = state.traits.level;
    _previousGold = state.inventory.gold;
    _previousMonstersKilled = state.progress.monstersKilled;
    _previousQuestsCompleted = state.progress.questCount;
  }

  /// 상태 변화에 따른 통계 업데이트
  ///
  /// 매 틱마다 호출되어 레벨업, 골드, 몬스터 처치, 퀘스트 완료 등을 추적
  void updateStatistics(GameState next) {
    // 플레이 시간 업데이트
    _sessionStats = _sessionStats.updatePlayTime(next.skillSystem.elapsedMs);

    // 레벨업 감지
    _detectLevelUps(next);

    // 골드 변화 감지
    _detectGoldChanges(next);

    // 몬스터 처치 감지
    _detectMonsterKills(next);

    // 퀘스트 완료 감지
    _detectQuestCompletions(next);
  }

  /// 레벨업 감지 및 기록
  void _detectLevelUps(GameState next) {
    if (next.traits.level > _previousLevel) {
      final levelUps = next.traits.level - _previousLevel;
      for (var i = 0; i < levelUps; i++) {
        _sessionStats = _sessionStats.recordLevelUp();
      }
      _previousLevel = next.traits.level;

      // 최고 레벨 업데이트
      unawaited(_statisticsStorage.updateHighestLevel(next.traits.level));
    }
  }

  /// 골드 변화 감지 및 기록
  void _detectGoldChanges(GameState next) {
    if (next.inventory.gold > _previousGold) {
      final earned = next.inventory.gold - _previousGold;
      _sessionStats = _sessionStats.recordGoldEarned(earned);

      // 최대 골드 업데이트
      unawaited(_statisticsStorage.updateHighestGold(next.inventory.gold));
    } else if (next.inventory.gold < _previousGold) {
      final spent = _previousGold - next.inventory.gold;
      _sessionStats = _sessionStats.recordGoldSpent(spent);
    }
    _previousGold = next.inventory.gold;
  }

  /// 몬스터 처치 감지 및 기록
  void _detectMonsterKills(GameState next) {
    if (next.progress.monstersKilled > _previousMonstersKilled) {
      final kills = next.progress.monstersKilled - _previousMonstersKilled;
      for (var i = 0; i < kills; i++) {
        _sessionStats = _sessionStats.recordKill();
      }
      _previousMonstersKilled = next.progress.monstersKilled;
    }
  }

  /// 퀘스트 완료 감지 및 기록
  void _detectQuestCompletions(GameState next) {
    if (next.progress.questCount > _previousQuestsCompleted) {
      final quests = next.progress.questCount - _previousQuestsCompleted;
      for (var i = 0; i < quests; i++) {
        _sessionStats = _sessionStats.recordQuestComplete();
      }
      _previousQuestsCompleted = next.progress.questCount;
    }
  }

  /// 사망 기록
  void recordDeath() {
    _sessionStats = _sessionStats.recordDeath();
  }

  /// 게임 클리어 기록
  Future<void> recordGameComplete() async {
    await _statisticsStorage.recordGameComplete();
  }

  /// 누적 통계 로드
  Future<void> loadCumulativeStats() async {
    _cumulativeStats = await _statisticsStorage.loadCumulative();
  }

  /// 세션 통계를 누적 통계에 병합
  Future<void> mergeSessionStats() async {
    await _statisticsStorage.mergeSession(_sessionStats);
    _cumulativeStats = await _statisticsStorage.loadCumulative();
  }
}
