import 'package:asciineverdie/data/skill_data.dart';
import 'package:asciineverdie/src/core/engine/combat_calculator.dart';
import 'package:asciineverdie/src/core/engine/item_service.dart';
import 'package:asciineverdie/src/core/engine/skill_service.dart';
import 'package:asciineverdie/src/core/model/arena_match.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/monster_combat_stats.dart';
import 'package:asciineverdie/src/core/model/skill.dart';
import 'package:asciineverdie/src/core/util/deterministic_random.dart';

/// 아레나 서비스
///
/// 로컬 아레나 대전 시스템의 핵심 로직 담당:
/// - 순위 계산 및 상대 결정
/// - 전투 실행
/// - 장비 교환
class ArenaService {
  ArenaService({DeterministicRandom? rng})
    : _rng = rng ?? DeterministicRandom(DateTime.now().millisecondsSinceEpoch);

  final DeterministicRandom _rng;

  late final SkillService _skillService = SkillService(rng: _rng);

  // ============================================================================
  // 스킬 시스템 헬퍼
  // ============================================================================

  /// HallOfFameEntry의 finalSkills에서 Skill 목록 추출
  List<Skill> _getSkillsFromEntry(HallOfFameEntry entry) {
    final skillData = entry.finalSkills;
    if (skillData == null || skillData.isEmpty) return [];

    final skills = <Skill>[];
    for (final data in skillData) {
      final skillName = data['name'];
      if (skillName != null) {
        final skill = SkillData.getSkillBySpellName(skillName);
        if (skill != null) {
          skills.add(skill);
        }
      }
    }
    return skills;
  }

  /// 스킬 ID 목록 추출 (HallOfFameEntry에서)
  List<String> _getSkillIdsFromEntry(HallOfFameEntry entry) {
    return _getSkillsFromEntry(entry).map((s) => s.id).toList();
  }

  /// 스킬 랭크 조회 (HallOfFameEntry의 finalSkills에서)
  int _getSkillRankFromEntry(HallOfFameEntry entry, String skillId) {
    final skill = SkillData.getSkillById(skillId);
    if (skill == null) return 1;

    final skillData = entry.finalSkills;
    if (skillData == null || skillData.isEmpty) return 1;

    for (final data in skillData) {
      if (data['name'] == skill.name) {
        final rankStr = data['rank'] ?? 'I';
        return _romanToInt(rankStr);
      }
    }
    return 1;
  }

  /// 로마 숫자 → 정수 변환
  int _romanToInt(String roman) {
    return switch (roman) {
      'I' => 1,
      'II' => 2,
      'III' => 3,
      'IV' => 4,
      'V' => 5,
      _ => 1,
    };
  }

  // ============================================================================
  // 상대 결정
  // ============================================================================

  /// 상대 결정 (바로 위 순위, 1위면 2위와 대결)
  ///
  /// [hallOfFame] 명예의 전당
  /// [challengerId] 도전자 캐릭터 ID
  /// Returns: 상대 캐릭터 (없으면 null)
  HallOfFameEntry? findOpponent(HallOfFame hallOfFame, String challengerId) {
    final ranked = hallOfFame.rankedEntries;
    if (ranked.length < 2) return null;

    final currentRank = hallOfFame.getRank(challengerId);
    if (currentRank <= 0) return null;

    // 1위면 2위와 대결
    if (currentRank == 1) {
      return ranked[1];
    }

    // 그 외는 바로 위 순위와 대결
    return ranked[currentRank - 2];
  }

  // ============================================================================
  // 전투 실행
  // ============================================================================

