package com.base.locationsharewhite.ads.admob

import android.content.Context
import android.view.ViewGroup
import androidx.core.view.isVisible
import com.base.locationsharewhite.ads.AdsType
import com.base.locationsharewhite.helper.EventUtils
import com.base.locationsharewhite.helper.config.ConstConfig
import com.google.android.gms.ads.AdListener
import com.google.android.gms.ads.AdLoader
import com.google.android.gms.ads.AdRequest
import com.google.android.gms.ads.LoadAdError
import com.google.android.gms.ads.nativead.NativeAd
import com.google.android.gms.ads.nativead.NativeAdOptions
import org.json.JSONObject
import java.util.UUID
import java.util.concurrent.ConcurrentLinkedDeque

/**
 *原生广告加载显示管理类
 */
class AdNativeMgr {

    /**
     * 上一次的缓存成功时间
     */
    protected var lastTime: Long = 0

    /**
     * 原生广告缓存队列
     */
    private val cacheItems = ConcurrentLinkedDeque<NativeAd>()

    fun loadAd(context: Context, parent: ViewGroup? = null, layout: Int? = null) {
        if (LimitUtils.isAdShow(AdsType.NATIVE)) return

        val reqId = UUID.randomUUID().toString()
        val obj = JSONObject()
        obj.put("req_id", reqId)
        obj.put("ad_type", "nativeAd")
        val adLoader = AdLoader.Builder(
            context,
            ConstConfig.nativeAdId
        )
            .forNativeAd { nativeAd ->
                cacheItems.offer(nativeAd)
                lastTime = System.currentTimeMillis()
                nativeAd.setOnPaidEventListener(AdmobEvent.EventOnPaidEventListener(nativeAd))
                AdmobEvent.pullAd(nativeAd.responseInfo, "nativeAd", reqId = reqId)
                if (parent != null && layout != null) show(parent, layout)

            }
            .withAdListener(object : AdListener() {
                override fun onAdFailedToLoad(error: LoadAdError) {
                    AdmobEvent.pullAd(error.responseInfo, "nativeAd", error.message, reqId = reqId)
                }

                override fun onAdClicked() {
                    super.onAdClicked()
                    AdmobEvent.clickAd(cacheItems.lastOrNull()?.responseInfo, "nativeAd")
                }

                override fun onAdClosed() {
                    super.onAdClosed()
                }
            })
            .withNativeAdOptions(
                NativeAdOptions.Builder()
//                    .setAdChoicesPlacement(NativeAdOptions.ADCHOICES_TOP_RIGHT)
//                    .setMediaAspectRatio(NativeAdOptions.NATIVE_MEDIA_ASPECT_RATIO_SQUARE)
                    .build()
            )
            .build()
        // Load AdMob native advanced ads
        adLoader.loadAds(AdRequest.Builder().build(), 1)
    }

    fun show(parent: ViewGroup, layout: Int) {
        if (!LimitUtils.isAdShow(AdsType.NATIVE)) {
            cacheItems.clear()
            return
        }
        val nativeAd = cacheItems.peek()
        if ((nativeAd == null).also {
                if (it) {
                    val obj2 = JSONObject()
                    obj2.put("reason", "no_ad")
                    obj2.put("ad_unit", "nativeAd")
                    EventUtils.event("ad_show_error", ext = obj2)
                }
            } || (!adAvailable()).also {
                if (it) {
                    val obj2 = JSONObject()
                    obj2.put("ad_unit", "nativeAd")
                    EventUtils.event("ad_expire", ext = obj2)
                }
            }) {
            //缓存过期了就清空
            cacheItems.clear()
            loadAd(parent.context.applicationContext, parent, layout)
            return
        }
        val obj = JSONObject()
        obj.put("ad_unit", "nativeAd")
        EventUtils.event("ad_prepare_show_native", ext = obj)
        NativeView(parent.context, layout).run {
            parent.removeAllViews()
            setNativeAd(nativeAd)
            parent.addView(this)
            parent.isVisible = true
            AdmobEvent.showAd(nativeAd?.responseInfo, "nativeAd")
        }
        loadAd(parent.context.applicationContext)
    }

    fun adAvailable(): Boolean {
        return ((System.currentTimeMillis() - lastTime) / 1000 / 60).toInt() < 30
    }
}