import 'dart:async';

import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:logging/logging.dart';
import 'package:provider/provider.dart';
import 'package:puzzleweave/ads/applovin_ads_controller.dart';
import 'package:puzzleweave/l10n/app_localizations.dart';
import 'package:puzzleweave/persistence/persistence.dart';
import 'package:puzzleweave/skin/skin.dart';

import '../remote_config/remote_config.dart';
import 'ad_helper.dart';

final Logger _log = Logger('AdsState');

/// Add by guoziyi
/// 自带广告的 StatefulWidget State
/// 从该类继承的 State 自动带有广告功能
abstract class AdsState<T extends StatefulWidget> extends State<T> {
  ///这个值用于数据统计，子类应该在initState初始化的时候正确设置skuId
  String skuId = "";

  VoidCallback? onEnterBackground; // app 进入后台回调， 外部如关心， 可设置此回调
  Function(Duration duration)? onEnterForeground; // app 回到前台回调， 外部如关心， 可设置此回调
  Function(AdState state)? onRewardAdState; // reward广告状态回调，外部如关心，可设置此回调
  Function(AdState state)? onInterstitialAdState; // reward广告状态回调，外部如关心，可设置此回调

  late ApplovinAdsController _applovinAdsController;
  late ValueNotifier<AppLifecycleState> lifecycleNotifier;

  Completer<bool>? _intersCompleter;
  Completer<bool>? _rewardCompleter;

  bool earnedReward = false; //是否确定获得激励

  //插屏广告是否准备好
  late ValueNotifier<bool> intersReadyNotifier;
  bool get isIntersReady => intersReadyNotifier.value;
  //激励广告是否准备好
  late ValueNotifier<bool> rewardReadyNotifier;
  bool get isRewardReady => rewardReadyNotifier.value;

  //插屏广告当前状态
  AdState get intersState => _applovinAdsController.interstitialAdState.value;
  //激励广告当前状态
  AdState get rewardState => _applovinAdsController.rewardedAdState.value;

  @override
  void initState() {
    super.initState();
    _applovinAdsController = context.read<ApplovinAdsController>();
    _applovinAdsController.interstitialAdState.removeListener(_onInterstitialAdState);
    _applovinAdsController.interstitialAdState.addListener(_onInterstitialAdState);

    _applovinAdsController.rewardedAdState.removeListener(_onRewardAdState);
    _applovinAdsController.rewardedAdState.addListener(_onRewardAdState);

    intersReadyNotifier = ValueNotifier(intersState == AdState.ready);
    rewardReadyNotifier = ValueNotifier(rewardState == AdState.ready);

    lifecycleNotifier = context.read<ValueNotifier<AppLifecycleState>>();
    lifecycleNotifier.removeListener(_handleAppLifecycle);
    lifecycleNotifier.addListener(_handleAppLifecycle);

    _applovinAdsController.loadInterstitialAd();
    _applovinAdsController.loadRewardedAd();
  }

  @override
  void dispose() {
    intersReadyNotifier.dispose();
    rewardReadyNotifier.dispose();

    lifecycleNotifier.removeListener(_handleAppLifecycle);
    if (_intersCompleter != null && !_intersCompleter!.isCompleted) {
      _intersCompleter!.complete(false);
    }
    _intersCompleter = null;
    if (_rewardCompleter != null && !_rewardCompleter!.isCompleted) {
      _rewardCompleter!.complete(false);
    }
    _rewardCompleter = null;
    _applovinAdsController.interstitialAdState.removeListener(_onInterstitialAdState);
    _applovinAdsController.rewardedAdState.removeListener(_onRewardAdState);
    super.dispose();
  }

  /// 广告 sdk 是否初始化完成
  Future<bool> adSDKReady() async {
    return _applovinAdsController.completer.future;
  }

  /// 检查是否应该展示banner广告
  bool shouldShowBannerAd(int doneLevels) {
    if (doneLevels == 0) {
      _log.info("首关不展示banner广告");
      return false; // 首关是引导关卡，一定不要显示广告
    }

    bool levelShould = doneLevels >= RemoteConfig().intersFreeLevels;

    DateTime now = DateTime.now();

    int bannerFreeDuration = RemoteConfig().bannerFreeDuration;
    DateTime firstRunTime = Persistence().firstRunTime;
    bool timeShould = now.difference(firstRunTime).inMinutes > bannerFreeDuration;

    return levelShould || timeShould;
  }

  /// banner 广告
  Widget get adBanner {
    return _applovinAdsController.bannerAdWidget;
  }

  ///显示激励广告
  ///返回奖励获取结果。true：成功获取到奖励；false；未获得奖励
  Future<bool> showRewardAd(String src, String skuId) async {
    if (!(await _applovinAdsController.isRewardedAdReady())) {
      _applovinAdsController.loadRewardedAd();
      if (mounted) {
        Fluttertoast.showToast(
          msg: AppLocalizations.of(context)!.adNotReady,
          toastLength: Toast.LENGTH_SHORT,
          gravity: ToastGravity.CENTER,
          timeInSecForIosWeb: 1,
          backgroundColor: SkinHelper.slotBorderColor,
          textColor: Colors.white,
          fontSize: 16.0,
        );
      }
      return false;
    }

    if (_rewardCompleter != null && !_rewardCompleter!.isCompleted) {
      _rewardCompleter!.complete(earnedReward);
    }
    _rewardCompleter = Completer<bool>();

    this.skuId = skuId;
    earnedReward = false;
    _applovinAdsController.showRewardedlAd(
      adSrc: src,
      skuId: skuId,
      onUserEarnedReward: (ad, reward) {
        _log.info("................earn reward..........");
        earnedReward = true;
      },
    );
    return _rewardCompleter!.future;
  }

