package com.xm.test.myfilemaster.ad

import android.app.Activity
import android.os.Handler
import android.os.Looper
import android.view.ViewGroup
import com.applovin.mediation.MaxAd
import com.applovin.mediation.MaxAdListener
import com.applovin.mediation.MaxError
import com.applovin.mediation.ads.MaxAppOpenAd
import com.applovin.mediation.ads.MaxInterstitialAd
import com.applovin.mediation.nativeAds.MaxNativeAdListener
import com.applovin.mediation.nativeAds.MaxNativeAdLoader
import com.applovin.mediation.nativeAds.MaxNativeAdView
import com.applovin.sdk.AppLovinSdk
import com.blankj.utilcode.util.ActivityUtils
import com.xm.test.myfilemaster.MyApplication
import com.xm.test.myfilemaster.netSendEvent
import org.json.JSONObject
import java.util.UUID
import java.util.concurrent.TimeUnit
import kotlin.math.pow

object MaxAdUtils {
    private var openAdUnit = "d0d45467dd658a78"
    private var interAdUnit = "98b24342c34a295b"
    private var naviteAdUnit = "be6f5e0e5a22fed4"
    var mOpenAd: MaxAppOpenAd? = null

    private var openLoadTime = Long.MAX_VALUE
    private var interLoadTime = Long.MAX_VALUE
    private var nativeLoadTime = Long.MAX_VALUE


    private fun isOpenAdLoaded() = mOpenAd?.isReady == true
    fun loadOpenAd(skip: Boolean = false, onLoad: (() -> Unit)? = null) {
        if(!AppLovinSdk.getInstance(MyApplication.fContext).isInitialized){
            onLoad?.invoke()
            return
        }
        openAdUnit = ComUtils.getAdUnitCfg().openAd?.unit_id ?: ""
         mOpenAd = MaxAppOpenAd(openAdUnit, MyApplication.fContext)
        if (isOpenAdLoaded() || skip) {
            onLoad?.invoke()
            return
        }

        val reqId = UUID.randomUUID().toString()
        val obj = JSONObject()
        obj.put("req_id", reqId)
        obj.put("ad_type", "openAd")
        netSendEvent("ad_pull_start", ext = obj)
        mOpenAd?.setListener(
            object : MaxAdListener {
                override fun onAdLoaded(p0: MaxAd) {
                    openLoadTime = System.currentTimeMillis()
                    onLoad?.invoke()
                    maxAdPullReport(p0, "openAd", reqId = reqId)
                }

                override fun onAdDisplayed(p0: MaxAd) {}

                override fun onAdHidden(p0: MaxAd) {}

                override fun onAdClicked(p0: MaxAd) {}

                override fun onAdLoadFailed(p0: String, p1: MaxError) {
                    onLoad?.invoke()
                    maxAdPullReport(null, "AppOpenAd", p1.message)
                }

                override fun onAdDisplayFailed(p0: MaxAd, p1: MaxError) {}
            }
        )
        mOpenAd?.loadAd()
    }

    fun showAppOpenAd(
        activity: Activity,
        slotname: String = "",
        skip: Boolean = false,
        onHidden: (() -> Unit)? = null
    ) {
        if (!AdUtils.isShowAd(slotname)) {
            onHidden?.invoke()
            return
        }

        if (!isOpenAdLoaded() || skip || !AppLovinSdk.getInstance(MyApplication.fContext).isInitialized) {
            onHidden?.invoke()
            return
        }
        if (System.currentTimeMillis() - openLoadTime > 1000 * 60 * 60) {
            loadOpenAd()
            onHidden?.invoke()
            return
        }
        mOpenAd?.setListener(object : MaxAdListener {
            override fun onAdLoaded(p0: MaxAd) {

            }

            override fun onAdDisplayed(p0: MaxAd) {
                SaveSoltShowTime(slotname)
                maxAdShowReport(p0, "openAd")
            }

            override fun onAdHidden(p0: MaxAd) {
                onHidden?.invoke()
                loadOpenAd()
            }

            override fun onAdClicked(p0: MaxAd) {
                maxAdclickReport(p0, "openAd")
            }

            override fun onAdLoadFailed(p0: String, p1: MaxError) {

            }

            override fun onAdDisplayFailed(p0: MaxAd, p1: MaxError) {
                onHidden?.invoke()
                loadOpenAd()
                val obj = JSONObject()
                obj.put("reason", p1.message)
                obj.put("ad_unit", "openAd")
                netSendEvent("ad_show_error", ext = obj)
            }

        })
        if (isOpenAdLoaded()) {
            mOpenAd?.showAd("OpenAd")
        } else {
            onHidden?.invoke()
            mOpenAd?.loadAd()
            val obj = JSONObject()
            obj.put("reason", "no_ad")
            obj.put("ad_unit", "openAd")
            netSendEvent("ad_show_error", ext = obj)
        }

    }


    private var interAd: MaxInterstitialAd? = null
    private var retryAttempt = 0
    fun isInterLoaded() = interAd?.isReady == true