  /// 아레나 전투 실행
  ///
  /// [match] 대전 정보
  /// Returns: 대전 결과 (승패, 장비 교환 후 캐릭터)
  ArenaMatchResult executeCombat(ArenaMatch match) {
    final calculator = CombatCalculator(rng: _rng);

    // 도전자 스탯 (풀 HP로 시작)
    final challengerStats = match.challenger.finalStats;
    final opponentStats = match.opponent.finalStats;

    if (challengerStats == null || opponentStats == null) {
      // 스탯이 없으면 도전자 패배 처리
      return ArenaMatchResult(
        match: match,
        isVictory: false,
        turns: 0,
        updatedChallenger: match.challenger,
        updatedOpponent: match.opponent,
      );
    }

    // 플레이어 스탯 (풀 HP로 초기화)
    var playerCombatStats = challengerStats.copyWith(
      hpCurrent: challengerStats.hpMax,
      mpCurrent: challengerStats.mpMax,
    );

    // 상대를 몬스터 형태로 변환
    var opponentMonsterStats = MonsterCombatStats.fromCombatStats(
      opponentStats,
      match.opponent.characterName,
    );

    // 전투 시뮬레이션
    int turns = 0;
    int playerAccum = 0;
    int opponentAccum = 0;
    const tickMs = 200;

    while (playerCombatStats.isAlive && opponentMonsterStats.isAlive) {
      playerAccum += tickMs;
      opponentAccum += tickMs;

      // 플레이어 공격
      if (playerAccum >= playerCombatStats.attackDelayMs) {
        final result = calculator.playerAttackMonster(
          attacker: playerCombatStats,
          defender: opponentMonsterStats,
        );
        opponentMonsterStats = result.updatedDefender;
        playerAccum = 0;
        turns++;
      }

      // 상대 공격 (살아있을 때만)
      if (opponentMonsterStats.isAlive &&
          opponentAccum >= opponentMonsterStats.attackDelayMs) {
        final result = calculator.monsterAttackPlayer(
          attacker: opponentMonsterStats,
          defender: playerCombatStats,
        );
        playerCombatStats = result.updatedDefender;
        opponentAccum = 0;
      }

      // 무한 루프 방지
      if (turns > 1000) break;
    }

    final isVictory = playerCombatStats.isAlive;

    // 장비 교환
    final (updatedChallenger, updatedOpponent) = _exchangeEquipment(
      match: match,
      isVictory: isVictory,
    );

    return ArenaMatchResult(
      match: match,
      isVictory: isVictory,
      turns: turns,
      updatedChallenger: updatedChallenger,
      updatedOpponent: updatedOpponent,
    );
  }

  /// 시뮬레이션 결과를 기반으로 전투 결과 생성
  ///
  /// [match] 대전 정보
  /// [challengerHp] 도전자 최종 HP
  /// [opponentHp] 상대 최종 HP
  /// [turns] 총 턴 수
  /// Returns: 대전 결과 (승패, 장비 교환 후 캐릭터)
  ArenaMatchResult createResultFromSimulation({
    required ArenaMatch match,
    required int challengerHp,
    required int opponentHp,
    required int turns,
  }) {
    // 도전자 HP가 0보다 크면 승리
    final isVictory = challengerHp > 0 && opponentHp <= 0;

    // 장비 교환
    final (updatedChallenger, updatedOpponent) = _exchangeEquipment(
      match: match,
      isVictory: isVictory,
    );

    return ArenaMatchResult(
      match: match,
      isVictory: isVictory,
      turns: turns,
      updatedChallenger: updatedChallenger,
      updatedOpponent: updatedOpponent,
    );
  }

