package com.composition.android.ad.admob.load

import android.app.Activity
import android.content.Context
import android.view.View
import android.view.ViewGroup
import com.composition.android.ad.admob.load.request.*
import com.composition.android.ad.admob.load.view.AdmobBannerView
import com.composition.android.ad.admob.load.view.AdmobNativeAdView
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.google.android.gms.ads.AdError
import com.google.android.gms.ads.AdView
import com.google.android.gms.ads.FullScreenContentCallback
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.nativead.NativeAdView
import com.google.android.gms.ads.rewarded.RewardedAd
import com.google.android.gms.ads.rewardedinterstitial.RewardedInterstitialAd

/**
 * @classname:
 * @author: LiuXiaoLong
 * @date: 2022/9/5
 * description: Admob广告加载类
 */
class AdmobAdLoader : AdLoader {

    override val advertisers: Advertisers
        get() = Advertisers.Admob

    override suspend fun load(context: Context, adUnitBean: AdUnitBean): AdResult {
        if (adUnitBean.isAvailable().not()) {
            return AdResult.Fail(adUnitBean, msg = "AdUnitBean无效")
        }
        //获取到具体的广告格式加载类
        val adFormatRequestImpl = when (adUnitBean.getAdType()) {
            AdType.REWARDED_VIDEO -> AdmobRewardRequestImpl()
            AdType.INTERSTITIAL -> AdmobInterstitialRequestImpl()
            AdType.REWARDED_INTERSTITIAL -> AdmobRewardInterstitialRequestImpl()
            AdType.APP_OPEN -> AdmobAppOpenRequestImpl()
            AdType.BANNER -> AdmobBannerRequestImpl()
            AdType.NATIVE -> AdMobNativeRequestImpl()
            else -> null
        }
        //根据策略进行加载
        return loadByStrategy(context, adUnitBean, adFormatRequestImpl)
    }

    override fun getBannerView(context: Context, adResult: AdResult.Success, viewHolder: BannerAdViewHolder): BasicAdView<*>? {
        return if (adResult.adObject != null) {
            AdmobBannerView(context).apply {
                setBannerAdViewHolder(viewHolder)
                render(adResult)
                AdManager.instance.globalListener?.invoke(adResult.adBean)
            }
        } else {
            null
        }
    }

    override fun getNativeAdView(context: Context, adResult: AdResult.Success, viewHolder: NativeAdViewHolder): View? {
        return if (adResult.adObject != null) {
            AdmobNativeAdView(context).apply {
                setNativeAdViewHolder(viewHolder)
                render(adResult)
                AdManager.instance.globalListener?.invoke(adResult.adBean)
            }
        } else {
            null
        }
    }


    override fun populateNativeAdView(context: Context, adResult: AdResult.Success, viewHolder: NativeAdViewHolder, advertisersContainerView: ViewGroup) {
        AdManager.instance.globalListener?.invoke(adResult.adBean)
        if (advertisersContainerView is NativeAdView) {
            AdmobNativeAdView.populateNativeAdView(context, adResult, viewHolder, advertisersContainerView)
        } else {
            adLog(msg = "Admob广告-填充原生-advertisersContainerView类型错误， 应该为NativeAdView")
        }
    }

    /**
     * 显示插屏广告
     */
    override fun showInterstitialAd(activity: Activity, adResult: AdResult.Success, adListener: AdListener) {

        if (adResult.adObject is InterstitialAd) {

            val interstitialAd = adResult.adObject as InterstitialAd
            interstitialAd.fullScreenContentCallback = object : FullScreenContentCallback() {
                override fun onAdDismissedFullScreenContent() {
                    super.onAdDismissedFullScreenContent()
                    adListener.onAdClose()
                    adLog(msg = "Admob广告-插屏-关闭")
                }

                override fun onAdFailedToShowFullScreenContent(p0: AdError) {
                    super.onAdFailedToShowFullScreenContent(p0)
                    adListener.onAdLoadedFail()
                    adLog(msg = "Admob广告-插屏-展示失败")
                }

                override fun onAdShowedFullScreenContent() {
                    super.onAdShowedFullScreenContent()
                    adLog(msg = "Admob广告-插屏-展示")
                    adListener.onAdShow(adUnitBean = adResult.adBean)
                    AdManager.instance.globalListener?.invoke(adResult.adBean)
                }
            }
            interstitialAd.setOnPaidEventListener {

            }
            interstitialAd.show(activity)
        } else {
            adLog(
                msg = "Admob广告-插屏-异常\n" +
                        "类型错误，当前类型为:${adResult.adObject?.javaClass?.simpleName}, 应为：InterstitialAd"
            )
            adListener.onAdLoadedFail()
        }
    }

