import 'package:asciineverdie/data/skill_data.dart';
import 'package:asciineverdie/src/core/engine/item_service.dart';
import 'package:asciineverdie/src/core/model/combat_stats.dart';
import 'package:asciineverdie/src/core/model/equipment_item.dart';
import 'package:asciineverdie/src/core/model/equipment_slot.dart';
import 'package:asciineverdie/src/core/model/game_state.dart';
import 'package:asciineverdie/src/core/model/hall_of_fame.dart';
import 'package:asciineverdie/src/core/model/item_stats.dart';
import 'package:asciineverdie/src/core/util/deterministic_random.dart';
import 'package:asciineverdie/src/core/util/roman.dart';

/// 테스트 캐릭터 생성 서비스 (디버그 모드 전용)
///
/// 현재 캐릭터를 레벨 100, 고급 장비, 다수의 스킬을 가진
/// 캐릭터로 변환하여 명예의 전당에 등록할 수 있게 함.
class TestCharacterService {
  TestCharacterService({required this.rng});

  final DeterministicRandom rng;

  /// 테스트 캐릭터 데이터 생성
  ///
  /// 현재 GameState를 기반으로:
  /// - 레벨 100
  /// - 장비: Rare+, 최소 Epic 2개, Legendary 1개
  /// - 스킬: 20~30개 랜덤
  HallOfFameEntry createTestCharacter(GameState state) {
    // 1. 장비 생성 (Rare+, Epic 2+, Legendary 1+)
    final equipment = _generateTestEquipment();

    // 2. 스킬 생성 (20~30개)
    final skills = _generateTestSkills();

    // 3. 레벨 100 기준 스탯 계산
    final testStats = _generateTestStats();

    // 4. CombatStats 계산
    final combatStats = CombatStats.fromStats(
      stats: testStats,
      equipment: equipment,
      level: 100,
    );

    // 5. HallOfFameEntry 생성
    return HallOfFameEntry(
      id: DateTime.now().millisecondsSinceEpoch.toString(),
      characterName: state.traits.name,
      race: state.traits.race,
      raceId: state.traits.raceId,
      klass: state.traits.klass,
      level: 100,
      totalPlayTimeMs: 36000000, // 10시간 (테스트용 기본값)
      totalDeaths: rng.nextInt(50), // 0~49 랜덤 사망 횟수
      monstersKilled: 5000 + rng.nextInt(5000), // 5000~10000 처치
      questsCompleted: 100 + rng.nextInt(50), // 100~150 퀘스트
      clearedAt: DateTime.now(),
      finalStats: combatStats,
      finalEquipment: equipment.items,
      finalSkills: skills,
    );
  }

  /// 테스트용 장비 생성
  ///
  /// 조건:
  /// - 모든 장비 Rare 이상
  /// - 최소 Epic 2개
  /// - 최소 Legendary 1개
  Equipment _generateTestEquipment() {
    final itemService = ItemService(rng: rng);
    final items = <EquipmentItem>[];

    // 희귀도 분배 결정
    // 11개 슬롯: 1 Legendary, 2 Epic, 나머지 Rare
    final rarities = <ItemRarity>[
      ItemRarity.legendary, // 1개
      ItemRarity.epic, ItemRarity.epic, // 2개
      ItemRarity.rare, ItemRarity.rare, ItemRarity.rare, // 3개
      ItemRarity.rare, ItemRarity.rare, ItemRarity.rare, // 3개
      ItemRarity.rare, ItemRarity.rare, // 2개
    ];

    // 희귀도 셔플
    _shuffleList(rarities);

    // 각 슬롯별 장비 생성
    for (var i = 0; i < Equipment.slotCount; i++) {
      final slot = EquipmentSlot.values[i];
      final rarity = rarities[i];
      final name = _generateEquipmentName(slot, rarity);

      final item = itemService.generateEquipment(
        name: name,
        slot: slot,
        level: 100,
        rarity: rarity,
      );
      items.add(item);
    }

    // Legendary 슬롯을 bestIndex로 설정
    final legendaryIndex = rarities.indexOf(ItemRarity.legendary);

    return Equipment(items: items, bestIndex: legendaryIndex);
  }