  /// 전투 시뮬레이션 (애니메이션용 스트림)
  ///
  /// progress_service._processCombatTickWithSkills()와 동일한 로직 사용
  /// [match] 대전 정보
  /// Returns: 턴별 전투 상황 스트림
  Stream<ArenaCombatTurn> simulateCombat(ArenaMatch match) async* {
    final calculator = CombatCalculator(rng: _rng);

    final challengerStats = match.challenger.finalStats;
    final opponentStats = match.opponent.finalStats;

    if (challengerStats == null || opponentStats == null) {
      return;
    }

    // 스킬 ID 목록 로드 (SkillBook과 동일한 방식)
    var challengerSkillIds = _getSkillIdsFromEntry(match.challenger);
    var opponentSkillIds = _getSkillIdsFromEntry(match.opponent);

    // 스킬이 없으면 기본 스킬 사용
    if (challengerSkillIds.isEmpty) {
      challengerSkillIds = SkillData.defaultSkillIds;
    }
    if (opponentSkillIds.isEmpty) {
      opponentSkillIds = SkillData.defaultSkillIds;
    }

    // 스킬 시스템 상태 초기화
    var challengerSkillSystem = SkillSystemState.empty();
    var opponentSkillSystem = SkillSystemState.empty();

    // DOT 및 디버프 추적 (일반 전투와 동일)
    var challengerDoTs = <DotEffect>[];
    var opponentDoTs = <DotEffect>[];
    var challengerDebuffs = <ActiveBuff>[];
    var opponentDebuffs = <ActiveBuff>[];

    var playerCombatStats = challengerStats.copyWith(
      hpCurrent: challengerStats.hpMax,
      mpCurrent: challengerStats.mpMax,
    );

    var opponentCombatStats = opponentStats.copyWith(
      hpCurrent: opponentStats.hpMax,
      mpCurrent: opponentStats.mpMax,
    );

    var opponentMonsterStats = MonsterCombatStats.fromCombatStats(
      opponentCombatStats,
      match.opponent.characterName,
    );

    var challengerMonsterStats = MonsterCombatStats.fromCombatStats(
      playerCombatStats,
      match.challenger.characterName,
    );

    int playerAccum = 0;
    int opponentAccum = 0;
    int elapsedMs = 0;
    const tickMs = 200;
    int turns = 0;

    // 초기 상태 전송
    yield ArenaCombatTurn(
      challengerHp: playerCombatStats.hpCurrent,
      opponentHp: opponentCombatStats.hpCurrent,
      challengerHpMax: playerCombatStats.hpMax,
      opponentHpMax: opponentCombatStats.hpMax,
      challengerMp: playerCombatStats.mpCurrent,
      opponentMp: opponentCombatStats.mpCurrent,
      challengerMpMax: playerCombatStats.mpMax,
      opponentMpMax: opponentCombatStats.mpMax,
    );

    while (playerCombatStats.isAlive && opponentCombatStats.hpCurrent > 0) {
      playerAccum += tickMs;
      opponentAccum += tickMs;
      elapsedMs += tickMs;

      // 스킬 시스템 시간 업데이트
      challengerSkillSystem = challengerSkillSystem.copyWith(
        elapsedMs: elapsedMs,
      );
      opponentSkillSystem = opponentSkillSystem.copyWith(elapsedMs: elapsedMs);

      int? challengerDamage;
      int? opponentDamage;
      bool isChallengerCritical = false;
      bool isOpponentCritical = false;
      bool isChallengerEvaded = false;
      bool isOpponentEvaded = false;
      bool isChallengerBlocked = false;
      bool isOpponentBlocked = false;
      String? challengerSkillUsed;
      String? opponentSkillUsed;
      int? challengerHealAmount;
      int? opponentHealAmount;

      // =========================================================================
      // DOT 틱 처리 (도전자 → 상대에게 적용된 DOT)
      // =========================================================================
      var dotDamageToOpponent = 0;
      final updatedChallengerDoTs = <DotEffect>[];
      for (final dot in challengerDoTs) {
        final (updatedDot, ticksTriggered) = dot.tick(tickMs);
        if (ticksTriggered > 0) {
          dotDamageToOpponent += dot.damagePerTick * ticksTriggered;
        }
        if (updatedDot.isActive) {
          updatedChallengerDoTs.add(updatedDot);
        }
      }
      challengerDoTs = updatedChallengerDoTs;

      if (dotDamageToOpponent > 0 && opponentCombatStats.hpCurrent > 0) {
        opponentCombatStats = opponentCombatStats.copyWith(
          hpCurrent: (opponentCombatStats.hpCurrent - dotDamageToOpponent)
              .clamp(0, opponentCombatStats.hpMax),
        );
      }

      // DOT 틱 처리 (상대 → 도전자에게 적용된 DOT)
      var dotDamageToChallenger = 0;
      final updatedOpponentDoTs = <DotEffect>[];
      for (final dot in opponentDoTs) {
        final (updatedDot, ticksTriggered) = dot.tick(tickMs);
        if (ticksTriggered > 0) {
          dotDamageToChallenger += dot.damagePerTick * ticksTriggered;
        }
        if (updatedDot.isActive) {
          updatedOpponentDoTs.add(updatedDot);
        }
      }
      opponentDoTs = updatedOpponentDoTs;

      if (dotDamageToChallenger > 0 && playerCombatStats.isAlive) {
        playerCombatStats = playerCombatStats.copyWith(
          hpCurrent: (playerCombatStats.hpCurrent - dotDamageToChallenger)
              .clamp(0, playerCombatStats.hpMax),
        );
      }

      // =========================================================================
      // 만료된 디버프 정리
      // =========================================================================
      challengerDebuffs = challengerDebuffs
          .where((ActiveBuff d) => !d.isExpired(elapsedMs))
          .toList();
      opponentDebuffs = opponentDebuffs
          .where((ActiveBuff d) => !d.isExpired(elapsedMs))
          .toList();

      // =========================================================================
      // 도전자 턴 (selectAutoSkill 사용 - 일반 전투와 동일)
      // =========================================================================
      if (playerAccum >= playerCombatStats.attackDelayMs) {
        playerAccum = 0;

        // 상대 몬스터 스탯 동기화
        opponentMonsterStats = MonsterCombatStats.fromCombatStats(
          opponentCombatStats,
          match.opponent.characterName,
        );

        // 스킬 자동 선택 (progress_service와 동일한 로직)
        final selectedSkill = _skillService.selectAutoSkill(
          player: playerCombatStats,
          monster: opponentMonsterStats,
          skillSystem: challengerSkillSystem,
          availableSkillIds: challengerSkillIds,
          activeDoTs: challengerDoTs,
          activeDebuffs: opponentDebuffs,
        );

        if (selectedSkill != null && selectedSkill.isAttack) {
          // 스킬 랭크 조회 및 적용
          final skillRank = _getSkillRankFromEntry(
            match.challenger,
            selectedSkill.id,
          );
          final skillResult = _skillService.useAttackSkillWithRank(
            skill: selectedSkill,
            player: playerCombatStats,
            monster: opponentMonsterStats,
            skillSystem: challengerSkillSystem,
            rank: skillRank,
          );
          playerCombatStats = skillResult.updatedPlayer;
          opponentCombatStats = opponentCombatStats.copyWith(
            hpCurrent: skillResult.updatedMonster.hpCurrent,
          );
          challengerSkillSystem = skillResult.updatedSkillSystem;
          challengerSkillUsed = selectedSkill.name;
          challengerDamage = skillResult.result.damage;
        } else if (selectedSkill != null && selectedSkill.isDot) {
          // DOT 스킬 사용
          final skillResult = _skillService.useDotSkill(
            skill: selectedSkill,
            player: playerCombatStats,
            skillSystem: challengerSkillSystem,
            playerInt: playerCombatStats.atk ~/ 10,
            playerWis: playerCombatStats.def ~/ 10,
          );
          playerCombatStats = skillResult.updatedPlayer;
          challengerSkillSystem = skillResult.updatedSkillSystem;
          if (skillResult.dotEffect != null) {
            challengerDoTs.add(skillResult.dotEffect!);
          }
          challengerSkillUsed = selectedSkill.name;
        } else if (selectedSkill != null && selectedSkill.isHeal) {
          // 회복 스킬 사용
          final skillResult = _skillService.useHealSkill(
            skill: selectedSkill,
            player: playerCombatStats,
            skillSystem: challengerSkillSystem,
          );
          playerCombatStats = skillResult.updatedPlayer;
          challengerSkillSystem = skillResult.updatedSkillSystem;
          challengerSkillUsed = selectedSkill.name;
          challengerHealAmount = skillResult.result.healedAmount;
        } else if (selectedSkill != null && selectedSkill.isBuff) {
          // 버프 스킬 사용
          final skillResult = _skillService.useBuffSkill(
            skill: selectedSkill,
            player: playerCombatStats,
            skillSystem: challengerSkillSystem,
          );
          playerCombatStats = skillResult.updatedPlayer;
          challengerSkillSystem = skillResult.updatedSkillSystem;
          challengerSkillUsed = selectedSkill.name;
        } else if (selectedSkill != null && selectedSkill.isDebuff) {
          // 디버프 스킬 사용
          final skillResult = _skillService.useDebuffSkill(
            skill: selectedSkill,
            player: playerCombatStats,
            skillSystem: challengerSkillSystem,
            currentDebuffs: opponentDebuffs,
          );
          playerCombatStats = skillResult.updatedPlayer;
          challengerSkillSystem = skillResult.updatedSkillSystem;
          final debuffEffect = skillResult.debuffEffect;
          if (debuffEffect != null) {
            opponentDebuffs =
                opponentDebuffs
                    .where(
                      (ActiveBuff d) => d.effect.id != debuffEffect.effect.id,
                    )
                    .toList()
                  ..add(debuffEffect);
          }
          challengerSkillUsed = selectedSkill.name;
        } else {
          // 일반 공격
          final result = calculator.playerAttackMonster(
            attacker: playerCombatStats,
            defender: opponentMonsterStats,
          );
          opponentCombatStats = opponentCombatStats.copyWith(
            hpCurrent: result.updatedDefender.hpCurrent,
          );

          if (result.result.isHit) {
            challengerDamage = result.result.damage;
            isChallengerCritical = result.result.isCritical;
          } else {
            isOpponentEvaded = true;
          }
        }
      }

      // =========================================================================
      // 상대 턴 (selectAutoSkill 사용 - 일반 전투와 동일)
      // =========================================================================
      if (opponentCombatStats.hpCurrent > 0 &&
          opponentAccum >= opponentCombatStats.attackDelayMs) {
        opponentAccum = 0;

        // 도전자 몬스터 스탯 동기화
        challengerMonsterStats = MonsterCombatStats.fromCombatStats(
          playerCombatStats,
          match.challenger.characterName,
        );

        // 스킬 자동 선택 (progress_service와 동일한 로직)
        final selectedSkill = _skillService.selectAutoSkill(
          player: opponentCombatStats,
          monster: challengerMonsterStats,
          skillSystem: opponentSkillSystem,
          availableSkillIds: opponentSkillIds,
          activeDoTs: opponentDoTs,
          activeDebuffs: challengerDebuffs,
        );

        if (selectedSkill != null && selectedSkill.isAttack) {
          // 스킬 랭크 조회 및 적용
          final skillRank = _getSkillRankFromEntry(
            match.opponent,
            selectedSkill.id,
          );
          final skillResult = _skillService.useAttackSkillWithRank(
            skill: selectedSkill,
            player: opponentCombatStats,
            monster: challengerMonsterStats,
            skillSystem: opponentSkillSystem,
            rank: skillRank,
          );
          opponentCombatStats = skillResult.updatedPlayer;
          playerCombatStats = playerCombatStats.copyWith(
            hpCurrent: skillResult.updatedMonster.hpCurrent,
          );
          opponentSkillSystem = skillResult.updatedSkillSystem;
          opponentSkillUsed = selectedSkill.name;
          opponentDamage = skillResult.result.damage;
        } else if (selectedSkill != null && selectedSkill.isDot) {
          // DOT 스킬 사용
          final skillResult = _skillService.useDotSkill(
            skill: selectedSkill,
            player: opponentCombatStats,
            skillSystem: opponentSkillSystem,
            playerInt: opponentCombatStats.atk ~/ 10,
            playerWis: opponentCombatStats.def ~/ 10,
          );
          opponentCombatStats = skillResult.updatedPlayer;
          opponentSkillSystem = skillResult.updatedSkillSystem;
          if (skillResult.dotEffect != null) {
            opponentDoTs.add(skillResult.dotEffect!);
          }
          opponentSkillUsed = selectedSkill.name;
        } else if (selectedSkill != null && selectedSkill.isHeal) {
          // 회복 스킬 사용
          final skillResult = _skillService.useHealSkill(
            skill: selectedSkill,
            player: opponentCombatStats,
            skillSystem: opponentSkillSystem,
          );
          opponentCombatStats = skillResult.updatedPlayer;
          opponentSkillSystem = skillResult.updatedSkillSystem;
          opponentSkillUsed = selectedSkill.name;
          opponentHealAmount = skillResult.result.healedAmount;
        } else if (selectedSkill != null && selectedSkill.isBuff) {
          // 버프 스킬 사용
          final skillResult = _skillService.useBuffSkill(
            skill: selectedSkill,
            player: opponentCombatStats,
            skillSystem: opponentSkillSystem,
          );
          opponentCombatStats = skillResult.updatedPlayer;
          opponentSkillSystem = skillResult.updatedSkillSystem;
          opponentSkillUsed = selectedSkill.name;
        } else if (selectedSkill != null && selectedSkill.isDebuff) {
          // 디버프 스킬 사용
          final skillResult = _skillService.useDebuffSkill(
            skill: selectedSkill,
            player: opponentCombatStats,
            skillSystem: opponentSkillSystem,
            currentDebuffs: challengerDebuffs,
          );
          opponentCombatStats = skillResult.updatedPlayer;
          opponentSkillSystem = skillResult.updatedSkillSystem;
          final debuffEffect = skillResult.debuffEffect;
          if (debuffEffect != null) {
            challengerDebuffs =
                challengerDebuffs
                    .where(
                      (ActiveBuff d) => d.effect.id != debuffEffect.effect.id,
                    )
                    .toList()
                  ..add(debuffEffect);
          }
          opponentSkillUsed = selectedSkill.name;
        } else {
          // 일반 공격 (디버프 효과 적용)
          var debuffedOpponent = opponentCombatStats;
          if (challengerDebuffs.isNotEmpty) {
            double atkMod = 0;
            for (final debuff in challengerDebuffs) {
              if (!debuff.isExpired(elapsedMs)) {
                atkMod += debuff.effect.atkModifier;
              }
            }
            final newAtk = (opponentCombatStats.atk * (1 + atkMod))
                .round()
                .clamp(opponentCombatStats.atk ~/ 10, opponentCombatStats.atk);
            debuffedOpponent = opponentCombatStats.copyWith(atk: newAtk);
          }

          opponentMonsterStats = MonsterCombatStats.fromCombatStats(
            debuffedOpponent,
            match.opponent.characterName,
          );
          final result = calculator.monsterAttackPlayer(
            attacker: opponentMonsterStats,
            defender: playerCombatStats,
          );
          playerCombatStats = result.updatedDefender;

          if (result.result.isHit) {
            opponentDamage = result.result.damage;
            isOpponentCritical = result.result.isCritical;
            isChallengerBlocked = result.result.isBlocked;
          } else {
            isChallengerEvaded = true;
          }
        }
      }

      // 액션이 발생했을 때만 턴 전송
      final hasAction =
          challengerDamage != null ||
          opponentDamage != null ||
          challengerHealAmount != null ||
          opponentHealAmount != null ||
          challengerSkillUsed != null ||
          opponentSkillUsed != null;

      if (hasAction) {
        turns++;
        yield ArenaCombatTurn(
          challengerDamage: challengerDamage,
          opponentDamage: opponentDamage,
          challengerHp: playerCombatStats.hpCurrent,
          opponentHp: opponentCombatStats.hpCurrent,
          challengerHpMax: playerCombatStats.hpMax,
          opponentHpMax: opponentCombatStats.hpMax,
          challengerMp: playerCombatStats.mpCurrent,
          opponentMp: opponentCombatStats.mpCurrent,
          challengerMpMax: playerCombatStats.mpMax,
          opponentMpMax: opponentCombatStats.mpMax,
          isChallengerCritical: isChallengerCritical,
          isOpponentCritical: isOpponentCritical,
          isChallengerEvaded: isChallengerEvaded,
          isOpponentEvaded: isOpponentEvaded,
          isChallengerBlocked: isChallengerBlocked,
          isOpponentBlocked: isOpponentBlocked,
          challengerSkillUsed: challengerSkillUsed,
          opponentSkillUsed: opponentSkillUsed,
          challengerHealAmount: challengerHealAmount,
          opponentHealAmount: opponentHealAmount,
        );

        // 애니메이션을 위한 딜레이
        await Future<void>.delayed(const Duration(milliseconds: 100));
      }

      // 무한 루프 방지
      if (turns > 1000) break;
    }
  }
  // ============================================================================
  // AI 베팅 슬롯 선택
  // ============================================================================