    //拉取插屏广告
    fun loadInterstitialAd(activity: Activity, onLoad: (() -> Unit)? = null) {
        if (!AppLovinSdk.getInstance(MyApplication.fContext).isInitialized) {
            onLoad?.invoke()
            return
        }
        interAdUnit = ComUtils.getAdUnitCfg().interAd.unit_id
        if (interAd != null) {
            onLoad?.invoke()
            return
        }
        var hasDone = false
        activity.window.decorView.postDelayed(Runnable {
            if (hasDone) {
                return@Runnable
            }
            hasDone = true
            onLoad?.invoke()
        }, 15000)
        val reqId = UUID.randomUUID().toString()
        val obj = JSONObject()
        obj.put("req_id", reqId)
        obj.put("ad_type", "interAd")
        obj.put("from", activity.javaClass.simpleName)
        netSendEvent("ad_pull_start", ext = obj)

        interAd = MaxInterstitialAd(interAdUnit, activity)
        interAd?.setListener(object : MaxAdListener {
            override fun onAdLoaded(p0: MaxAd) {

                maxAdPullReport(p0, "InterstitialAd")
                retryAttempt = 0
                onLoad?.invoke()
            }

            override fun onAdDisplayed(p0: MaxAd) {

            }

            override fun onAdHidden(p0: MaxAd) {
            }

            override fun onAdClicked(p0: MaxAd) {

            }

            override fun onAdLoadFailed(p0: String, p1: MaxError) {
                maxAdPullReport(null, "InterstitialAd", p1.message)
                onLoad?.invoke()
                retryAttempt++
                Handler(Looper.getMainLooper()).postDelayed({
                    retryAttempt++
                    interAd?.loadAd()
                }, TimeUnit.SECONDS.toMillis(2.0.pow(6.coerceAtMost(retryAttempt)).toLong()))
            }

            override fun onAdDisplayFailed(p0: MaxAd, p1: MaxError) {

            }

        })
        interAd?.loadAd()
    }

    //展示插屏广告
    fun showMaxInterstitialAd(
        activity: Activity,
        soltName: String = "",
        skip: Boolean = false,
        isFirst: Boolean = true,
        onHidden: (() -> Unit)? = null
    ) {

        if (activity.isFinishing || activity.isDestroyed) {
            onHidden?.invoke()
            return
        }
        if (!AdUtils.isShowAd(soltName)) {
            onHidden?.invoke()
            return
        }
        if (skip) {
            onHidden?.invoke()
            return
        }
        if (System.currentTimeMillis() - interLoadTime > 1000 * 60 * 60) {
            loadInterstitialAd(activity)
            onHidden?.invoke()
            return
        }
        if (interAd != null) {
            interAd?.setListener(object : MaxAdListener {
                override fun onAdLoaded(p0: MaxAd) {
                }

                override fun onAdDisplayed(p0: MaxAd) {
                    maxAdShowReport(p0, "interAd", activity)
                    SaveSoltShowTime(soltName)
                }

                override fun onAdHidden(p0: MaxAd) {
                    interAd = null
                    onHidden?.invoke()
                    loadInterstitialAd(activity)
                }

                override fun onAdClicked(p0: MaxAd) {
                    maxAdclickReport(p0, "interAd")
                }

                override fun onAdLoadFailed(p0: String, p1: MaxError) {

                }

                override fun onAdDisplayFailed(p0: MaxAd, p1: MaxError) {
                    interAd = null
                    onHidden?.invoke()
                    loadInterstitialAd(activity)
                    val obj = JSONObject()
                    obj.put("reason", p1.message)
                    obj.put("ad_unit", "interAd")
                    netSendEvent("ad_show_error", ext = obj)
                }

            })
            if (interAd?.isReady == true) {
                interAd?.showAd()
            } else {
                onHidden?.invoke()
                interAd?.loadAd()
            }
            netSendEvent("ad_prepare_show")
        } else {
            onHidden?.invoke()
            loadInterstitialAd(activity) {
                if (isFirst) {
                    netSendEvent("ad_reload_inter")
                    showMaxInterstitialAd(
                        ActivityUtils.getTopActivity(),
                        "interstitial_slot",
                        isFirst = false
                    )
                }
            }
            val obj = JSONObject()
            obj.put("reason", "no_ad")
            obj.put("ad_unit", "interAd")
            netSendEvent("ad_show_error", ext = obj)
        }
    }

    var nativeAdLoader: MaxNativeAdLoader? = null
    private var nativeAd: MaxAd? = null

    private var nativeData: Pair<MaxNativeAdView?, MaxAd?>? = null

    private var loadingListener: (() -> Unit)? = null
    private var isLoading = false

