package com.base.filerecoveryrecyclebin.ads.admob

import android.app.Activity
import com.base.filerecoveryrecyclebin.GlobalConfig
import com.base.filerecoveryrecyclebin.activity.splash.Splash2Activity
import com.base.filerecoveryrecyclebin.ads.AdDisplayUtils
import com.base.filerecoveryrecyclebin.ads.CountdownDialog.startCountdownAndShowAd
import com.base.filerecoveryrecyclebin.ads.admob.AdmobEvent.clickAd
import com.base.filerecoveryrecyclebin.ads.admob.AdmobEvent.pullAd
import com.base.filerecoveryrecyclebin.ads.admob.AdmobEvent.showAd
import com.base.filerecoveryrecyclebin.help.BaseApplication
import com.base.filerecoveryrecyclebin.utils.EventUtils
import com.base.filerecoveryrecyclebin.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
import org.json.JSONObject
import java.util.UUID

object AdmobOpenUtils {

    private val TAG = "AdmobOpenUtils"
    private val mRequest = AdRequest.Builder().build()
    private var openLoadTime = Long.MAX_VALUE
    private var mOpenAd: AppOpenAd? = null
    fun isOpenAdLoaded() = mOpenAd != null

    fun loadAppOpenAd(skip: Boolean = false, onLoad: ((where: Int) -> Unit)? = null) {

        if (mOpenAd != null || skip) {
            onLoad?.invoke(1)
            return
        }
        if (!AdDisplayUtils.getInstance().shouldShowAd("openAd")) {
            onLoad?.invoke(2)
            return
        }
        val reqId = UUID.randomUUID().toString()
        val obj = JSONObject()
        obj.put("req_id", reqId)
        obj.put("ad_type", "openAd")
        EventUtils.event("ad_pull_start", ext = obj)
        AppOpenAd.load(
            BaseApplication.context,
            GlobalConfig.ID_ADMOB_OPEN,
            mRequest,
            object : AppOpenAd.AppOpenAdLoadCallback() {
                override fun onAdLoaded(ad: AppOpenAd) {
                    LogEx.logDebug(TAG, "onAdLoaded")
                    openLoadTime = System.currentTimeMillis()
                    mOpenAd = ad
                    onLoad?.invoke(3)
                    pullAd(ad.responseInfo, "openAd", reqId = reqId)
                    ad.onPaidEventListener = AdmobEvent.EventOnPaidEventListener(ad)
                }

                override fun onAdFailedToLoad(p0: LoadAdError) {
                    LogEx.logDebug(TAG, "LoadAdError ${p0.message}")
                    mOpenAd = null
                    onLoad?.invoke(4)
                    pullAd(p0.responseInfo, "openAd", p0.message, reqId = reqId)
                }
            })
    }


    fun showAppOpenAd(
        activity: Activity,
        isRetry: Boolean = false,
        showBefore: ((flag: Boolean) -> Unit)? = null,
        onHidden: ((where: Int) -> Unit)? = null
    ) {

        if (activity.isFinishing || activity.isDestroyed) {
            return
        }
        if (!AdDisplayUtils.getInstance().shouldShowAd("openAd")) {
            onHidden?.invoke(1)
            return
        }
        if (System.currentTimeMillis() - openLoadTime > 1000 * 60 * 60) {
            LogEx.logDebug(TAG, "openLoadTime out time")
            mOpenAd = null
            loadAppOpenAd()
            onHidden?.invoke(2)
            val obj2 = JSONObject()
            obj2.put("ad_unit", "openAd")
            EventUtils.event("ad_expire", ext = obj2)
            return
        }
        if (!isRetry) {
            val obj1 = JSONObject()
            obj1.put("ad_unit", "openAd")
            EventUtils.event("ad_prepare_show", ext = obj1)
        }

        if (mOpenAd != null) {
            LogEx.logDebug(TAG, "mOpenAd!=null")
            showBefore?.invoke(true)
            if (Splash2Activity.isSplashHot) {
                startCountdownAndShowAd {
                    showReadyAd(activity, showBefore, onHidden)
                }
            } else {
                showReadyAd(activity, showBefore, onHidden)
            }
        } else {
            LogEx.logDebug(TAG, "mOpenAd=null")
            loadAppOpenAd {
                if (mOpenAd != null) {
                    showBefore?.invoke(true)
                    if (Splash2Activity.isSplashHot) {
                        startCountdownAndShowAd {
                            showReadyAd(activity, showBefore, onHidden)
                        }
                    } else {
                        showReadyAd(activity, showBefore, onHidden)
                    }
                } else {
                    val obj = JSONObject()
                    obj.put("reason", "no_ad")
                    obj.put("ad_unit", "openAd")
                    EventUtils.event("ad_show_error", ext = obj)
                    onHidden?.invoke(5)
                }
            }
        }
    }


    private fun showReadyAd(
        activity: Activity,
        showBefore: ((flag: Boolean) -> Unit)? = null,
        onHidden: ((where: Int) -> Unit)?
    ) {
        val thisMOpenAd = mOpenAd
        mOpenAd = null
        thisMOpenAd?.fullScreenContentCallback = object : FullScreenContentCallback() {
            override fun onAdClicked() {
                clickAd(thisMOpenAd?.responseInfo, "openAd")
            }

            override fun onAdDismissedFullScreenContent() {
                mOpenAd = null
                onHidden?.invoke(3)
                loadAppOpenAd()
            }

            override fun onAdFailedToShowFullScreenContent(p0: AdError) {
                mOpenAd = null
                onHidden?.invoke(4)
                loadAppOpenAd()
                val obj = JSONObject()
                obj.put("reason", p0.message)
                obj.put("ad_unit", "openAd")
                EventUtils.event("ad_show_error", ext = obj)
            }

            override fun onAdShowedFullScreenContent() {
                showBefore?.invoke(true)
                showAd(thisMOpenAd?.responseInfo, "openAd", activity)
            }
        }
        thisMOpenAd?.show(activity)
    }
}