import 'dart:io' show Platform;
import 'package:flutter/services.dart';
import 'package:unity_levelplay_mediation/unity_levelplay_mediation.dart';

const String TAG = 'InterstitialAdManager';


const String APP_KEY_IOS = '24e816d5d';


enum InterstitialAdType {
  first,
  second,
  third;

  String get displayName {
    switch (this) {
      case InterstitialAdType.first:
        return 'First Interstitial';
      case InterstitialAdType.second:
        return 'Second Interstitial';
      case InterstitialAdType.third:
        return 'Third Interstitial';
    }
  }

  /// 获取广告的 adUnitId（广告位 ID）
  String get adUnitId {
    switch (this) {
      case InterstitialAdType.first:
        return 'ipgwvc8d6vg3bbf6';
      case InterstitialAdType.second:
        return '5b53pus0enyp87xw';
      case InterstitialAdType.third:
        return 'mnhvu9lj9vrdb4fz';
    }
  }

  /// 获取广告的 placement 名称（返回广告 ID）
  String get placementName => adUnitId;
}

/// Interstitial 广告管理器（单例）
class InterstitialAdManager with LevelPlayInitListener {
  // 单例实例
  static final InterstitialAdManager _instance =
  InterstitialAdManager._internal();

  // 工厂构造函数返回单例
  factory InterstitialAdManager() {
    return _instance;
  }

  // 私有构造函数
  InterstitialAdManager._internal();

  // 三个 Interstitial 广告实例
  final Map<InterstitialAdType, LevelPlayInterstitialAd> _interstitialAds = {};

  // adId 到 adType 的映射，用于在监听器中识别广告
  final Map<String, InterstitialAdType> _adIdToTypeMap = {};

  // 初始化状态
  bool _isInitialized = false;
  bool _isInitializing = false;

  // 当前正在展示的广告（避免同时展示多个）
  InterstitialAdType? _currentShowingAd;

  // 广告完成回调映射
  final Map<InterstitialAdType, VoidCallback?> _adCompletedCallbacks = {};

  // --- 开屏广告专用回调和状态 ---
  Function(InterstitialAdType adType)? _onSplashAdReadyCallback;
  Function()? _onSplashAdAllFailedCallback;
  Set<InterstitialAdType> _splashAdsToLoad = {};
  int _splashAdsFailedCount = 0;
  bool _isHandlingSplashAd = false;

  /// 获取单例实例
  static InterstitialAdManager get instance => _instance;

  /// 获取广告实例
  LevelPlayInterstitialAd? getAd(InterstitialAdType adType) {
    return _interstitialAds[adType];
  }

  /// 初始化 LevelPlay SDK 和广告实例
  Future<void> initialize() async {
    if (_isInitialized || _isInitializing) {
      logMethodName(
        'Initialize',
        'Info',
        'Already initialized or initializing',
      );
      return;
    }

    _isInitializing = true;

    try {
      // 检查平台，只支持 iOS
      if (!Platform.isIOS) {
        logMethodName(
          'Platform Check',
          'Error',
          'This app only supports iOS platform',
        );
        _isInitializing = false;
        return;
      }

      // 初始化三个 Interstitial 广告实例，每个使用不同的 adUnitId
      for (var adType in InterstitialAdType.values) {
        final ad = LevelPlayInterstitialAd(adUnitId: adType.adUnitId);
        _interstitialAds[adType] = ad;
        ad.setListener(_InterstitialAdListenerWrapper(adType, this));
      }

      // 启用调试模式
      // await enableDebug();

      // 初始化 LevelPlay SDK
      final initRequest = LevelPlayInitRequest.builder(APP_KEY_IOS).build();
      await LevelPlay.init(initRequest: initRequest, initListener: this);
    } on PlatformException catch (e) {
      _isInitializing = false;
      logMethodName('Initialize', 'PlatformException', e);
    } catch (e) {
      _isInitializing = false;
      logMethodName('Initialize', 'Error', e);
    }
  }

  /// iOS14 IDFA 访问权限检查
  Future<void> checkATT() async {
    try {
      final currentStatus =
      await ATTrackingManager.getTrackingAuthorizationStatus();
      logMethodName(
        'getTrackingAuthorizationStatus',
        'ATTStatus:',
        currentStatus,
      );
      if (currentStatus == ATTStatus.NotDetermined) {
        final returnedStatus =
        await ATTrackingManager.requestTrackingAuthorization();
        logMethodName(
          'requestTrackingAuthorizationATTStatus',
          'ATTStatus returned:',
          returnedStatus,
        );
      }
    } catch (e) {
      logMethodName('checkATT', 'Error', e);
    }
  }

  /// 启用调试模式
  Future<void> enableDebug() async {
    try {
      await LevelPlay.setAdaptersDebug(true);
      LevelPlay.validateIntegration();
    } catch (e) {
      logMethodName('enableDebug', 'Error', e);
    }
  }

