import 'dart:math' as math;

import 'package:asciineverdie/data/game_text_l10n.dart' as l10n;
import 'package:asciineverdie/src/shared/animation/monster_size.dart';
import 'package:asciineverdie/src/core/engine/act_progression_service.dart';
import 'package:asciineverdie/src/core/engine/combat_calculator.dart';
import 'package:asciineverdie/src/core/model/combat_state.dart';
import 'package:asciineverdie/src/core/model/combat_stats.dart';
import 'package:asciineverdie/src/core/model/game_state.dart';
import 'package:asciineverdie/src/core/model/monster_combat_stats.dart';
import 'package:asciineverdie/src/core/model/monster_grade.dart';
import 'package:asciineverdie/src/core/model/pq_config.dart';
import 'package:asciineverdie/src/core/util/balance_constants.dart';
import 'package:asciineverdie/src/core/util/pq_logic.dart' as pq_logic;

/// 태스크 생성 서비스
///
/// ProgressService에서 분리된 다음 태스크 생성 로직 담당:
/// - 시장 이동, 전환 태스크, 보스 리트라이, 몬스터 전투 생성
class TaskGenerator {
  const TaskGenerator({required this.config});

  final PqConfig config;

  /// 큐가 비어있을 때 다음 태스크 생성 (원본 Dequeue 667-684줄)
  ({ProgressState progress, QueueState queue}) generateNextTask(
    GameState state,
  ) {
    var progress = state.progress;
    final queue = state.queue;
    final oldTaskType = progress.currentTask.type;

    // 1. Encumbrance 초과 시 시장 이동
    if (_shouldGoToMarket(progress)) {
      return _createMarketTask(progress, queue);
    }

    // 2. 전환 태스크 (buying/heading)
    if (_needsTransitionTask(oldTaskType)) {
      return _createTransitionTask(state, progress, queue);
    }

    // 3. Act Boss 리트라이
    if (state.progress.pendingActCompletion) {
      return _createActBossRetryTask(state, progress, queue);
    }

    // 4. 최종 보스 전투
    if (state.progress.finalBossState == FinalBossState.fighting &&
        !state.progress.isInBossLevelingMode) {
      if (state.progress.bossLevelingEndTime != null) {
        progress = progress.copyWith(clearBossLevelingEndTime: true);
      }
      final actProgressionService = ActProgressionService(config: config);
      return actProgressionService.startFinalBossFight(state, progress, queue);
    }

    // 5. 일반 몬스터 전투
    return _createMonsterTask(state, progress, queue);
  }

  /// 시장 이동 조건 확인
  bool _shouldGoToMarket(ProgressState progress) {
    return progress.encumbrance.position >= progress.encumbrance.max &&
        progress.encumbrance.max > 0;
  }

  /// 전환 태스크 필요 여부 확인
  bool _needsTransitionTask(TaskType oldTaskType) {
    return oldTaskType != TaskType.kill &&
        oldTaskType != TaskType.neutral &&
        oldTaskType != TaskType.buying;
  }

  /// 시장 이동 태스크 생성
  ({ProgressState progress, QueueState queue}) _createMarketTask(
    ProgressState progress,
    QueueState queue,
  ) {
    final taskResult = pq_logic.startTask(
      progress,
      l10n.taskHeadingToMarket(),
      4 * 1000,
    );
    final updatedProgress = taskResult.progress.copyWith(
      currentTask: TaskInfo(caption: taskResult.caption, type: TaskType.market),
      currentCombat: null,
    );
    return (progress: updatedProgress, queue: queue);
  }

  /// 전환 태스크 생성 (buying 또는 heading)
  ({ProgressState progress, QueueState queue}) _createTransitionTask(
    GameState state,
    ProgressState progress,
    QueueState queue,
  ) {
    final gold = state.inventory.gold;
    final equipPrice = state.traits.level * 50;

    // Gold 충분 시 장비 구매
    if (gold > equipPrice) {
      final taskResult = pq_logic.startTask(
        progress,
        l10n.taskUpgradingHardware(),
        5 * 1000,
      );
      final updatedProgress = taskResult.progress.copyWith(
        currentTask: TaskInfo(
          caption: taskResult.caption,
          type: TaskType.buying,
        ),
        currentCombat: null,
      );
      return (progress: updatedProgress, queue: queue);
    }

    // Gold 부족 시 전장 이동
    final taskResult = pq_logic.startTask(
      progress,
      l10n.taskEnteringDebugZone(),
      4 * 1000,
    );
    final updatedProgress = taskResult.progress.copyWith(
      currentTask: TaskInfo(
        caption: taskResult.caption,
        type: TaskType.neutral,
      ),
      currentCombat: null,
    );
    return (progress: updatedProgress, queue: queue);
  }

