package com.base.scanqrclear.ads.admob

import android.app.Activity
import android.os.Bundle
import com.base.scanqrclear.MyApplication
import com.base.scanqrclear.ads.AdEvent
import com.base.scanqrclear.ads.taichiPref
import com.base.scanqrclear.ads.taichiSharedPreferencesEditor
import com.base.scanqrclear.bean.config.AdConfigBean
import com.base.scanqrclear.helper.EventUtils
import com.base.scanqrclear.utils.LogEx
import com.facebook.appevents.AppEventsConstants
import com.facebook.appevents.AppEventsLogger
import com.google.android.gms.ads.AdError
import com.google.android.gms.ads.AdValue
import com.google.android.gms.ads.AdView
import com.google.android.gms.ads.LoadAdError
import com.google.android.gms.ads.OnPaidEventListener
import com.google.android.gms.ads.ResponseInfo
import com.google.android.gms.ads.appopen.AppOpenAd
import com.google.android.gms.ads.interstitial.InterstitialAd
import com.google.android.gms.ads.nativead.NativeAd
import com.google.android.gms.ads.rewarded.RewardedAd
import com.google.firebase.analytics.FirebaseAnalytics
import com.google.firebase.analytics.ktx.analytics
import com.google.firebase.ktx.Firebase
import org.json.JSONObject
import kotlin.random.Random


class AdmobEvent : AdEvent {

    override val TAG: String = "AdmobEvent"

    constructor(adUnit: String, from: String) : super() {
        this.adUnit = adUnit
        this.from = from
    }


    fun pullAd(
        responseInfo: ResponseInfo?,
        error: LoadAdError? = null,
    ) {
        val obj = JSONObject()
        obj.put("req_id", reqId)
        if (responseInfo != null) {
            val response = responseInfo.adapterResponses.getOrNull(0)
            if (response != null) {
                obj.put("source", response.adSourceName)

                val credentials = mapOf(
                    "placementid" to response.credentials.get("placementid"),
                    "appid" to response.credentials.get("appid"),
                    "pubid" to response.credentials.get("pubid")
                )
                obj.put("credentials", credentials.toString())
            }
            obj.put("session_id", responseInfo.responseId)
        }
        obj.put("networkname", responseInfo?.mediationAdapterClassName)
        obj.put("ad_unit", adUnit)
        obj.put("from", from)
        if (error == null) {
            obj.put("status", "1")
        } else {
            obj.put("errMsg", error.toString())
            obj.put("status", "2")
        }
        EventUtils.event("ad_pull", ext = obj)
        LogEx.logDebug(TAG, "ad_pull obj=$obj")
    }


    fun clickAd(responseInfo: ResponseInfo?) {

        val response = responseInfo?.adapterResponses?.getOrNull(0)
        val obj = JSONObject()
        obj.put("req_id", reqId)
        obj.put("source", response?.adSourceName)
        obj.put("ad_unit", adUnit)

        val credentials = mapOf(
            "placementid" to response?.credentials?.get("placementid"),
            "appid" to response?.credentials?.get("appid"),
            "pubid" to response?.credentials?.get("pubid")
        )
        obj.put("credentials", credentials.toString())
        obj.put("session_id", responseInfo?.responseId)
        obj.put("from", from)
        obj.put("networkname", responseInfo?.mediationAdapterClassName)
        if (adUnit != "nativeAd") {
            EventUtils.event("ad_click", ext = obj)
        } else {
            EventUtils.event("ad_click", ext = obj)
        }
    }

    fun showAd(responseInfo: ResponseInfo?, activity: Activity? = null) {
        val response = responseInfo?.adapterResponses?.getOrNull(0)
        val obj = JSONObject()
        obj.put("req_id", reqId)
        obj.put("source", response?.adSourceName)
        obj.put("ad_unit", adUnit)
        obj.put("networkname", responseInfo?.mediationAdapterClassName)
        val credentials = mapOf(
            "placementid" to response?.credentials?.get("placementid"),
            "appid" to response?.credentials?.get("appid"),
            "pubid" to response?.credentials?.get("pubid")
        )
        obj.put("credentials", credentials.toString())
        obj.put("session_id", responseInfo?.responseId)
        obj.put("from", activity?.javaClass?.simpleName)
        if (adUnit != "nativeAd") {
            EventUtils.event("ad_show", ext = obj)
        } else {
            EventUtils.event("ad_show", ext = obj)
        }
        LogEx.logDebug(TAG, "ad_show $obj")
    }