  /// 加载开屏广告的专用方法 - 并行加载三个广告，任意一个成功就立即回调并跳转
  /// 如果所有广告都失败，则调用 onAllAdsFailed
  void loadInitialSplashAd({
    required Function(InterstitialAdType adType) onAdReady,
    required Function() onAllAdsFailed,
  }) {
    if (!_isInitialized) {
      logMethodName(
        'LoadInitialSplashAd',
        'Warning',
        'Manager not initialized yet. Call initialize() first.',
      );
      onAllAdsFailed();
      return;
    }

    _onSplashAdReadyCallback = onAdReady;
    _onSplashAdAllFailedCallback = onAllAdsFailed;
    _splashAdsFailedCount = 0;
    _isHandlingSplashAd = true;

    _splashAdsToLoad = {
      InterstitialAdType.first,
      InterstitialAdType.second,
      InterstitialAdType.third,
    };

    logMethodName('LoadInitialSplashAd', 'Info', '开始并行加载初始开屏广告...');
    for (final adType in _splashAdsToLoad) {
      loadAd(adType);
    }
  }

  /// 清除开屏广告回调的私有方法
  void _clearSplashCallbacks() {
    _onSplashAdReadyCallback = null;
    _onSplashAdAllFailedCallback = null;
    _splashAdsToLoad.clear();
    _splashAdsFailedCount = 0;
    _isHandlingSplashAd = false;
  }

  /// 加载指定类型的广告
  Future<void> loadAd(InterstitialAdType adType) async {
    if (!_isInitialized) {
      logMethodName(
        'LoadAd',
        'Warning',
        'Manager not initialized yet. Call initialize() first.',
      );
      return;
    }

    final ad = _interstitialAds[adType];
    if (ad != null) {
      try {
        await ad.loadAd();
        // 加载后更新 adId 映射
        if (ad.adId.isNotEmpty) {
          _adIdToTypeMap[ad.adId] = adType;
        }
        logMethodName('LoadAd', 'Success', 'Loading ${adType.displayName}');
      } catch (e) {
        logMethodName(
          'LoadAd',
          'Error',
          'Failed to load ${adType.displayName}: $e',
        );
      }
    } else {
      logMethodName(
        'LoadAd',
        'Error',
        'Ad instance not found for ${adType.displayName}',
      );
    }
  }

  /// 显示指定类型的广告
  /// [onAdCompleted] 广告完成回调（广告关闭或展示失败时调用）
  Future<void> showAd(
      InterstitialAdType adType, {
        VoidCallback? onAdCompleted,
      }) async {
    if (!_isInitialized) {
      logMethodName(
        'ShowAd',
        'Warning',
        'Manager not initialized yet. Call initialize() first.',
      );
      return;
    }

    // 如果已有广告在展示，直接忽略新的展示请求，避免串台
    if (_currentShowingAd != null) {
      logMethodName(
        'ShowAd',
        'Info',
        'Another interstitial is showing (${_currentShowingAd!.displayName}), skip ${adType.displayName}',
      );
      return;
    }

    final ad = _interstitialAds[adType];
    if (ad != null) {
      try {
        final isReady = await ad.isAdReady();
        if (isReady) {
          _currentShowingAd = adType;
          // 保存完成回调
          _adCompletedCallbacks[adType] = onAdCompleted;
          await ad.showAd(placementName: adType.placementName);
          logMethodName('ShowAd', 'Success', 'Showing ${adType.displayName}');
        } else {
          logMethodName(
            'ShowAd',
            'Warning',
            '${adType.displayName} is not ready yet',
          );
          // 如果未就绪，尝试重新加载
          await loadAd(adType);
          // 广告未就绪时也调用完成回调
          onAdCompleted?.call();
        }
      } catch (e) {
        logMethodName(
          'ShowAd',
          'Error',
          'Failed to show ${adType.displayName}: $e',
        );
        // 避免异常导致状态悬挂
        if (_currentShowingAd == adType) {
          _currentShowingAd = null;
        }
        // 异常时调用完成回调
        onAdCompleted?.call();
      }
    } else {
      logMethodName(
        'ShowAd',
        'Error',
        'Ad instance not found for ${adType.displayName}, try to load it.',
      );
      // 理论上初始化已创建实例；若缺失则尝试加载
      await loadAd(adType);
      // 广告实例不存在时也调用完成回调
      onAdCompleted?.call();
    }
  }

  /// 检查指定类型的广告是否已准备好
  Future<bool> isAdReady(InterstitialAdType adType) async {
    if (!_isInitialized) {
      return false;
    }

    final ad = _interstitialAds[adType];
    if (ad != null) {
      try {
        return await ad.isAdReady();
      } catch (e) {
        logMethodName(
          'isAdReady',
          'Error',
          'Failed to check ${adType.displayName}: $e',
        );
        return false;
      }
    }
    return false;
  }