  /// Act Boss 재도전 태스크 생성
  ({ProgressState progress, QueueState queue}) _createActBossRetryTask(
    GameState state,
    ProgressState progress,
    QueueState queue,
  ) {
    final actProgressionService = ActProgressionService(config: config);
    final actBoss = actProgressionService.createActBoss(state);
    final combatCalculator = CombatCalculator(rng: state.rng);
    final durationMillis = combatCalculator.estimateCombatDurationMs(
      player: actBoss.playerStats,
      monster: actBoss.monsterStats,
    );

    final taskResult = pq_logic.startTask(
      progress,
      l10n.taskDebugging(actBoss.monsterStats.name),
      durationMillis,
    );

    final updatedProgress = taskResult.progress.copyWith(
      currentTask: TaskInfo(
        caption: taskResult.caption,
        type: TaskType.kill,
        monsterBaseName: actBoss.monsterStats.name,
        monsterPart: '*',
        monsterLevel: actBoss.monsterStats.level,
        monsterGrade: MonsterGrade.boss,
        monsterSize: getBossSizeForAct(state.progress.plotStageCount),
      ),
      currentCombat: actBoss,
    );

    return (progress: updatedProgress, queue: queue);
  }

  /// 일반 몬스터 전투 태스크 생성
  ({ProgressState progress, QueueState queue}) _createMonsterTask(
    GameState state,
    ProgressState progress,
    QueueState queue,
  ) {
    final level = state.traits.level;

    // 퀘스트 몬스터 데이터 확인
    final questMonster = state.progress.currentQuestMonster;
    final questMonsterData = questMonster?.monsterData;
    final questLevel = questMonsterData != null
        ? int.tryParse(questMonsterData.split('|').elementAtOrNull(1) ?? '') ??
              0
        : null;

    // 몬스터 생성
    final monsterResult = pq_logic.monsterTask(
      config,
      state.rng,
      level,
      questMonsterData,
      questLevel,
    );

    // 몬스터 레벨 조정 (밸런스)
    final actMinLevel = ActMonsterLevel.forPlotStage(
      state.progress.plotStageCount,
    );
    final baseLevel = math.max(level, actMinLevel);
    final effectiveMonsterLevel = monsterResult.level
        .clamp(math.max(1, baseLevel - 3), baseLevel + 3)
        .toInt();

    // 전투 스탯 생성
    final playerCombatStats = CombatStats.fromStats(
      stats: state.stats,
      equipment: state.equipment,
      level: level,
      monsterLevel: effectiveMonsterLevel,
    );

    final monsterCombatStats = MonsterCombatStats.fromLevel(
      name: monsterResult.displayName,
      level: effectiveMonsterLevel,
      speedType: MonsterCombatStats.inferSpeedType(monsterResult.baseName),
      plotStageCount: state.progress.plotStageCount,
    );

    // 전투 상태 및 지속시간
    final combatState = CombatState.start(
      playerStats: playerCombatStats,
      monsterStats: monsterCombatStats,
    );

    final combatCalculator = CombatCalculator(rng: state.rng);
    final durationMillis = combatCalculator.estimateCombatDurationMs(
      player: playerCombatStats,
      monster: monsterCombatStats,
    );

    final taskResult = pq_logic.startTask(
      progress,
      l10n.taskDebugging(monsterResult.displayName),
      durationMillis,
    );

    // 몬스터 사이즈 결정
    final monsterSize = getMonsterSizeForAct(
      plotStageCount: state.progress.plotStageCount,
      grade: monsterResult.grade,
      rng: state.rng,
    );

    final updatedProgress = taskResult.progress.copyWith(
      currentTask: TaskInfo(
        caption: taskResult.caption,
        type: TaskType.kill,
        monsterBaseName: monsterResult.baseName,
        monsterPart: monsterResult.part,
        monsterLevel: effectiveMonsterLevel,
        monsterGrade: monsterResult.grade,
        monsterSize: monsterSize,
      ),
      currentCombat: combatState,
    );

    return (progress: updatedProgress, queue: queue);
  }
}
