package com.composition.android.lib.ad.interfaces

import android.app.Activity
import android.content.Context
import android.view.View
import android.view.ViewGroup
import com.composition.android.lib.ad.basic.*
import com.composition.android.lib.ad.bean.AdUnitBean
import com.composition.android.lib.ad.exception.AdLoadFailException
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.withTimeoutOrNull

/**
 * @classname:
 * @author: LiuXiaoLong
 * @date: 2022/9/1
 * description:广告商加载广告接口
 */
interface AdLoader {


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


    /**
     * 广告根据策略配置进行加载
     * 可配置：
     * 加载超时时间、重试次数
     *
     */
    suspend fun loadByStrategy(context: Context, adUnitBean: AdUnitBean, iAdFormatRequest: IAdFormatRequest?) : AdResult{
        if (iAdFormatRequest == null){
            return AdResult.Fail(adUnitBean, msg = "广告类型解析出错，请检查adType, 当前广告商:${adUnitBean.advertisersName} 不支持 ${adUnitBean.adType} 类型的广告加载")
        }
        return try {
            withTimeoutOrNull(adUnitBean.requestAdConfig.adLoadTimeOut){
                flow<AdResult> {
                    emit(iAdFormatRequest.load(context, adUnitBean))
                }.onEach {
                    if (it is AdResult.Fail){
                        throw AdLoadFailException()
                    }
                }.retry(adUnitBean.requestAdConfig.adLoadRetryCount.toLong()){
                    it is AdLoadFailException
                }.firstOrNull()
            }?:AdResult.Fail(adUnitBean, AdLoadCode.FAIL, "加载失败")
        }catch (e : Exception){
            AdResult.Fail(adUnitBean, AdLoadCode.FAIL, "加载失败")
        }
    }

    /**
     * 获取BannerAd View
     */
    fun getBannerView(context: Context, adResult: AdResult.Success, viewHolder: BannerAdViewHolder) : BasicAdView<*>?

    /**
     * 获取原生广告View
     *
     */
    fun getNativeAdView(context: Context, adResult: AdResult.Success, viewHolder: NativeAdViewHolder) :View?

    /**
     * 填充原生广告，不会返回View
     * @param adResult 请求成功的广告实例
     * @param viewHolder 要填充的广告布局内容
     * @param adRootView 广告的根布局，例如Admob: NativeAdView
     * 此方法适用于在外部直接写好所有整体的布局 NativeAdView中包含了具体布局，比如在RecyclerView中，这样布局已经绘制，只要填充内容就好
     */
    fun populateNativeAdView(context: Context, adResult: AdResult.Success, viewHolder: NativeAdViewHolder, adRootView : View)

    fun showInterstitialAd(activity: Activity, success: AdResult.Success,adListener: AdListener)

    fun showRewardedAd(activity: Activity, success: AdResult.Success, adListener: AdListener)

    fun showRewardedInterstitialAd(activity: Activity, success: AdResult.Success, adListener: AdListener)

    fun showSplashAd(activity: Activity, splashViewGroup : ViewGroup?, success: AdResult.Success, adListener: AdListener)

    fun showFullScreenAd(activity: Activity, success: AdResult.Success, adListener: AdListener)

}