package com.dumpster.cleaner.business.ads.admob

import android.app.Activity
import android.content.Context
import com.dumpster.cleaner.GlobalConfig
import com.dumpster.cleaner.MyApplication
import com.dumpster.cleaner.business.ads.AdEvent
import com.dumpster.cleaner.business.ads.AdState
import com.dumpster.cleaner.business.ads.AdsShowCallBack
import com.dumpster.cleaner.business.ads.AdsType
import com.dumpster.cleaner.business.ads.AdsType.Companion.INSERT
import com.dumpster.cleaner.business.ads.LimitUtils
import com.dumpster.cleaner.business.ads.admob.AdmobEvent.AdmobOnPaidEventListener
import com.dumpster.cleaner.utils.LogEx
import com.google.android.gms.ads.AdError
import com.google.android.gms.ads.AdRequest
import com.google.android.gms.ads.FullScreenContentCallback
import com.google.android.gms.ads.LoadAdError
import com.google.android.gms.ads.appopen.AppOpenAd

/**
 * 开屏广告加载显示管理类
 */
class AdOpenMgr {

    private val TAG = "AdOpenMgr"
    private val adState = AdState<AppOpenAd>()
    private var showCallBack: AdsShowCallBack? = null

    //正在加载回调
    private var loadingCallBack: ((flag: Boolean) -> Unit)? = null

    fun show(
        activity: Activity,
        adEvent: AdEvent,
        showCallBack: AdsShowCallBack?
    ) {
        if (activity.isFinishing || activity.isDestroyed) {
            return
        }

        adState.currentAdEvent?.let { adEvent.reqId = it.reqId }

        if (!adEvent.isUnLimit) {
            if (!LimitUtils.isAdShow(AdsType.OPEN, adEvent)) {
                showCallBack?.failed()
                return
            }
            if (LimitUtils.isIntervalOpenLimit(adEvent)) {
                showCallBack?.failed()
                return
            }
        }

        val needLoad = !adState.adAvailable()
        this.showCallBack = showCallBack

        adEvent.adPrepareShow()
        if (needLoad) {
            if (!adState.loadingAd) {
                LogEx.logDebug(adEvent.TAG, "open adState !loadingAd")
                loadAd(activity, adEvent) {
                    if (it) {
                        showReadyAd(activity, adEvent)
                    } else {
                        showCallBack?.adFailed()
                    }
                }
            } else {
                LogEx.logDebug(adEvent.TAG, "open adState is loadingAd")
                loadingCallBack = {
                    if (it) {
                        showReadyAd(activity, adEvent)
                    } else {
                        showCallBack?.adFailed()
                    }
                }
            }
        } else {
            LogEx.logDebug(adEvent.TAG, "open ad ready")
            showReadyAd(activity, adEvent)
        }
    }

    private fun showReadyAd(ac: Activity, adEvent: AdEvent) {

        val admobEvent = (adEvent as AdmobEvent)

        if (ac.isFinishing || ac.isDestroyed || adState.currentAd == null) {
            LogEx.logDebug(TAG, "showReadyAd ac=null isFinishing isDestroyed")
            return
        }

        adState.currentAd?.run {


            fullScreenContentCallback = object : FullScreenContentCallback() {
                override fun onAdShowedFullScreenContent() {

                    admobEvent.showAd(this@run.responseInfo, ac)

                    showCallBack?.show()

                    adState.onAdDisplayed(INSERT)
                    //计数
                    LimitUtils.addDisplayNum()

                }

                override fun onAdFailedToShowFullScreenContent(adError: AdError) {
                    super.onAdFailedToShowFullScreenContent(adError)

                    showCallBack?.adFailed()
                    showCallBack = null
                    adState.onAdDisplayFailed()

                    admobEvent.adShowError(adError)

                }

                override fun onAdDismissedFullScreenContent() {
                    super.onAdDismissedFullScreenContent()

                    showCallBack?.close()
                    showCallBack = null

                    adState.onAdHidden(INSERT)

                    //预加载,“Timeout for show call succeed.”预加载的广告大概率,
                    loadAd(MyApplication.appContext, AdmobEvent("openAd", "preload"))
                }

                override fun onAdClicked() {
                    admobEvent.clickAd(this@run.responseInfo)
                    //计数
                    LimitUtils.addClickNum()
                }
            }
            show(ac)
        }
    }

    fun loadAd(
        context: Context,
        adEvent: AdEvent,
        loadCallBack: ((flag: Boolean) -> Unit)? = null
    ) {

        if (!adEvent.isUnLimit) {
            if (!LimitUtils.isAdShow(AdsType.OPEN, adEvent)) {
                this.showCallBack?.failed()
                this.showCallBack = null
                adState.onAdLoadFailed()
                return
            }
        }

        //避免无效预加载
        if (adState.loadingAd) {
            return
        }

        adEvent.adPulStart()
        adState.loadStart(adEvent)

        AppOpenAd.load(
            context,
            GlobalConfig.ID_ADMOB_OPEN,
            AdRequest.Builder().build(),
            object : AppOpenAd.AppOpenAdLoadCallback() {
                override fun onAdLoaded(appOpenAd: AppOpenAd) {
                    LogEx.logDebug(adEvent.TAG, "open onAdLoaded loadAd")

                    appOpenAd.onPaidEventListener = AdmobOnPaidEventListener(appOpenAd, adEvent.scope)
                    adState.onAdLoaded(appOpenAd)

                    loadCallBack?.invoke(true)
                    loadingCallBack?.invoke(true)
                    loadingCallBack = null

                    LimitUtils.addRequestNum()
                    (adEvent as AdmobEvent).pullAd(appOpenAd.responseInfo)
                }

                override fun onAdFailedToLoad(loadAdError: LoadAdError) {
                    LogEx.logDebug(adEvent.TAG, "open onAdFailedToLoad loadAd")
                    adState.onAdLoadFailed()

                    loadCallBack?.invoke(false)
                    loadingCallBack?.invoke(false)
                    loadingCallBack = null

                    (adEvent as AdmobEvent).pullAd(loadAdError.responseInfo, loadAdError)
                }
            }
        )
    }

}