    //拉取原生广告
    fun loadMaxNativeAd() {
        naviteAdUnit = ComUtils.getAdUnitCfg().native.unit_id
        nativeAdLoader = MaxNativeAdLoader(naviteAdUnit, MyApplication.fContext)
        if (!AppLovinSdk.getInstance(MyApplication.fContext).isInitialized) {
            return
        }
        if (nativeAd != null) {
            return
        }
        if (nativeData != null) {
            return
        }

        if (isLoading) {
            return
        }
        isLoading = true
        val reqId = UUID.randomUUID().toString()
        val obj = JSONObject()
        obj.put("req_id", reqId)
        obj.put("ad_type", "nativeAd")
        netSendEvent("ad_pull_start", ext = obj)
        nativeAdLoader?.setNativeAdListener(object : MaxNativeAdListener() {
            override fun onNativeAdLoaded(maxNativeAdView: MaxNativeAdView?, maxAd: MaxAd) {
                nativeData = Pair(maxNativeAdView, maxAd)
                nativeAd = nativeData?.second
                maxAdPullReport(maxAd, "NativeAd")
                isLoading = false
                loadingListener?.invoke()
            }

            override fun onNativeAdLoadFailed(p0: String, p1: MaxError) {
                maxAdPullReport(null, "NativeAd", p1.message)
                isLoading = false
            }
        })
        nativeAdLoader?.loadAd()
    }

    //展示原生广告
    fun showMaxNativeAd(activity: Activity?, parent: ViewGroup, slotname: String = "") {
        if (!AppLovinSdk.getInstance(MyApplication.fContext).isInitialized) {
            return
        }
        if (!AdUtils.isShowAd(slotname)) {
            return
        }
        loadingListener = {
            nativeAd?.let {
                nativeAdLoader?.destroy(it)
            }
            if ((System.currentTimeMillis() - nativeLoadTime <= 1000 * 60 * 60) && nativeData?.first != null) {
                parent.removeAllViews()
                parent.addView(nativeData?.first)
                maxAdShowReport(nativeData?.second, "NativeAd")
                SaveSoltShowTime(slotname)
            }
            nativeData = null
            loadingListener = null
            loadMaxNativeAd()
        }
        if (nativeAd == null) {
            loadMaxNativeAd()
            val obj = JSONObject()
            obj.put("reason", "no_ad")
            obj.put("ad_unit", "nativeAd")
            netSendEvent("ad_show_error", ext = obj)
        } else {
            loadingListener?.invoke()
        }
    }

    //广告拉取上报
    private fun maxAdPullReport(
        ad: MaxAd?,
        adUnit: String,
        error: String? = null,
        reqId: String? = null
    ) {
        val obj = JSONObject()
        obj.put("UnitId", ad?.adUnitId)
        obj.put("ad_unit", adUnit)
        obj.put(
            "creativeId",
            ad?.creativeId
        )
        obj.put("req_id", reqId)
        obj.put("status", if (ad == null) "0" else "1")
        obj.put("networkname", ad?.networkName)
        obj.put("placement", ad?.placement)
        obj.put("networkplacement", ad?.networkPlacement)
        obj.put("requestLatencyMillis", ad?.requestLatencyMillis)
        obj.put("valueMicros", ad?.revenue?.times(1000000))
        if (error == null) {
            obj.put("status", "1")
        } else {
            obj.put("errMsg", error)
            obj.put("status", "2")
        }
        netSendEvent("ad_pull", ext = obj)
    }

    //广告展示上报
    private fun maxAdShowReport(ad: MaxAd?, adUnit: String, activity: Activity? = null) {
        val obj = JSONObject()
        obj.put("UnitId", ad?.adUnitId)
        obj.put("ad_unit", adUnit)
        obj.put(
            "creativeId",
            ad?.creativeId
        )
        obj.put("networkname", ad?.networkName)
        obj.put("placement", ad?.placement)
        obj.put("networkplacement", ad?.networkPlacement)
        obj.put("requestLatencyMillis", ad?.requestLatencyMillis)
        obj.put("valueMicros", ad?.revenue?.times(1000000))
//        ad?.revenue?.let {
//            Firebase.analytics.logEvent("ad_price", Bundle().apply {
//                putDouble("valueMicros", it * 1000000)
//            })
//        }
        netSendEvent("ad_show", ext = obj)
    }

    //广告点击上报
    private fun maxAdclickReport(ad: MaxAd?, adUnit: String) {
        val obj = JSONObject()
        obj.put("UnitId", ad?.adUnitId)
        obj.put("ad_unit", adUnit)
        obj.put(
            "creativeId",
            ad?.creativeId
        )
        obj.put("networkname", ad?.networkName)
        obj.put("placement", ad?.placement)
        obj.put("networkplacement", ad?.networkPlacement)
        obj.put("requestLatencyMillis", ad?.requestLatencyMillis)
        obj.put("valueMicros", ad?.revenue?.times(1000000))
        netSendEvent("ad_click", ext = obj)
    }

    fun SaveSoltShowTime(key: String) {
//        val nums=SPUtils.getInstance().getInt("${key}_ad_show_num", 0)
//        SPUtils.getInstance().put("${key}_ad_show_num",  nums+1)

        MyApplication.fContext.saveDataStoreBlock(getLongString(key), System.currentTimeMillis())
        val adNum =
            MyApplication.fContext.queryDataStoreBlock(getIntString("${key}_ad_show_num"), 0)
        MyApplication.fContext.saveDataStoreBlock(getIntString("${key}_ad_show_num"), adNum + 1)
    }

}