package com.composition.android.lib.ad

import android.app.Activity
import android.content.Context
import android.view.View
import android.view.ViewGroup
import com.composition.android.lib.ad.basic.AdResult
import com.composition.android.lib.ad.basic.BannerAdViewHolder
import com.composition.android.lib.ad.basic.NativeAdViewHolder
import com.composition.android.lib.ad.bean.AdUnitBean
import com.composition.android.lib.ad.impl.Api
import com.composition.android.lib.ad.impl.NormalAdListener
import com.composition.android.lib.ad.interfaces.AdListener
import kotlinx.coroutines.flow.Flow

/**
 * @classname:
 * @author: LiuXiaoLong
 * @date: 2022/9/1
 * description:广告加载类，用于处理广告的加载、展示
 */
object AdLoad {

    fun addToCache(adResult: AdResult.Success) {
        Api.instance.addToCache(adResult)
    }

    /**
     * 预加载广告
     * @param context 上下文
     * @param adSlotNames 要预加载的广告位名称
     */
    suspend fun preloadAd(context: Context, vararg adSlotNames: String) {
        Api.instance.preloadAd(context, adSlotNames = adSlotNames)
    }


    /**
     * 预加载广告
     * @param context 上下文
     * @param adUnitBeans 要预加载的广告单元配置
     */
    suspend fun preloadAd(context: Context, adUnitBeans: List<AdUnitBean>) {
        Api.instance.preloadAd(context, adUnitBeans)
    }

    /**
     * 检查是否有缓存的广告
     * @param adSlotName 广告位名称
     */
    suspend fun hasCacheAd(adSlotName: String): Boolean {
        return Api.instance.hasCacheAd(adSlotName)
    }

    /**
     * 获取缓存的广告
     *
     */
    suspend fun getCacheAd(adUnitBean: AdUnitBean): AdResult.Success? {
        return Api.instance.getCacheAd(adUnitBean)
    }

    /**
     * 获取缓存的广告
     *
     */
    suspend fun getCacheAd(adSlotName: String): AdResult.Success? {
        return Api.instance.getCacheAd(adSlotName)
    }


    /**
     * 根据广告位置名称加载广告
     * 需要先进行配置广告单元信息
     * 可传入多个广告位，会按顺序加载多个广告
     * @param context 上下文，推荐用activity context, 部分中介广告加载必须要activity context
     * @param adSlotName 广告位名称
     * @see AdUnitBean
     * @see AdUnitConfigManager
     * @return Flow<AdResult> 返回协程Flow流
     */
    suspend fun loadAd(context: Context, vararg adSlotNames: String): Flow<AdResult> {
        val beans = AdUnitConfigManager.instance.getAdUnitBySlotName(adSlotNames.toList())
        return loadAd(context = context, adUnitBeans = beans)
    }

    /**
     * 根据广告单元信息加载广告
     * @param context 上下文，推荐用activity context, 部分中介广告加载必须要activity context
     *
     */
    suspend fun loadAd(context: Context, adUnitBeans: List<AdUnitBean>): Flow<AdResult> {
        return Api.instance.load(context, adUnitBeans)
    }


    /**
     * 获取Banner广告View
     */
    fun getBannerAdView(context: Context, success: AdResult.Success, viewHolder: BannerAdViewHolder): View? {
        return Api.instance.getBannerView(context, success, viewHolder)
    }

    fun getNativeAdView(context: Context, adResult: AdResult.Success, viewHolder: NativeAdViewHolder): View? {
        return Api.instance.getNativeAdView(context, adResult, viewHolder)
    }



    fun populateNativeAdView(context: Context, adResult: AdResult.Success, viewHolder: NativeAdViewHolder, advertisersContainerView: ViewGroup) {
        Api.instance.populateNativeAdView(context, adResult, viewHolder, advertisersContainerView)
    }

    fun destroyAd(adResult: AdResult?) {
        Api.instance.destroyAd(adResult)
    }

    /**
     *
     * 显示全屏广告，包含插屏、激励视频、激励插屏，根据传入的AdReslt.adBean.getAdType判断
     * @param activity
     * @param adResult 请求成功的广告结果
     * @param adListener 广告展示监听
     *
     */
    fun showFullScreenAd(
        activity: Activity,
        adResult: AdResult.Success,
        adListener: AdListener
    ) {
        Api.instance.showFullScreenAd(activity, adResult, adListener = adListener)
    }

    /**
     * 显示全屏广告
     * @param activity
     * @param adResult 请求成功的广告实例
     * @param adListener 广告展示监听 高阶函数式
     */
    fun showFullScreenAd(
        activity: Activity,
        adResult: AdResult.Success,
        adListener: NormalAdListener.() -> Unit
    ) {
        showFullScreenAd(activity, adResult, NormalAdListener().also(adListener))
    }

    /**
     * 显示插屏广告
     * @param activity
     * @param adResult 请求成功的广告实例
     * @param adListener 插屏广告监听
     */
    fun showInterstitialAd(
        activity: Activity,
        adResult: AdResult.Success,
        adListener: AdListener
    ) {
        Api.instance.showInterstitialAd(activity = activity, adResult = adResult, adListener = adListener)
    }


    fun showInterstitialAd(
        activity: Activity,
        adResult: AdResult.Success,
        adListener: NormalAdListener.() -> Unit
    ) {
        showInterstitialAd(activity = activity, adResult = adResult, adListener = NormalAdListener().also(adListener))
    }


    /**
     * 显示激励视频广告
     * @param activity
     * @param adResult 请求成功的广告实例
     * @param adListener 插屏广告监听
     */
    fun showRewardedAd(
        activity: Activity,
        adResult: AdResult.Success,
        adListener: NormalAdListener.() -> Unit
    ) {
        Api.instance.showRewardedAd(activity = activity, adResult = adResult, adListener = NormalAdListener().also(adListener))
    }


    /**
     * 显示激励插屏广告
     * @param activity
     * @param adResult 请求成功的广告实例
     * @param adListener 插屏广告监听
     */
    fun showRewardedInterstitialAd(
        activity: Activity,
        adResult: AdResult.Success,
        adListener: AdListener
    ) {
        Api.instance.showRewardedInterstitialAd(activity = activity, adResult = adResult, adListener = adListener)
    }


    fun showRewardedInterstitialAd(
        activity: Activity,
        adResult: AdResult.Success,
        adListener: NormalAdListener.() -> Unit
    ) {
        showRewardedInterstitialAd(activity = activity, adResult = adResult, adListener = NormalAdListener().also(adListener))
    }


    /**
     * 显示开屏广告
     * @param activity 用于展示的activity
     * @param splashViewGroup 用于填充广告的ViewGroup
     * @param adResult 请求成功的广告实例
     * @param adListener 广告监听
     */
    fun showSplash(
        activity: Activity,
        splashViewGroup: ViewGroup?,
        adResult: AdResult.Success,
        adListener: AdListener
    ) {
        Api.instance.showSplash(activity = activity, splashViewGroup = splashViewGroup, success = adResult, adListener = adListener)
    }


    fun showSplash(
        activity: Activity,
        splashViewGroup: ViewGroup?,
        adResult: AdResult.Success,
        adListener: NormalAdListener.() -> Unit
    ) {
        Api.instance.showSplash(activity = activity, splashViewGroup = splashViewGroup, success = adResult, adListener = NormalAdListener().also(adListener))
    }


}