import 'package:asciineverdie/src/core/model/combat_stats.dart';
import 'package:asciineverdie/src/core/model/equipment_item.dart';
import 'package:asciineverdie/src/core/model/game_state.dart';

/// 명예의 전당 엔트리 (Phase 10: Hall of Fame Entry)
///
/// 게임 클리어 시 저장되는 캐릭터 정보
class HallOfFameEntry {
  const HallOfFameEntry({
    required this.id,
    required this.characterName,
    required this.race,
    required this.klass,
    required this.level,
    required this.totalPlayTimeMs,
    required this.totalDeaths,
    required this.monstersKilled,
    required this.questsCompleted,
    required this.clearedAt,
    this.finalStats,
    this.finalEquipment,
    this.finalSpells,
  });

  /// 고유 ID (UUID)
  final String id;

  /// 캐릭터 이름
  final String characterName;

  /// 종족
  final String race;

  /// 클래스
  final String klass;

  /// 최종 레벨
  final int level;

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

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

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

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

  /// 클리어 일시
  final DateTime clearedAt;

  /// 최종 전투 스탯 (향후 아스키 아레나용)
  final CombatStats? finalStats;

  /// 최종 장비 목록 (풀 스탯 포함)
  final List<EquipmentItem>? finalEquipment;

  /// 최종 스펠북 (스펠 이름 + 랭크)
  final List<Map<String, String>>? finalSpells;

  /// 플레이 시간을 Duration으로 변환
  Duration get totalPlayTime => Duration(milliseconds: totalPlayTimeMs);

  /// 플레이 시간 포맷팅 (HH:MM:SS)
  String get formattedPlayTime {
    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')}';
  }

  /// 클리어 날짜 포맷팅 (YYYY.MM.DD)
  String get formattedClearedDate {
    return '${clearedAt.year}.${clearedAt.month.toString().padLeft(2, '0')}.'
        '${clearedAt.day.toString().padLeft(2, '0')}';
  }

  /// GameState에서 HallOfFameEntry 생성
  factory HallOfFameEntry.fromGameState({
    required GameState state,
    required int totalDeaths,
    required int monstersKilled,
    CombatStats? combatStats,
  }) {
    return HallOfFameEntry(
      id: DateTime.now().millisecondsSinceEpoch.toString(),
      characterName: state.traits.name,
      race: state.traits.race,
      klass: state.traits.klass,
      level: state.traits.level,
      totalPlayTimeMs: state.skillSystem.elapsedMs,
      totalDeaths: totalDeaths,
      monstersKilled: monstersKilled,
      questsCompleted: state.progress.questCount,
      clearedAt: DateTime.now(),
      finalStats: combatStats,
      finalEquipment: List<EquipmentItem>.from(state.equipment.items),
      finalSpells: state.spellBook.spells
          .map((s) => {'name': s.name, 'rank': s.rank})
          .toList(),
    );
  }

  /// JSON으로 직렬화
  Map<String, dynamic> toJson() {
    return {
      'id': id,
      'characterName': characterName,
      'race': race,
      'klass': klass,
      'level': level,
      'totalPlayTimeMs': totalPlayTimeMs,
      'totalDeaths': totalDeaths,
      'monstersKilled': monstersKilled,
      'questsCompleted': questsCompleted,
      'clearedAt': clearedAt.toIso8601String(),
      'finalStats': finalStats?.toJson(),
      'finalEquipment': finalEquipment?.map((e) => e.toJson()).toList(),
      'finalSpells': finalSpells,
    };
  }

  /// JSON에서 역직렬화
  factory HallOfFameEntry.fromJson(Map<String, dynamic> json) {
    return HallOfFameEntry(
      id: json['id'] as String,
      characterName: json['characterName'] as String,
      race: json['race'] as String,
      klass: json['klass'] as String,
      level: json['level'] as int,
      totalPlayTimeMs: json['totalPlayTimeMs'] as int,
      totalDeaths: json['totalDeaths'] as int? ?? 0,
      monstersKilled: json['monstersKilled'] as int? ?? 0,
      questsCompleted: json['questsCompleted'] as int? ?? 0,
      clearedAt: DateTime.parse(json['clearedAt'] as String),
      finalStats: json['finalStats'] != null
          ? CombatStats.fromJson(json['finalStats'] as Map<String, dynamic>)
          : null,
      finalEquipment: json['finalEquipment'] != null
          ? (json['finalEquipment'] as List<dynamic>)
              .map((e) => EquipmentItem.fromJson(e as Map<String, dynamic>))
              .toList()
          : null,
      finalSpells: json['finalSpells'] != null
          ? (json['finalSpells'] as List<dynamic>)
              .map((s) => Map<String, String>.from(s as Map))
              .toList()
          : null,
    );
  }
}

/// 명예의 전당 (Hall of Fame)
///
/// 클리어한 캐릭터 목록 관리
class HallOfFame {
  const HallOfFame({required this.entries});

  /// 명예의 전당 엔트리 목록 (클리어 시간 역순)
  final List<HallOfFameEntry> entries;

  /// 빈 명예의 전당
  factory HallOfFame.empty() => const HallOfFame(entries: []);

  /// 새 엔트리 추가
  HallOfFame addEntry(HallOfFameEntry entry) {
    final newEntries = List<HallOfFameEntry>.from(entries)
      ..add(entry)
      ..sort((a, b) => b.clearedAt.compareTo(a.clearedAt));
    return HallOfFame(entries: newEntries);
  }

  /// 엔트리 수
  int get count => entries.length;

  /// 비어있는지 확인
  bool get isEmpty => entries.isEmpty;

  /// JSON으로 직렬화
  Map<String, dynamic> toJson() {
    return {'entries': entries.map((e) => e.toJson()).toList()};
  }

  /// JSON에서 역직렬화
  factory HallOfFame.fromJson(Map<String, dynamic> json) {
    final entriesJson = json['entries'] as List<dynamic>? ?? [];
    return HallOfFame(
      entries: entriesJson
          .map((e) => HallOfFameEntry.fromJson(e as Map<String, dynamic>))
          .toList(),
    );
  }
}