  /// AI가 도전자에게서 약탈할 슬롯 자동 선택
  ///
  /// 도전자의 가장 좋은 장비 슬롯 선택 (무기 제외)
  EquipmentSlot selectOpponentBettingSlot(HallOfFameEntry challenger) {
    final equipment = challenger.finalEquipment ?? [];
    if (equipment.isEmpty) {
      // 장비가 없으면 기본 슬롯 (투구)
      return EquipmentSlot.helm;
    }

    // 무기를 제외한 장비 중 가장 높은 점수의 슬롯 선택
    EquipmentSlot? bestSlot;
    int bestScore = -1;

    for (final item in equipment) {
      // 무기는 약탈 불가
      if (item.slot == EquipmentSlot.weapon) continue;
      if (item.isEmpty) continue;

      final score = ItemService.calculateEquipmentScore(item);
      if (score > bestScore) {
        bestScore = score;
        bestSlot = item.slot;
      }
    }

    // 유효한 슬롯이 없으면 투구 선택
    return bestSlot ?? EquipmentSlot.helm;
  }

  /// 베팅 가능한 슬롯 목록 반환 (무기 제외)
  List<EquipmentSlot> getBettableSlots() {
    return EquipmentSlot.values
        .where((slot) => slot != EquipmentSlot.weapon)
        .toList();
  }

