package com.composition.android.ad.applovinmax.load

import android.app.Activity
import android.content.Context
import android.view.View
import android.view.ViewGroup
import com.applovin.mediation.*
import com.applovin.mediation.ads.MaxAdView
import com.applovin.mediation.ads.MaxAppOpenAd
import com.applovin.mediation.ads.MaxInterstitialAd
import com.applovin.mediation.ads.MaxRewardedAd
import com.applovin.mediation.nativeAds.MaxNativeAdLoader
import com.applovin.mediation.nativeAds.MaxNativeAdView
import com.applovin.sdk.AppLovinSdk
import com.composition.android.ad.applovinmax.load.request.*
import com.composition.android.ad.applovinmax.load.view.AppLovinMaxBannerView
import com.composition.android.ad.applovinmax.load.view.AppLovinMaxNativeTemplateView
import com.composition.android.ad.applovinmax.load.view.AppLovinMaxNativeView
import com.composition.android.lib.ad.AdManager
import com.composition.android.lib.ad.basic.*
import com.composition.android.lib.ad.bean.AdUnitBean
import com.composition.android.lib.ad.interfaces.AdListener
import com.composition.android.lib.ad.interfaces.AdLoader
import com.composition.android.lib.ad.util.adLog
import com.composition.android.lib.ad.util.adLogE
import com.composition.android.lib.ad.util.adLogWithFrame
import com.composition.android.lib.ad.util.parentRemove

/**
 * @classname:
 * @author: LiuXiaoLong
 * @date: 2022/11/11
 * description:AppLovinMax广告加载器
 */
class AppLovinMaxLoader : AdLoader {
    override val advertisers: Advertisers
        get() = Advertisers.AppLovinMax


    suspend fun loadNativeAd(context: Context, adUnitBean: AdUnitBean, nativeAdViewHolder: NativeAdViewHolder): AdResult{
        return loadByStrategy(context, adUnitBean, AppLovinMaxNativeRequestImpl())
    }

    override suspend fun load(context: Context, adUnitBean: AdUnitBean): AdResult {

        val requestImpl = when (adUnitBean.getAdType()) {
            AdType.APP_OPEN -> AppLovinMaxAppOpenRequestImpl()
            AdType.INTERSTITIAL -> AppLovinMaxInterstitialRequestImpl()
            AdType.BANNER -> AppLovinMaxBannerRequestImpl()
            AdType.NATIVE_TEMPLATE -> AppLovinMaxNativeTemplateRequestImpl()
            AdType.REWARDED_VIDEO -> AppLovinMaxRewardRequestImpl()
            AdType.NATIVE -> AppLovinMaxNativeRequestImpl()
            else -> null
        }
        return loadByStrategy(context, adUnitBean, requestImpl)
    }


    /**
     * 获取横幅Banner广告View
     * @param context 上下文
     * @param adResult 请求成功的结果
     * @param viewHolder 横幅广告需要的配置：activity、adListener
     */
    override fun getBannerView(context: Context, adResult: AdResult.Success, viewHolder: BannerAdViewHolder): BasicAdView<*>? {
        return if (adResult.adObject is MaxAdView) {
            AdManager.instance.globalListener?.invoke(adResult.adBean)
            AppLovinMaxBannerView(context).apply {
                setBannerAdViewHolder(viewHolder)
                render(adResult)
            }
        } else {
            null
        }
    }

    /**
     * 获取原生、原生模板广告View
     * @param context 上下文
     * @param adResult 请求成功的结果
     * @param viewHolder 原生广告需要的配置
     * @return View?
     */
    override fun getNativeAdView(context: Context, adResult: AdResult.Success, viewHolder: NativeAdViewHolder): View? {
        return if (adResult.adObject != null) {
            AdManager.instance.globalListener?.invoke(adResult.adBean)
            when (adResult.adBean.getAdType()) {
                AdType.NATIVE_TEMPLATE -> {
                    AppLovinMaxNativeTemplateView(context).apply {
                        setViewHolder(viewHolder)
                        render(adResult)
                    }
                }
                AdType.NATIVE ->{
                    AppLovinMaxNativeView(context).apply {
                        setViewHolder(viewHolder)
                        render(adResult)
                    }
                }
                else -> {
                    null
                }
            }
        } else {
            null
        }
    }


    /**
     * 根据广告adResult.adObject类型，销毁广告
     * @param 广告实例
     *
     */
    override fun destroyAd(adResult: AdResult) {

        try {
            if (adResult is AdResult.Success) {
                when(val ad = adResult.adObject) {
                    is Triple<*, *, *>-> {
                        val triple = adResult.adObject as? Triple<MaxNativeAdLoader, MaxNativeAdView?, MaxAd?>
                        triple?.first?.destroy(triple.third)
                    }
                    is MaxAdView -> ad.destroy()
                    is MaxInterstitialAd -> ad.destroy()
                    is MaxRewardedAd -> ad.destroy()
                    is MaxAppOpenAd -> ad.destroy()
                    else -> {}
                }
                adResult.adObject = null
            }
            adLogWithFrame(msg = "APPLovin广告-${adResult.adBean.getAdType().name}-销毁广告对象完成")
        }catch (e : Exception){
            adLogWithFrame(msg = "APPLovin广告-销毁广告出现了问题 ${e.message}")

        }

    }