    class EventOnPaidEventListener(private val ad: Any?) : OnPaidEventListener {
        override fun onPaidEvent(adValue: AdValue) {

            val adRatio = AdConfigBean.adsConfigBean.adRatio
            val random = Random.Default.nextInt(1, 100)
            if (random > adRatio) {
                taichiSharedPreferencesEditor.putFloat("TaichiTroasCache", 0f)
                taichiSharedPreferencesEditor.commit()
                EventUtils.event("ad_price_limit")
                return
            }

            val valueMicros = adValue.valueMicros
            val currencyCode = adValue.currencyCode
            val precision = adValue.precisionType

            val obj = JSONObject()
            obj.put("valueMicros", valueMicros)
            obj.put("currencyCode", currencyCode)
            obj.put("precision", precision)

            Firebase.analytics.logEvent("ad_price", Bundle().apply {
                putDouble("valueMicros", valueMicros / 1000000.0)
            })

            val params = Bundle()
            val currentImpressionRevenue = adValue.valueMicros.toDouble() / 1000000.0
            params.putDouble(FirebaseAnalytics.Param.VALUE, currentImpressionRevenue)
            params.putString(FirebaseAnalytics.Param.CURRENCY, "USD")
            LogEx.logDebug("EventOnPaidEventListener", "precisionType=${adValue.precisionType}")
            val precisionType = when (adValue.precisionType) {
                0 -> "UNKNOWN"
                1 -> "ESTIMATED"
                2 -> "PUBLISHER_PROVIDED"
                3 -> "PRECISE"
                else -> "Invalid"
            }
            params.putString("precisionType", precisionType)
            Firebase.analytics.logEvent("Ad_Impression_Revenue", params)
            val previousTaichiTroasCache = taichiPref.getFloat("TaichiTroasCache", 0f)

            val currentTaichiTroasCache = (previousTaichiTroasCache +
                    currentImpressionRevenue).toFloat()

            val taichiAdValue = AdConfigBean.adsConfigBean.taichiAdValue / 100f
            if (currentTaichiTroasCache >= taichiAdValue) {//如果超过0.01就触发一次tROAS taichi事件
                val roasbundle = Bundle()
                roasbundle.putDouble(
                    FirebaseAnalytics.Param.VALUE,
                    currentTaichiTroasCache.toDouble()
                )
                roasbundle.putString(FirebaseAnalytics.Param.CURRENCY, "USD")
                Firebase.analytics.logEvent("Total_Ads_Revenue_001", roasbundle)
                taichiSharedPreferencesEditor.putFloat("TaichiTroasCache", 0f)//重新清零，开始计算

                val logger = AppEventsLogger.newLogger(MyApplication.appContext)
                val parameters = Bundle()
                parameters.putString(AppEventsConstants.EVENT_PARAM_CURRENCY, "USD")
                logger.logEvent("ad_value", currentTaichiTroasCache.toDouble(), parameters)
            } else {
                taichiSharedPreferencesEditor.putFloat("TaichiTroasCache", currentTaichiTroasCache)
            }
            taichiSharedPreferencesEditor.commit()

            var key = "ad_price"
            when (ad) {
                is AppOpenAd -> {
                    val adUnitId = ad.adUnitId
                    val loadedAdapterResponseInfo = ad.responseInfo.loadedAdapterResponseInfo
                    val adSourceName = loadedAdapterResponseInfo?.adSourceName
                    val adSourceId = loadedAdapterResponseInfo?.adSourceId
                    val adSourceInstanceName = loadedAdapterResponseInfo?.adSourceInstanceName
                    val adSourceInstanceId = loadedAdapterResponseInfo?.adSourceInstanceId
                    val sessionId = ad.responseInfo.responseId
                    val extras = ad.responseInfo.responseExtras
                    val mediationGroupName = extras.getString("mediation_group_name")
                    val mediationABTestName = extras.getString("mediation_ab_test_name")
                    val mediationABTestVariant = extras.getString("mediation_ab_test_variant")
                    obj.put("ad_unit", "openAd")
                    obj.put("adUnitId", adUnitId)
                    obj.put("adSourceName", adSourceName)
                    obj.put("adSourceId", adSourceId)
                    obj.put("adSourceInstanceName", adSourceInstanceName)
                    obj.put("adSourceInstanceId", adSourceInstanceId)
                    obj.put("mediationGroupName", mediationGroupName)
                    obj.put("mediationABTestName", mediationABTestName)
                    obj.put("mediationABTestVariant", mediationABTestVariant)
                    obj.put("session_id", sessionId)
                }

                is InterstitialAd -> {
                    val adUnitId = ad.adUnitId
                    val loadedAdapterResponseInfo = ad.responseInfo.loadedAdapterResponseInfo
                    val adSourceName = loadedAdapterResponseInfo?.adSourceName
                    val adSourceId = loadedAdapterResponseInfo?.adSourceId
                    val adSourceInstanceName = loadedAdapterResponseInfo?.adSourceInstanceName
                    val adSourceInstanceId = loadedAdapterResponseInfo?.adSourceInstanceId
                    val sessionId = ad.responseInfo.responseId
                    val extras = ad.responseInfo.responseExtras
                    val mediationGroupName = extras.getString("mediation_group_name")
                    val mediationABTestName = extras.getString("mediation_ab_test_name")
                    val mediationABTestVariant = extras.getString("mediation_ab_test_variant")
                    obj.put("ad_unit", "interAd")
                    obj.put("adUnitId", adUnitId)
                    obj.put("adSourceName", adSourceName)
                    obj.put("adSourceId", adSourceId)
                    obj.put("adSourceInstanceName", adSourceInstanceName)
                    obj.put("adSourceInstanceId", adSourceInstanceId)
                    obj.put("mediationGroupName", mediationGroupName)
                    obj.put("mediationABTestName", mediationABTestName)
                    obj.put("mediationABTestVariant", mediationABTestVariant)
                    obj.put("session_id", sessionId)
                }

                is RewardedAd -> {
                    val loadedAdapterResponseInfo = ad.responseInfo.loadedAdapterResponseInfo
                    val adSourceName = loadedAdapterResponseInfo?.adSourceName
                    val adSourceId = loadedAdapterResponseInfo?.adSourceId
                    val adSourceInstanceName = loadedAdapterResponseInfo?.adSourceInstanceName
                    val adSourceInstanceId = loadedAdapterResponseInfo?.adSourceInstanceId
                    val sessionId = ad.responseInfo.responseId
                    val extras = ad.responseInfo.responseExtras
                    val mediationGroupName = extras.getString("mediation_group_name")
                    val mediationABTestName = extras.getString("mediation_ab_test_name")
                    val mediationABTestVariant = extras.getString("mediation_ab_test_variant")
                    obj.put("adSourceName", adSourceName)
                    obj.put("adSourceId", adSourceId)
                    obj.put("adSourceInstanceName", adSourceInstanceName)
                    obj.put("adSourceInstanceId", adSourceInstanceId)
                    obj.put("mediationGroupName", mediationGroupName)
                    obj.put("mediationABTestName", mediationABTestName)
                    obj.put("mediationABTestVariant", mediationABTestVariant)
                    obj.put("session_id", sessionId)
                }

                is NativeAd -> {
                    key = "ad_price"
                    val loadedAdapterResponseInfo = ad.responseInfo?.loadedAdapterResponseInfo
                    val adSourceName = loadedAdapterResponseInfo?.adSourceName
                    val adSourceId = loadedAdapterResponseInfo?.adSourceId
                    val adSourceInstanceName = loadedAdapterResponseInfo?.adSourceInstanceName
                    val adSourceInstanceId = loadedAdapterResponseInfo?.adSourceInstanceId
                    val sessionId = ad.responseInfo?.responseId
                    val extras = ad.responseInfo?.responseExtras
                    val mediationGroupName = extras?.getString("mediation_group_name")
                    val mediationABTestName = extras?.getString("mediation_ab_test_name")
                    val mediationABTestVariant = extras?.getString("mediation_ab_test_variant")
                    obj.put("ad_unit", "nativeAd")
                    obj.put("adSourceName", adSourceName)
                    obj.put("adSourceId", adSourceId)
                    obj.put("adSourceInstanceName", adSourceInstanceName)
                    obj.put("adSourceInstanceId", adSourceInstanceId)
                    obj.put("mediationGroupName", mediationGroupName)
                    obj.put("mediationABTestName", mediationABTestName)
                    obj.put("mediationABTestVariant", mediationABTestVariant)
                    obj.put("session_id", sessionId)
                }

                else -> {
                    runCatching {
                        val adView = ad as AdView
                        val adUnitId = adView.adUnitId
                        val loadedAdapterResponseInfo = adView.responseInfo?.loadedAdapterResponseInfo
                        val adSourceName = loadedAdapterResponseInfo?.adSourceName
                        val adSourceId = loadedAdapterResponseInfo?.adSourceId
                        val adSourceInstanceName = loadedAdapterResponseInfo?.adSourceInstanceName
                        val adSourceInstanceId = loadedAdapterResponseInfo?.adSourceInstanceId
                        val sessionId = adView.responseInfo?.responseId
                        val extras = adView.responseInfo?.responseExtras
                        val mediationGroupName = extras?.getString("mediation_group_name")
                        val mediationABTestName = extras?.getString("mediation_ab_test_name")
                        val mediationABTestVariant = extras?.getString("mediation_ab_test_variant")
                        obj.put("ad_unit", "banner")
                        obj.put("adUnitId", adUnitId)
                        obj.put("adSourceName", adSourceName)
                        obj.put("adSourceId", adSourceId)
                        obj.put("adSourceInstanceName", adSourceInstanceName)
                        obj.put("adSourceInstanceId", adSourceInstanceId)
                        obj.put("mediationGroupName", mediationGroupName)
                        obj.put("mediationABTestName", mediationABTestName)
                        obj.put("mediationABTestVariant", mediationABTestVariant)
                        obj.put("session_id", sessionId)
                    }
                }
            }
            EventUtils.event(key, ext = obj)
        }
    }

    fun adShowError(adError: AdError) {
        val obj = JSONObject()
        obj.put("req_id", reqId)
        obj.put("reason", adError.message)
        obj.put("code", adError.code)
        obj.put("from", from)
        obj.put("ad_unit", "openAd")
        EventUtils.event("ad_show_error", ext = obj)
        LogEx.logDebug(TAG, "ad_show_error $obj")
    }
}


