import 'dart:async';

import 'package:asciineverdie/src/core/engine/debug_settings_service.dart';
import 'package:asciineverdie/src/core/engine/progress_loop.dart';
import 'package:asciineverdie/src/core/engine/return_rewards_service.dart';
import 'package:asciineverdie/src/core/model/game_state.dart';
import 'package:asciineverdie/src/core/model/monetization_state.dart';
import 'package:asciineverdie/src/core/model/treasure_chest.dart';
import 'package:asciineverdie/src/core/storage/save_manager.dart';
import 'package:flutter/foundation.dart';

/// 복귀 보상 기능 관리자 (Phase 7)
///
/// 장시간 접속하지 않은 유저에게 복귀 보상(상자)을 지급하는
/// 기능을 담당합니다.
class ReturnRewardsManager {
  ReturnRewardsManager();

  // 대기 중인 복귀 보상
  ReturnChestReward? _pendingReturnReward;

  /// 복귀 보상 콜백 (UI에서 다이얼로그 표시용)
  void Function(ReturnChestReward reward)? onReturnRewardAvailable;

  /// 대기 중인 복귀 보상
  ReturnChestReward? get pendingReturnReward => _pendingReturnReward;

  /// 복귀 보상 체크 (로드 시 호출)
  ///
  /// 오프라인 시간에 따라 보상을 계산하고, 보상이 있으면
  /// UI에 알림을 예약합니다.
  void checkReturnRewards({
    required MonetizationState monetization,
    required GameState loaded,
  }) {
    final rewardsService = ReturnRewardsService.instance;
    final debugSettings = DebugSettingsService.instance;

    // 디버그 모드: 오프라인 시간 시뮬레이션 적용
    final lastPlayTime = debugSettings.getSimulatedLastPlayTime(
      monetization.lastPlayTime,
    );

    final reward = rewardsService.calculateReward(
      lastPlayTime: lastPlayTime,
      currentTime: DateTime.now(),
      isPaidUser: monetization.isPaidUser,
    );

    if (reward.hasReward) {
      _pendingReturnReward = reward;
      debugPrint(
        '[ReturnRewards] Reward available: ${reward.chestCount} chests, '
        '${reward.hoursAway} hours away',
      );

      // UI에서 다이얼로그 표시를 위해 콜백 호출
      // startNew 후에 호출하도록 딜레이
      Future<void>.delayed(const Duration(milliseconds: 500), () {
        if (_pendingReturnReward != null) {
          onReturnRewardAvailable?.call(_pendingReturnReward!);
        }
      });
    }
  }

  /// 복귀 보상 수령 완료 (상자 보상 적용)
  ///
  /// [rewards] 오픈된 상자 보상 목록
  /// Returns: 보상이 적용된 새로운 GameState
  Future<GameState?> applyReturnReward({
    required List<ChestReward> rewards,
    required GameState state,
    required ProgressLoop? loop,
    required SaveManager saveManager,
    required bool cheatsEnabled,
    required MonetizationState monetization,
  }) async {
    if (rewards.isEmpty) {
      // 보상 없이 건너뛴 경우
      _pendingReturnReward = null;
      debugPrint('[ReturnRewards] Reward skipped');
      return null;
    }

    var updatedState = state;

    // 보상 적용
    for (final reward in rewards) {
      updatedState = _applySingleReward(updatedState, reward);
    }

    loop?.replaceState(updatedState); // ProgressLoop 상태도 업데이트

    // 저장
    unawaited(
      saveManager.saveState(
        updatedState,
        cheatsEnabled: cheatsEnabled,
        monetization: monetization,
      ),
    );

    _pendingReturnReward = null;

    debugPrint('[ReturnRewards] Rewards applied: ${rewards.length} items');
    return updatedState;
  }

  /// 단일 보상 적용 (내부)
  GameState _applySingleReward(GameState state, ChestReward reward) {
    switch (reward.type) {
      case ChestRewardType.equipment:
        return _applyEquipmentReward(state, reward);
      case ChestRewardType.potion:
        return _applyPotionReward(state, reward);
      case ChestRewardType.gold:
        return _applyGoldReward(state, reward);
      case ChestRewardType.experience:
        return _applyExperienceReward(state, reward);
    }
  }

  /// 장비 보상 적용
  GameState _applyEquipmentReward(GameState state, ChestReward reward) {
    if (reward.equipment == null) return state;

    // 현재 장비와 비교하여 더 좋으면 자동 장착
    final slotIndex = reward.equipment!.slot.index;
    final currentItem = state.equipment.getItemByIndex(slotIndex);

    if (currentItem.isEmpty ||
        reward.equipment!.itemWeight > currentItem.itemWeight) {
      debugPrint('[ReturnRewards] Equipped: ${reward.equipment!.name}');
      return state.copyWith(
        equipment: state.equipment.setItemByIndex(slotIndex, reward.equipment!),
      );
    }

    // 더 좋지 않으면 판매 (골드로 변환)
    final sellPrice = (reward.equipment!.level * 50 * 0.3).round().clamp(
      1,
      99999,
    );
    debugPrint(
      '[ReturnRewards] Sold: ${reward.equipment!.name} '
      'for $sellPrice gold',
    );
    return state.copyWith(
      inventory: state.inventory.copyWith(
        gold: state.inventory.gold + sellPrice,
      ),
    );
  }

  /// 포션 보상 적용
  GameState _applyPotionReward(GameState state, ChestReward reward) {
    if (reward.potionId == null) return state;

    debugPrint(
      '[ReturnRewards] Added potion: ${reward.potionId} '
      'x${reward.potionCount}',
    );
    return state.copyWith(
      potionInventory: state.potionInventory.addPotion(
        reward.potionId!,
        reward.potionCount ?? 1,
      ),
    );
  }

  /// 골드 보상 적용
  GameState _applyGoldReward(GameState state, ChestReward reward) {
    if (reward.gold == null || reward.gold! <= 0) return state;

    debugPrint('[ReturnRewards] Added gold: ${reward.gold}');
    return state.copyWith(
      inventory: state.inventory.copyWith(
        gold: state.inventory.gold + reward.gold!,
      ),
    );
  }

  /// 경험치 보상 적용
  GameState _applyExperienceReward(GameState state, ChestReward reward) {
    if (reward.experience == null || reward.experience! <= 0) return state;

    debugPrint('[ReturnRewards] Added experience: ${reward.experience}');
    return state.copyWith(
      progress: state.progress.copyWith(
        exp: state.progress.exp.copyWith(
          position: state.progress.exp.position + reward.experience!,
        ),
      ),
    );
  }

  /// 복귀 보상 건너뛰기
  void skipReturnReward() {
    _pendingReturnReward = null;
    debugPrint('[ReturnRewards] Reward skipped by user');
  }
}