    /**
     * 填充原生广告
     *
     */
    override fun populateNativeAdView(context: Context, adResult: AdResult.Success, viewHolder: NativeAdViewHolder, advertisersContainerView: ViewGroup) {
        when(adResult.adBean.getAdType()){
            AdType.NATIVE_TEMPLATE ->{
                val triple = adResult.adObject as? Triple<MaxNativeAdLoader, MaxNativeAdView?, MaxAd?>
                //这里主要是对广告View设置监听
                AppLovinMaxNativeTemplateView.populateNativeTemplateAdView(context, adResult, viewHolder)
                //父布局先移除
                triple?.second?.parentRemove()
                //移除View
                advertisersContainerView.removeAllViews()
                advertisersContainerView.addView(triple?.second)
            }
            AdType.NATIVE ->{
                val triple = adResult.adObject as? Triple<MaxNativeAdLoader, MaxNativeAdView?, MaxAd?>
                AppLovinMaxNativeView.populateNativeTemplateAdView(context, adResult, viewHolder)
                //父布局先移除
                triple?.second?.parentRemove()
                //移除View
                advertisersContainerView.removeAllViews()
                advertisersContainerView.addView(triple?.second)
            }
            else->{
                adLogE(tag = AdManager.TAG, "AppLovinMax组件暂未接入原生广告，不支持填充")
            }
        }
    }

    override fun showInterstitialAd(activity: Activity, adResult: AdResult.Success, adListener: AdListener) {
        if (adResult.adObject is MaxInterstitialAd) {
            val maxInterstitialAd = adResult.adObject as? MaxInterstitialAd
            if (maxInterstitialAd?.isReady == true) {
                maxInterstitialAd.setListener(object : MaxAdListener{
                    override fun onAdLoaded(ad: MaxAd?) {

                    }

                    override fun onAdDisplayed(ad: MaxAd?) {
                        AdManager.instance.globalListener?.invoke(adResult.adBean)
                        adListener.onAdShow(adResult.adBean)
                        adLogWithFrame(msg = "AppLovinMax广告-插屏-显示")
                    }

                    override fun onAdHidden(ad: MaxAd?) {
                        adListener.onAdClose()
                        adLogWithFrame(msg = "AppLovinMax广告-插屏-关闭")
                        destroyAd(adResult)
                    }

                    override fun onAdClicked(ad: MaxAd?) {
                        adListener.onAdClick()
                        adLogWithFrame(msg = "AppLovinMax广告-插屏-点击")
                    }

                    override fun onAdLoadFailed(adUnitId: String?, error: MaxError?) {
                    }

                    override fun onAdDisplayFailed(ad: MaxAd?, error: MaxError?) {
                        adListener.onAdShowFail("AppLovinMax广告-插屏-显示失败-${error?.message}")
                        adLogWithFrame(msg = "AppLovinMax广告-插屏-显示失败")
                    }
                })
                maxInterstitialAd.showAd()
            }else{
                adLogWithFrame(msg = "AppLovinMax广告-插屏-显示失败-isReady:false")
                adListener.onAdShowFail("AppLovinMax广告-插屏-显示失败-isReady:false")
            }
        }else{
            adLogWithFrame(msg = "AppLovinMax广告-插屏-错误-类型错误，当前为:${adResult.adObject?.javaClass?.simpleName}, 应该为:MaxInterstitialAd")
            adListener.onAdShowFail("类型错误，当前为:${adResult.adObject?.javaClass?.simpleName}, 应该为:MaxInterstitialAd")
        }
    }

