import 'package:guru_app/ads/ads_manager.dart';
import 'package:guru_app/ads/core/ads.dart';
import 'package:guru_app/ads/core/ads_config.dart';
import 'package:guru_utils/log/log.dart';
import 'package:guru_applovin_flutter/guru_applovin_flutter.dart';
import 'package:guru_applovin_flutter/interstitial_ad.dart';
import 'package:guru_utils/ads/ads.dart';



/// Created by Haoyi on 5/6/21

class ApplovinInterstitialAds extends InterstitialAds<InterstitialAdEvent> {
  late InterstitialAd interstitialAd;

  @override
  final AdUnitId adUnitId;
  final AdSlotId? adAmazonSlotId;

  // @override
  // RetryConfig get retryConfig {
  //   final adsService = Injector.provide<AdsService>();
  //   return adsService.adsConfig.interstitialConfig.retryConfig;
  // }

  ApplovinInterstitialAds.create(this.adUnitId, this.adAmazonSlotId);

  @override
  void init() {
    super.init();
    interstitialAd = InterstitialAd(
        adUnitId: adUnitId.id, adAmazonSlotId: adAmazonSlotId?.id, listener: dispatchEvent);
  }

  @override
  Map<InterstitialAdEvent, AdsEvent> get eventsMapping => {
        InterstitialAdEvent.onAdLoaded: AdsEvent.adLoaded,
        InterstitialAdEvent.onAdLoadFailed: AdsEvent.adLoadFailed,
        InterstitialAdEvent.onAdDisplayFailed: AdsEvent.adDisplayFailed,
        InterstitialAdEvent.onAdDisplayed: AdsEvent.adDisplayed,
        InterstitialAdEvent.onAdClicked: AdsEvent.adClick,
        InterstitialAdEvent.onAdHidden: AdsEvent.adHidden,
      };

  @override
  Future<bool> requestDispose() async {
    try {
      return await interstitialAd.dispose() ?? false;
    } catch (error, stacktrace) {
      Log.w("requestDispose error", error: error, stackTrace: stacktrace);
      return false;
    }
  }

  @override
  Future<bool> requestHide() async {
    return false;
  }

  @override
  Future<AdCause> requestLoad() async {
    try {
      Log.w("[$runtimeType] requestLoad", tag: "Ads");
      final result = await interstitialAd.load() ?? false;
      if (result) {
        return AdCause.success;
      } else {
        return AdCause.requestFailed;
      }
    } catch (error, stacktrace) {
      Log.w("requestLoad error! $error  $stacktrace");
      return AdCause.internalError;
    }
  }

  @override
  Future<AdCause> requestShow({required String scene, bool ignoreCheck = false}) async {
    // final now = DateTimeUtils.currentTimeInMillis();
    // final impGapInMillis = AdsManager.instance.adsConfig.interstitialConfig.impGapInSeconds * 1000;
    // if ((now - AdsManager.instance.latestFullscreenAdsHiddenTimestamps) < 60000 ||
    //     ((now - latestHiddenAt) < impGapInMillis)) {
    //   Log.d("show ads too frequency", syncFirebase: true);
    //   return AdCause.tooFrequent;
    // }
    if (!ignoreCheck) {
      final result = AdsManager.instance.canShowInterstitial(scene);
      if (result != AdCause.success) {
        return result;
      }
    }
    Log.d("[$runtimeType] requestShow", tag: "Ads", syncFirebase: true);
    try {
      final result = await interstitialAd.show(placement: scene) ?? false;
      if (result) {
        return AdCause.success;
      } else {
        return AdCause.requestFailed;
      }
    } catch (error, stacktrace) {
      Log.w("requestShow error", error: error, stackTrace: stacktrace, syncFirebase: true);
      return AdCause.internalError;
    }
  }

  @override
  Future<bool> checkLoaded() async {
    try {
      return await interstitialAd.isLoaded() ?? false;
    } catch (error, stacktrace) {
      return false;
    }
  }

  @override
  Future<int> getStatus() async {
    try {
      return await interstitialAd.getAdState();
    } catch (error, stacktrace) {
      Log.w("getInterstitialAdStatus error",
          error: error, stackTrace: stacktrace, syncFirebase: true);
      return AdStatus.FAILED;
    }
  }
}