  /// 희귀도에 맞는 장비 이름 생성
  String _generateEquipmentName(EquipmentSlot slot, ItemRarity rarity) {
    final prefixes = switch (rarity) {
      ItemRarity.legendary => [
        'Divine',
        'Mythical',
        'Godlike',
        'Eternal',
        'Transcendent',
      ],
      ItemRarity.epic => [
        'Ancient',
        'Infernal',
        'Celestial',
        'Void',
        'Corrupted',
      ],
      ItemRarity.rare => [
        'Superior',
        'Enchanted',
        'Reinforced',
        'Blessed',
        'Refined',
      ],
      _ => ['Standard', 'Basic', 'Common'],
    };

    final slotNames = switch (slot) {
      EquipmentSlot.weapon => [
        'Keyboard of Power',
        'Binary Blade',
        'Compiler Crusher',
      ],
      EquipmentSlot.shield => [
        'Firewall Shield',
        'Exception Handler',
        'Null Guard',
      ],
      EquipmentSlot.helm => ['Neural Helm', 'Thought Processor', 'Mind Buffer'],
      EquipmentSlot.hauberk => ['Matrix Armor', 'Byte Mail', 'Kernel Plate'],
      EquipmentSlot.brassairts => [
        'Bit Guards',
        'Stream Bracers',
        'Thread Wraps',
      ],
      EquipmentSlot.vambraces => [
        'Code Vambraces',
        'Debug Cuffs',
        'Loop Guards',
      ],
      EquipmentSlot.gauntlets => [
        'Input Gloves',
        'Handler Mitts',
        'Pointer Grips',
      ],
      EquipmentSlot.gambeson => ['Layer Vest', 'Cache Coat', 'Buffer Jacket'],
      EquipmentSlot.cuisses => [
        'Register Guards',
        'Stack Protectors',
        'Heap Leggings',
      ],
      EquipmentSlot.greaves => [
        'Runtime Greaves',
        'Compile Shins',
        'Execute Boots',
      ],
      EquipmentSlot.sollerets => [
        'Boot Loader',
        'System Treads',
        'Process Soles',
      ],
    };

    final prefix = prefixes[rng.nextInt(prefixes.length)];
    final slotName = slotNames[rng.nextInt(slotNames.length)];

    return '$prefix $slotName';
  }

  /// 테스트용 스킬 생성 (20~30개)
  ///
  /// SkillData.spellNameToSkill에 정의된 전투 스킬만 선택
  List<Map<String, String>> _generateTestSkills() {
    // 전투에서 실제로 사용 가능한 스킬 목록
    final validSpells = SkillData.spellNameToSkill.keys.toList();
    final skillCount = 20 + rng.nextInt(11); // 20~30개
    final selectedSpells = <String>{};
    final skills = <Map<String, String>>[];

    // 중복 없이 스킬 선택
    while (selectedSpells.length < skillCount &&
        selectedSpells.length < validSpells.length) {
      final index = rng.nextInt(validSpells.length);
      final spell = validSpells[index];
      if (selectedSpells.add(spell)) {
        // 랭크: V~X 랜덤 (레벨 100 기준 높은 랭크)
        final rank = _randomHighRank();
        skills.add({'name': spell, 'rank': rank});
      }
    }

    return skills;
  }

  /// 높은 랭크 생성 (V~X 선호)
  String _randomHighRank() {
    // 5~10 범위 (V~X)
    final rankValue = 5 + rng.nextInt(6);
    return intToRoman(rankValue);
  }

  /// 테스트용 스탯 생성 (레벨 100 기준)
  Stats _generateTestStats() {
    // 레벨 100 기준 높은 스탯
    // 기본 스탯: 50~80 범위
    final str = 50 + rng.nextInt(31);
    final con = 50 + rng.nextInt(31);
    final dex = 50 + rng.nextInt(31);
    final int_ = 50 + rng.nextInt(31);
    final wis = 50 + rng.nextInt(31);
    final cha = 50 + rng.nextInt(31);

    // HP/MP 계산 (레벨 100 기준)
    final hpMax = 500 + con * 10;
    final mpMax = 200 + int_ * 5 + wis * 3;

    return Stats(
      str: str,
      con: con,
      dex: dex,
      intelligence: int_,
      wis: wis,
      cha: cha,
      hpMax: hpMax,
      mpMax: mpMax,
      hpCurrent: hpMax,
      mpCurrent: mpMax,
    );
  }

  /// 리스트 셔플 (Fisher-Yates)
  void _shuffleList<T>(List<T> list) {
    for (var i = list.length - 1; i > 0; i--) {
      final j = rng.nextInt(i + 1);
      final temp = list[i];
      list[i] = list[j];
      list[j] = temp;
    }
  }
}