  /// 检查是否已初始化
  bool get isInitialized => _isInitialized;

  /// LevelPlay Init listener
  @override
  void onInitFailed(LevelPlayInitError error) {
    ////初始化失败
    logMethodName('❌InitListener', 'onInitFailed', error);
    _isInitialized = false;
    _isInitializing = false;
  }

  @override
  void onInitSuccess(LevelPlayConfiguration configuration) {
    //初始化成功
    logMethodName('✅InitListener', 'onInitSuccess', configuration);
    _isInitialized = true;
    _isInitializing = false;
  }

  /// 内部方法：处理广告事件（由监听器包装类调用）
  void _handleAdEvent(
      InterstitialAdType adType,
      String eventName,
      dynamic data,
      ) {
    logMethodName('${adType.displayName}', eventName, data);
  }

  /// 工具函数
  void logMethodName(String adFormat, String methodName, dynamic data) {
    print('$TAG: $adFormat - $methodName $data');
  }
}

/// Interstitial 广告监听器包装类
/// 用于为每个广告实例创建独立的监听器，以便准确识别事件来源
class _InterstitialAdListenerWrapper with LevelPlayInterstitialAdListener {
  final InterstitialAdType adType;
  final InterstitialAdManager manager;

  _InterstitialAdListenerWrapper(this.adType, this.manager);

  @override
  void onAdClicked(LevelPlayAdInfo adInfo) {
    manager._handleAdEvent(adType, 'onAdClicked', adInfo);
  }

  @override
  void onAdClosed(LevelPlayAdInfo adInfo) {
    manager._handleAdEvent(adType, 'onAdClosed', adInfo);

    // 调用完成回调
    final callback = manager._adCompletedCallbacks[adType];
    callback?.call();
    manager._adCompletedCallbacks.remove(adType);

    // 广告关闭后，自动重新加载该广告以便下次使用
    manager.logMethodName(
      'onAdClosed',
      'Info',
      '广告已关闭，开始重新加载: ${adType.displayName}',
    );
    // 清理当前展示状态
    if (manager._currentShowingAd == adType) {
      manager._currentShowingAd = null;
    }
    manager.loadAd(adType);
  }

  @override
  void onAdDisplayFailed(LevelPlayAdError error, LevelPlayAdInfo adInfo) {
    manager._handleAdEvent(adType, 'onAdDisplayFailed', '$error | $adInfo');

    // 调用完成回调
    final callback = manager._adCompletedCallbacks[adType];
    callback?.call();
    manager._adCompletedCallbacks.remove(adType);

    // 广告展示失败后，也重新加载该广告
    manager.logMethodName(
      'onAdDisplayFailed',
      'Info',
      '广告展示失败，开始重新加载: ${adType.displayName}',
    );
    // 展示失败时清理当前展示状态
    if (manager._currentShowingAd == adType) {
      manager._currentShowingAd = null;
    }
    manager.loadAd(adType);
  }

  @override
  void onAdDisplayed(LevelPlayAdInfo adInfo) {
    manager._handleAdEvent(adType, 'onAdDisplayed', adInfo);
  }

  @override
  void onAdInfoChanged(LevelPlayAdInfo adInfo) {
    manager._handleAdEvent(adType, 'onAdInfoChanged', adInfo);
  }

  @override
  void onAdLoadFailed(LevelPlayAdError error) {
    manager._handleAdEvent(adType, 'onAdLoadFailed', error);

    // 处理开屏广告失败逻辑
    if (manager._isHandlingSplashAd &&
        manager._splashAdsToLoad.contains(adType) &&
        manager._onSplashAdAllFailedCallback != null) {
      manager.logMethodName(
        'LoadInitialSplashAd',
        'Failed',
        '❌ 广告加载失败: ${adType.displayName}, 原因: $error',
      );
      manager._splashAdsFailedCount++;
      if (manager._splashAdsFailedCount >= manager._splashAdsToLoad.length) {
        manager._onSplashAdAllFailedCallback!();
        manager._clearSplashCallbacks();
      }
    }
  }

  @override
  void onAdLoaded(LevelPlayAdInfo adInfo) {
    manager._handleAdEvent(adType, 'onAdLoaded', adInfo);

    // 处理开屏广告逻辑：任意一个加载成功就立即回调（只触发一次）
    if (manager._isHandlingSplashAd &&
        manager._splashAdsToLoad.contains(adType) &&
        manager._onSplashAdReadyCallback != null) {
      manager.logMethodName(
        'LoadInitialSplashAd',
        'Success',
        '✅ 广告加载成功: ${adType.displayName}',
      );
      manager._onSplashAdReadyCallback!(adType);
      // 清除回调状态，确保后续广告加载成功不会再次触发回调
      manager._clearSplashCallbacks();
    }
  }
}
