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/rewarded_video_ad.dart';
import 'package:guru_utils/ads/ads.dart';

/// Created by Haoyi on 5/26/21

class ApplovinRewardedAds extends RewardedAds<RewardedVideoAdEvent> {
  late RewardedVideoAd rewardedVideoAd;

  @override
  final AdUnitId adUnitId;
  final AdSlotId? adAmazonSlotId;

  ApplovinRewardedAds.create(this.adUnitId, {this.adAmazonSlotId});

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

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

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

  @override
  Future<bool> requestDispose() async {
    try {
      return await rewardedVideoAd.dispose() ?? false;
    } catch (error, stacktrace) {
      Log.w("requestDispose error! $error  $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 rewardedVideoAd.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> requestReset() async {
    try {
      Log.w("[$runtimeType] requestLoad", tag: "Ads");
      final result = await rewardedVideoAd.dispose() ?? false;
      if (result) {
        rewardedVideoAd = RewardedVideoAd(adUnitId: adUnitId.id, listener: dispatchEvent);
        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();
    // if (now - latestHiddenAt < 60000) {
    //   Log.i("show ads too frequency");
    //   return false;
    // }
    // Log.i("show interstitial");
    try {
      Log.d("[$hashCode]requestShow rewardedAds", syncFirebase: true);
      final result = await rewardedVideoAd.show(placement: scene) ?? false;
      if (result) {
        return AdCause.success;
      } else {
        return AdCause.requestFailed;
      }
    } catch (error, stacktrace) {
      Log.w("requestShow rewarded error", error: error, stackTrace: stacktrace, syncFirebase: true);
      return AdCause.internalError;
    }
  }

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

  @override
  bool needReset() {
    Log.d("reset check elapsedTimeInMillisSinceStartLoadAds $elapsedTimeInMillisSinceStartLoadAds",
        tag: "Ads");
    return elapsedTimeInMillisSinceStartLoadAds > 30 * 1000;
  }
}
