import 'package:asciineverdie/src/core/engine/ad_service.dart';
import 'package:asciineverdie/src/core/engine/iap_service.dart';
import 'package:asciineverdie/src/core/engine/progress_loop.dart';
import 'package:asciineverdie/src/core/model/monetization_state.dart';
import 'package:flutter/foundation.dart';

/// 속도 부스트(광고 배속) 기능 관리자
///
/// 광고 시청 후 일정 시간 동안 게임 속도를 높이는 기능을 담당합니다.
/// 게임 시간(elapsedMs) 기준으로 종료 시점을 판정합니다.
class SpeedBoostManager {
  SpeedBoostManager({
    required bool Function() cheatsEnabledGetter,
    required Future<List<int>> Function() getAvailableSpeeds,
  }) : _cheatsEnabledGetter = cheatsEnabledGetter,
       _getAvailableSpeeds = getAvailableSpeeds;

  final bool Function() _cheatsEnabledGetter;
  final Future<List<int>> Function() _getAvailableSpeeds;

  // 속도 부스트 상태
  bool _isSpeedBoostActive = false;
  static const int _speedBoostDuration = 300; // 5분 (게임 시간 기준, 초)

  // 광고 표시 중 플래그 (lifecycle reload 방지용)
  bool _isShowingAd = false;
  int _adEndTimeMs = 0; // 광고 종료 시점 (밀리초)

  /// 배속 저장 (pause/resume 시 유지)
  int savedSpeedMultiplier = 1;

  /// 상태 변경 알림 콜백
  VoidCallback? onStateChanged;

  /// 광고 배속 배율 (릴리즈: 5x, 디버그빌드+디버그모드: 20x)
  int get speedBoostMultiplier =>
      (kDebugMode && _cheatsEnabledGetter()) ? 20 : 5;

  /// 속도 부스트 활성화 여부
  bool get isSpeedBoostActive => _isSpeedBoostActive;

  /// 광고 표시 중 여부 (lifecycle reload 방지용)
  bool get isShowingAd => _isShowingAd;

  /// 최근 광고를 시청했는지 여부 (1초 이내)
  bool get isRecentlyShowedAd {
    if (_adEndTimeMs == 0) return false;
    return DateTime.now().millisecondsSinceEpoch - _adEndTimeMs < 1000;
  }

  /// 속도 부스트 지속 시간 (초)
  int get speedBoostDuration => _speedBoostDuration;

  /// 속도 부스트 남은 시간 (초) - 게임 시간(elapsedMs) 기준 계산
  int getRemainingSeconds(
    MonetizationState monetization,
    int currentElapsedMs,
  ) {
    if (!_isSpeedBoostActive) return 0;
    final endMs = monetization.speedBoostEndMs;
    if (endMs == null) return 0;
    final remainingMs = endMs - currentElapsedMs;
    return remainingMs > 0 ? (remainingMs / 1000).ceil() : 0;
  }

  /// 현재 실제 배속 (부스트 적용 포함)
  int getCurrentSpeedMultiplier(ProgressLoop? loop) {
    if (_isSpeedBoostActive) return speedBoostMultiplier;
    return loop?.speedMultiplier ?? savedSpeedMultiplier;
  }