  // ============================================================================
  // 장비 약탈
  // ============================================================================

  /// 장비 약탈 (승자가 패자의 베팅 슬롯 장비 획득)
  ///
  /// - 승자: 자신이 선택한 슬롯의 패자 장비 획득
  /// - 패자: 해당 슬롯 장비 손실 → 기본 장비로 대체
  (HallOfFameEntry, HallOfFameEntry) _exchangeEquipment({
    required ArenaMatch match,
    required bool isVictory,
  }) {
    // 도전자 장비 목록 복사
    final challengerEquipment = List<EquipmentItem>.from(
      match.challenger.finalEquipment ?? [],
    );

    // 상대 장비 목록 복사
    final opponentEquipment = List<EquipmentItem>.from(
      match.opponent.finalEquipment ?? [],
    );

    if (isVictory) {
      // 도전자 승리: 도전자가 선택한 슬롯의 상대 장비 획득
      final winnerSlot = match.challengerBettingSlot;
      final lootedItem = _findItemBySlot(opponentEquipment, winnerSlot);

      // 도전자: 약탈한 장비로 교체
      _replaceItemInList(challengerEquipment, winnerSlot, lootedItem);

      // 상대: 해당 슬롯 기본 장비로 대체
      final defaultItem = _createDefaultEquipment(winnerSlot);
      _replaceItemInList(opponentEquipment, winnerSlot, defaultItem);
    } else {
      // 상대 승리: 상대가 선택한 슬롯의 도전자 장비 획득
      final winnerSlot = match.opponentBettingSlot;
      final lootedItem = _findItemBySlot(challengerEquipment, winnerSlot);

      // 상대: 약탈한 장비로 교체
      _replaceItemInList(opponentEquipment, winnerSlot, lootedItem);

      // 도전자: 해당 슬롯 기본 장비로 대체
      final defaultItem = _createDefaultEquipment(winnerSlot);
      _replaceItemInList(challengerEquipment, winnerSlot, defaultItem);
    }

    // 업데이트된 엔트리 생성
    final updatedChallenger = match.challenger.copyWith(
      finalEquipment: challengerEquipment,
    );
    final updatedOpponent = match.opponent.copyWith(
      finalEquipment: opponentEquipment,
    );

    return (updatedChallenger, updatedOpponent);
  }

  /// 슬롯으로 장비 찾기
  EquipmentItem _findItemBySlot(
    List<EquipmentItem> equipment,
    EquipmentSlot slot,
  ) {
    for (final item in equipment) {
      if (item.slot == slot) return item;
    }
    return EquipmentItem.empty(slot);
  }

  /// 장비 목록에서 특정 슬롯의 아이템 교체
  void _replaceItemInList(
    List<EquipmentItem> equipment,
    EquipmentSlot slot,
    EquipmentItem newItem,
  ) {
    for (var i = 0; i < equipment.length; i++) {
      if (equipment[i].slot == slot) {
        equipment[i] = newItem;
        return;
      }
    }
    // 슬롯이 없으면 추가
    equipment.add(newItem);
  }

  /// 기본 장비 생성 (Common 등급)
  ///
  /// 패자가 장비를 잃었을 때 빈 슬롯 방지용
  EquipmentItem _createDefaultEquipment(EquipmentSlot slot) {
    return ItemService.createDefaultEquipmentForSlot(slot);
  }
}
