package com.zxdemo.admob

import android.app.Activity
import android.os.Bundle
import com.facebook.appevents.AppEventsConstants
import com.facebook.appevents.AppEventsLogger
import com.google.android.gms.ads.AdValue
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 com.zxdemo.ZxApplication
import com.zxdemo.http.ZxHttp
import org.json.JSONObject

object ReportAdUtils {
    fun pullStartAd(
        reqId: String,
        className: String,
    ) {
        val obj = JSONObject()
        obj.put("req_id", reqId)
        obj.put("ad_type", reqId)
        obj.put("from", className)
        ZxHttp.getHttpReportInterface("ad_pull_start", "", ext = obj)
    }

    fun pullAd(
        responseInfo: ResponseInfo?,
        adUnit: String,
        error: String? = null,
        reqId: String? = null
    ) {
        val obj = JSONObject()
        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("req_id", reqId)
        obj.put("mediation", "admob")
        if (error == null) {
            obj.put("status", "1")
        } else {
            obj.put("errMsg", error)
            obj.put("status", "2")
        }
        ZxHttp.getHttpReportInterface("ad_pull", "", ext = obj)
    }

    private val taichiPref by lazy {
        ZxApplication.context.getSharedPreferences("TaichiTroasCache", 0)
    }

    private val taichiSharedPreferencesEditor by lazy {
        taichiPref.edit()
    }

    class EventOnPaidEventListener(private val ad: Any?) : OnPaidEventListener {
        override fun onPaidEvent(adValue: AdValue) {
            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")
            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)
            if (currentTaichiTroasCache >= 0.01) {//如果超过0.01就触发一次tROAS taichi事件
                val roasbundle = Bundle()
                roasbundle.putDouble(
                    FirebaseAnalytics.Param.VALUE,
                    currentTaichiTroasCache
                )
                roasbundle.putString(FirebaseAnalytics.Param.CURRENCY, "USD")
                Firebase.analytics.logEvent("Total_Ads_Revenue_001", roasbundle)
                taichiSharedPreferencesEditor.putFloat("TaichiTroasCache", 0f)//重新清零，开始计算

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

            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("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("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 -> {
                    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)
                }
            }
            ZxHttp.getHttpReportInterface("ad_price", "", ext = obj)
        }
    }

    fun clickAd(responseInfo: ResponseInfo?, adUnit: String) {
        val response = responseInfo?.adapterResponses?.getOrNull(0)
        val obj = JSONObject()
        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("networkname", responseInfo?.mediationAdapterClassName)
        obj.put("mediation", "admob")
        if (adUnit != "nativeAd") {
            ZxHttp.getHttpReportInterface("ad_click", "", ext = obj)
        } else {
            ZxHttp.getHttpReportInterface("bigimage_ad_click", "", ext = obj)
        }
    }

    fun showAd(responseInfo: ResponseInfo?, adUnit: String, activity: Activity? = null) {
        val response = responseInfo?.adapterResponses?.getOrNull(0)
        val obj = JSONObject()
        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)
        obj.put("mediation", "admob")
        if (adUnit != "nativeAd") {
            ZxHttp.getHttpReportInterface("ad_show", "", ext = obj)
        } else {
            ZxHttp.getHttpReportInterface("bigimage_ad_show", "", ext = obj)
        }
    }

    fun showErrorAd(reason: String, adUnit: String) {
        val obj = JSONObject()
        obj.put("reason", reason)
        obj.put("ad_unit", adUnit)
        ZxHttp.getHttpReportInterface("ad_show_error", "", ext = obj)
    }

    fun showPrepareAd(adUnit: String) {
        val obj = JSONObject()
        obj.put("ad_unit", adUnit)
        ZxHttp.getHttpReportInterface("ad_prepare_show", "", ext = obj)
    }
}