    /**
     * 显示激励广告
     */
    override fun showRewardedAd(activity: Activity, adResult: AdResult.Success, adListener: AdListener) {
        if (adResult.adObject is RewardedAd) {
            val adObj = adResult.adObject as RewardedAd
            adObj.fullScreenContentCallback = object : FullScreenContentCallback() {

                override fun onAdDismissedFullScreenContent() {
                    adListener.onAdClose()
                    adLog(msg = "Admob广告-激励-关闭")
                }

                override fun onAdFailedToShowFullScreenContent(p0: AdError) {
                    super.onAdFailedToShowFullScreenContent(p0)
                    adListener.onAdLoadedFail()
                    adLog(msg = "Admob广告-激励-展示失败")
                }

                override fun onAdShowedFullScreenContent() {
                    adLog(msg = "Admob广告-激励-展示")
                    adListener.onAdShow(adResult.adBean)
                    AdManager.instance.globalListener?.invoke(adResult.adBean)
                }
            }
            adObj.setOnPaidEventListener {
            }
            adObj.show(activity) {
                adListener.onAdRewarded()
            }
        } else {
            adLog(
                msg = "Admob广告-激励-异常\n" +
                        "类型错误，当前类型为:${adResult.adObject?.javaClass?.simpleName}, 应为：RewardedAd"
            )
            adListener.onAdShowFail("类型错误，当前类型为:${adResult.adObject?.javaClass?.simpleName}, 应为：RewardedAd")
        }
    }

    override fun showRewardedInterstitialAd(activity: Activity, adResult: AdResult.Success, adListener: AdListener) {
        if (adResult.adObject is RewardedInterstitialAd) {
            val rewardedInterstitialAd = adResult.adObject as RewardedInterstitialAd
            rewardedInterstitialAd.fullScreenContentCallback = object : FullScreenContentCallback() {
                override fun onAdDismissedFullScreenContent() {
                    adLog(msg = "Admob广告-激励插屏-关闭")
                    adListener.onAdClose()
                }

                override fun onAdFailedToShowFullScreenContent(p0: AdError) {
                    super.onAdFailedToShowFullScreenContent(p0)
                    adLog(msg = "Admob广告-激励插屏-展示失败")
                    adListener.onAdLoadedFail()
                }

                override fun onAdShowedFullScreenContent() {
                    adLog(msg = "Admob广告-激励插屏-展示")
                    adListener.onAdShow(adResult.adBean)
                    AdManager.instance.globalListener?.invoke(adResult.adBean)
                }
            }
            rewardedInterstitialAd.setOnPaidEventListener {
            }
            rewardedInterstitialAd.show(activity) {
                adListener.onAdRewarded()
            }
        } else {
            adLog(
                msg = "Admob广告-激励插屏-异常\n" +
                        "类型错误，当前类型为:${adResult.adObject?.javaClass?.simpleName}, 应为：RewardedInterstitialAd"
            )
            adListener.onAdShowFail("类型错误，当前类型为:${adResult.adObject?.javaClass?.simpleName}, 应为：RewardedInterstitialAd")
        }
    }

    /**
     * 显示全屏广告，根据广告类型进行判断需要展示的广告
     * 包括：
     * 插屏广告，激励视频广告，激励插屏广告
     */
    override fun showFullScreenAd(activity: Activity, adResult: AdResult.Success, adListener: AdListener) {
        when (adResult.adBean.getAdType()) {
            AdType.INTERSTITIAL -> showInterstitialAd(activity, adResult, adListener)
            AdType.REWARDED_VIDEO -> showRewardedAd(activity, adResult, adListener)
            AdType.REWARDED_INTERSTITIAL -> showRewardedInterstitialAd(activity, adResult, adListener)
            else -> adListener.onAdShowFail("无对应广告类型的广告进行展示 AdType:${adResult.adBean.adType}")
        }
    }

    /**
     * 显示开屏广告
     */
    override fun showSplashAd(activity: Activity, splashViewGroup: ViewGroup?, adResult: AdResult.Success, adListener: AdListener) {
        val appOpenAd = adResult.adObject as? AppOpenAd
        if (appOpenAd != null) {
            val callback: FullScreenContentCallback = object : FullScreenContentCallback() {
                override fun onAdDismissedFullScreenContent() {
                    adLog(msg = "Admob广告-开屏-关闭")
                    adListener.onAdClose()
                }

                override fun onAdFailedToShowFullScreenContent(adError: AdError) {
                    adLog(msg = "Admob广告-开屏-展示异常")
                    adListener.onAdSkip()
                }

                override fun onAdShowedFullScreenContent() {
                    adLog(msg = "Admob广告-开屏-展示")
                    adListener.onAdShow(adResult.adBean)
                    AdManager.instance.globalListener?.invoke(adResult.adBean)
                }
            }
            appOpenAd.fullScreenContentCallback = callback
            appOpenAd.setOnPaidEventListener {
            }
            appOpenAd.show(activity)
        } else {
            adLog(msg = "Admob广告-开屏-异常-广告实例为空")
            adListener.onAdShowFail("Admob广告-开屏-异常-广告实例为空")
        }
    }


    override fun destroyAd(adResult: AdResult) {
        try {
            if (adResult is AdResult.Success) {
                when (val ad = adResult.adObject) {
                    is AdView -> ad.destroy()
                    is NativeAd -> ad.destroy()
                    else -> {}
                }
                adResult.adObject = null
            }
            adLog(msg = "Admob广告-销毁广告对象完成")
        }catch (e : Exception){
            e.printStackTrace()
        }
    }

}