  /// 속도 부스트 활성화 (광고 시청 후)
  ///
  /// 유료 유저: 무료 활성화
  /// 무료 유저: 인터스티셜 광고 시청 후 활성화
  /// Returns: (활성화 성공 여부, 업데이트된 monetization)
  Future<(bool, MonetizationState)> activateSpeedBoost({
    required ProgressLoop? loop,
    required MonetizationState monetization,
    required int currentElapsedMs,
  }) async {
    if (_isSpeedBoostActive) return (false, monetization);
    if (loop == null) return (false, monetization);

    // 유료 유저는 무료 활성화
    if (IAPService.instance.isAdRemovalPurchased) {
      final updatedMonetization = _startSpeedBoost(
        loop: loop,
        monetization: monetization,
        currentElapsedMs: currentElapsedMs,
      );
      debugPrint('[SpeedBoost] Activated (paid user)');
      return (true, updatedMonetization);
    }

    // 무료 유저는 인터스티셜 광고 필요
    MonetizationState updatedMonetization = monetization;
    bool activated = false;
    _isShowingAd = true;

    final adResult = await AdService.instance.showInterstitialAd(
      adType: AdType.interstitialSpeed,
      onComplete: () {
        updatedMonetization = _startSpeedBoost(
          loop: loop,
          monetization: monetization,
          currentElapsedMs: currentElapsedMs,
        );
        activated = true;
      },
    );

    _isShowingAd = false;
    _adEndTimeMs = DateTime.now().millisecondsSinceEpoch;

    if (adResult == AdResult.completed || adResult == AdResult.debugSkipped) {
      debugPrint('[SpeedBoost] Activated (free user with ad)');
      return (activated, updatedMonetization);
    }

    debugPrint('[SpeedBoost] Activation failed: $adResult');
    return (false, monetization);
  }

  /// 속도 부스트 시작 (내부)
  MonetizationState _startSpeedBoost({
    required ProgressLoop? loop,
    required MonetizationState monetization,
    required int currentElapsedMs,
  }) {
    _isSpeedBoostActive = true;

    // loop가 있으면 현재 배속 저장 및 즉시 적용
    if (loop != null) {
      savedSpeedMultiplier = loop.speedMultiplier;
      loop.updateAvailableSpeeds([speedBoostMultiplier]);
    }

    // 종료 시점 저장 (게임 시간 기준)
    final endMs = currentElapsedMs + (_speedBoostDuration * 1000);
    final updatedMonetization = monetization.copyWith(speedBoostEndMs: endMs);

    debugPrint('[SpeedBoost] Started, ends at $endMs ms');
    onStateChanged?.call();

    return updatedMonetization;
  }

  /// 매 틱마다 부스트 만료 체크
  ///
  /// Returns: 부스트가 종료되었으면 true
  bool checkExpiry({
    required int elapsedMs,
    required MonetizationState monetization,
    required ProgressLoop? loop,
  }) {
    if (!_isSpeedBoostActive) return false;

    final endMs = monetization.speedBoostEndMs;
    if (endMs != null && elapsedMs >= endMs) {
      endSpeedBoost(loop: loop);
      return true;
    }
    return false;
  }

  /// 속도 부스트 종료 (외부 호출 가능)
  void endSpeedBoost({required ProgressLoop? loop}) {
    _isSpeedBoostActive = false;

    // 원래 배속 복원
    if (loop != null) {
      final savedSpeed = savedSpeedMultiplier;

      _getAvailableSpeeds().then((speeds) {
        loop.updateAvailableSpeeds(speeds);
        loop.setSpeed(savedSpeed);
        debugPrint('[SpeedBoost] Speed restored to ${savedSpeed}x');
      });
    }

    onStateChanged?.call();
    debugPrint('[SpeedBoost] Ended');
  }

  /// 속도 부스트 수동 취소
  ///
  /// Returns: 업데이트된 monetization
  MonetizationState cancelSpeedBoost({
    required ProgressLoop? loop,
    required MonetizationState monetization,
  }) {
    if (_isSpeedBoostActive) {
      endSpeedBoost(loop: loop);
    }
    return monetization.copyWith(speedBoostEndMs: null);
  }

  /// 부스트 상태에 따른 초기 배속 설정 계산
  ///
  /// startNew() 호출 시 사용
  ({List<int> speeds, int initialSpeed}) calculateInitialSpeeds({
    required List<int> baseAvailableSpeeds,
    required int baseSpeed,
  }) {
    if (_isSpeedBoostActive) {
      // 부스트 상태: 부스트 배속만 사용, 기본 배속 저장
      savedSpeedMultiplier = baseSpeed;
      return (
        speeds: [speedBoostMultiplier],
        initialSpeed: speedBoostMultiplier,
      );
    }
    // 일반 상태: 기본 배속 사용
    return (speeds: baseAvailableSpeeds, initialSpeed: baseSpeed);
  }
}