    override fun showRewardedAd(activity: Activity, adResult: AdResult.Success, adListener: AdListener) {
        if (adResult.adObject is MaxRewardedAd) {
            val maxRewardedAd = adResult.adObject as? MaxRewardedAd
            if (maxRewardedAd?.isReady == true) {
                maxRewardedAd.setListener(object : MaxRewardedAdListener{
                    override fun onAdLoaded(ad: MaxAd?) {

                    }

                    override fun onAdDisplayed(ad: MaxAd?) {
                        AdManager.instance.globalListener?.invoke(adResult.adBean)
                        adListener.onAdShow(adResult.adBean)
                        adLogWithFrame(msg = "AppLovinMax广告-激励-显示")
                    }

                    override fun onAdHidden(ad: MaxAd?) {
                        adListener.onAdClose()
                        adLogWithFrame(msg = "AppLovinMax广告-激励-关闭")
                        destroyAd(adResult)
                    }

                    override fun onAdClicked(ad: MaxAd?) {
                        adListener.onAdClick()
                        adLogWithFrame(msg = "AppLovinMax广告-激励-点击")
                    }

                    override fun onAdLoadFailed(adUnitId: String?, error: MaxError?) {
                    }

                    override fun onAdDisplayFailed(ad: MaxAd?, error: MaxError?) {
                        adListener.onAdShowFail("AppLovinMax广告-激励-显示失败-${error?.message}")
                        adLogWithFrame(msg = "AppLovinMax广告-激励-显示失败")
                    }

                    override fun onUserRewarded(ad: MaxAd?, reward: MaxReward?) {
                        adLogWithFrame(msg = "AppLovinMax广告-激励-下发奖励")
                        adListener.onAdRewarded()
                    }

                    override fun onRewardedVideoStarted(ad: MaxAd?) {
                    }

                    override fun onRewardedVideoCompleted(ad: MaxAd?) {
                    }
                })
                maxRewardedAd.showAd()
            }else{
                adLogWithFrame(msg = "AppLovinMax广告-激励-显示失败-isReady:false")
                adListener.onAdShowFail("AppLovinMax广告-激励-显示失败-isReady:false")
            }
        }else{
            adLogWithFrame(
                msg = "AppLovinMax广告-激励-错误-类型错误，当前为:${adResult.adObject?.javaClass?.simpleName}, 应该为:MaxRewardedAd"
            )
            adListener.onAdShowFail("类型错误，当前为:${adResult.adObject?.javaClass?.simpleName}, 应该为:MaxRewardedAd")
        }
    }

    override fun showRewardedInterstitialAd(activity: Activity, adResult: AdResult.Success, adListener: AdListener) {
        adLogWithFrame(tag = AdManager.TAG, msg = "AppLovinMax广告-插屏激励-不支持此广告格式")
        adListener.onAdShowFail("AppLovinMax广告-插屏激励-不支持此广告格式")
    }

    override fun showSplashAd(activity: Activity, splashViewGroup: ViewGroup?, adResult: AdResult.Success, adListener: AdListener) {
        if (adResult.adObject is MaxAppOpenAd) {

            val maxAppOpenAd = adResult.adObject as MaxAppOpenAd

            if (maxAppOpenAd.isReady && AppLovinSdk.getInstance(activity).isInitialized) {
                maxAppOpenAd.setListener(object : MaxAdListener {
                    override fun onAdLoaded(ad: MaxAd?) {

                    }

                    override fun onAdDisplayed(ad: MaxAd?) {
                        adListener.onAdShow(adResult.adBean)
                        AdManager.instance.globalListener?.invoke(adResult.adBean)
                    }

                    override fun onAdHidden(ad: MaxAd?) {
                        adLogWithFrame(msg = "穿山甲广告-开屏-关闭")
                        adListener.onAdClose()
                        destroyAd(adResult)
                    }

                    override fun onAdClicked(ad: MaxAd?) {
                        adLogWithFrame(msg = "AppLovinMax广告-开屏-点击")
                        adListener.onAdClick()
                    }

                    override fun onAdLoadFailed(adUnitId: String?, error: MaxError?) {
                        adLogWithFrame(msg = "AppLovinMax广告-开屏-点击")

                    }

                    override fun onAdDisplayFailed(ad: MaxAd?, error: MaxError?) {
                        adLogWithFrame(msg = "AppLovinMax广告-开屏-显示失败")
                        adListener.onAdShowFail("AppLovinMax广告-开屏-显示失败")
                    }

                })
            }
            maxAppOpenAd.showAd()


        } else {
            adLogWithFrame(msg = "AppLovinMax广告-开屏-异常-类型错误，当前类型为:${adResult.adObject?.javaClass?.simpleName}, 应为：MaxAppOpenAd")
            adListener.onAdShowFail("类型错误，当前类型为:${adResult.adObject?.javaClass?.simpleName}, 应为：MaxAppOpenAd")
        }
    }

    /**
     * 显示全屏类型广告
     * @param activity 用于展示广告的上下文
     * @param adResult 请求成功的广告实例
     * @param adListener 广告监听
     */
    override fun showFullScreenAd(activity: Activity, adResult: AdResult.Success, adListener: AdListener) {
        when(adResult.adBean.getAdType()){
            AdType.INTERSTITIAL -> showInterstitialAd(activity, adResult, adListener)
            AdType.REWARDED_INTERSTITIAL -> showRewardedInterstitialAd(activity, adResult, adListener)
            AdType.REWARDED_VIDEO -> showRewardedAd(activity, adResult, adListener)
            else -> {
                adListener.onAdShowFail("AppLovinMax, 传入的AdType为:${adResult.adBean.getAdType()},  非全屏类型广告")
            }
        }
    }


}