  bool shouldShowInterstitialAd(String src, int doneLevels) {
    bool shouldShowAd = false;
    if (src == 'level_enter') {
      shouldShowAd = _shouldShowEnterIntersAd(doneLevels);
    } else {
      shouldShowAd = _shouldShowExitIntersAd(doneLevels);
    }
    return shouldShowAd;
  }

  ///显示插屏广告
  ///返回广告播放结果。true：播放成功；false；播放失败
  Future<bool> showInterstitialAd(String src, String skuId, int doneLevels) async {
    bool shouldShowAd = shouldShowInterstitialAd(src, doneLevels);
    if (!shouldShowAd) return false;

    // 插屏广告没有预备好或者当前不符合播放插屏广告条件，直接返回false
    if (!(await _applovinAdsController.isInterstitialAdReady())) {
      _applovinAdsController.loadInterstitialAd();
      return false;
    }

    if (_intersCompleter != null && !_intersCompleter!.isCompleted) {
      _intersCompleter!.complete(false);
    }
    _intersCompleter = Completer<bool>();

    this.skuId = skuId;
    _applovinAdsController.showInterstitialAd(adSrc: src, skuId: skuId);

    return _intersCompleter!.future;
  }

  // 检查是否应该展示进入插屏广告
  bool _shouldShowEnterIntersAd(int doneLevels) {
    if (doneLevels == 0) return false; // 首关是引导关卡，一定不要显示广告

    bool levelShould = doneLevels >= RemoteConfig().intersFreeLevels;

    DateTime now = DateTime.now();
    int enterIntersDuration = RemoteConfig().enterIntersFreeDuration; //新手保护时长，单位：分钟
    DateTime firstRunTime = Persistence().firstRunTime;
    bool timeShould = now.difference(firstRunTime).inMinutes > enterIntersDuration; //判断当前时间是否已超过新手保护时长

    return levelShould || timeShould; // 时间限制和关卡限制两者只要满足其一都可以播放插屏
  }

  // 检查是否应该展示退出插屏广告
  bool _shouldShowExitIntersAd(int doneLevels) {
    bool levelShould = doneLevels >= RemoteConfig().intersFreeLevels;

    DateTime now = DateTime.now();
    int quitIntersDuration = RemoteConfig().quitIntersFreeDuration; //新手保护时长，单位：分钟
    DateTime firstRunTime = Persistence().firstRunTime;
    bool timeShould = now.difference(firstRunTime).inMinutes > quitIntersDuration;

    return levelShould || timeShould; // 时间限制和关卡限制两者只要满足其一都可以播放插屏
  }

  // 插屏广告回调处理
  _onInterstitialAdState() {
    if (intersState == AdState.dismissed) {
      _log.info("onInterstitialAdState AdState.dismissed");
      if (_intersCompleter != null && !_intersCompleter!.isCompleted) {
        _intersCompleter!.complete(true);
      }
      _intersCompleter = null;
    }
    intersReadyNotifier.value = (intersState == AdState.ready);
    onInterstitialAdState?.call(intersState);
  }

  // 激励广告回调处理
  _onRewardAdState() {
    if (_applovinAdsController.rewardedAdState.value == AdState.dismissed) {
      _log.info("onRewardAdState AdState.dismissed");
      if (_rewardCompleter != null && !_rewardCompleter!.isCompleted) {
        _rewardCompleter!.complete(earnedReward);
      }
      _rewardCompleter = null;
    }
    rewardReadyNotifier.value = (rewardState == AdState.ready);

    onRewardAdState?.call(rewardState);
  }

  ///-----------[Lifecycle]-------------
  ///需要处理可重写状态处理函数
  AppLifecycleState lifeState = AppLifecycleState.resumed;
  bool get isActive => lifeState == AppLifecycleState.resumed;
  void _handleAppLifecycle() {
    _log.info('AppLifecycleState changed: ${lifecycleNotifier.value}');
    lifeState = lifecycleNotifier.value;

    if (lifeState == AppLifecycleState.inactive) {
      //前台可见，但是无法交互
      onInactive();
    } else if (lifeState == AppLifecycleState.paused) {
      //前台不可见
      onPause();
    } else if (lifeState == AppLifecycleState.resumed) {
      //前台可见，可交互
      onResume();
    }
  }

  void onInactive() {}

  DateTime? _leaveTime;
  void onPause() {
    if (intersState == AdState.showing || rewardState == AdState.showing) {
      return;
    }
    _leaveTime = DateTime.now(); // 记录切换到后台的时间
    onEnterBackground?.call();
    _log.info("App enter background, leaveTime: $_leaveTime");
  }

  void onResume() {
    if (_leaveTime != null) {
      var duration = DateTime.now().difference(_leaveTime!);
      _log.info("App enter foreground, leaveTime: $_leaveTime, duration=$duration");
      onEnterForeground?.call(duration);
    }
    _leaveTime = null;
  }
}
