package com.composition.android.lib.ad.widget

import android.content.Context
import android.content.res.TypedArray
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.LinearLayout
import androidx.core.view.isVisible
import androidx.lifecycle.findViewTreeLifecycleOwner
import androidx.lifecycle.lifecycleScope
import com.composition.android.lib.ad.AdLoad
import com.composition.android.lib.ad.AdManager
import com.composition.android.lib.ad.AdUnitConfigManager
import com.composition.android.lib.ad.R
import com.composition.android.lib.ad.basic.AdResult
import com.composition.android.lib.ad.basic.Advertisers
import com.composition.android.lib.ad.basic.NativeAdViewHolder
import com.composition.android.lib.ad.basic.buildAdNativeViewHolder
import com.composition.android.lib.ad.impl.NormalAdListener
import com.composition.android.lib.ad.util.adLogE
import com.convenient.android.common.extension.getActivityFromView
import kotlinx.coroutines.flow.firstOrNull
import kotlinx.coroutines.launch

/**
 * @classname:
 * @author: LiuXiaoLong
 * @date: 2022/9/7
 * description: 自定义的原生广告View, 通过在xml中的配置，view中进行加载广告并展示
 *
 * <NativeAdView
 *  //对应的NativeAdViewHolder view配置，设置view的id..还有其他的，具体查看attr.xml/NativeAdView
 *  app:ad_view_title="@id/tv_ad_title"
 *  app:ad_view_title_desc="..."
 *
 *  //不同广告厂商的原生广告根布局，在每个库中都会默认定义一个，或者自行添加
 *  admob : layout_admob_native_ad_view_root.xml   gms.NativeAdView
 *
 *  app:native_admob_advertisers_root_view="@layout/layout_admob_native_ad_view_root"
 *  app:native_csj_advertisers_root_view="xxx"
 *  app:native_app_lovin_advertisers_root_view="xxx"
 *  app:native_custom_advertisers_root_view="xxx"
 *
 * >
 *
 *     //具体的原生广告view布局
 *     <TextView
 *      android:id="@+id/tv_ad_title"
 *     />
 *
 * </NativeAdView>
 *
 *
 *
 */
class NativeAdView : LinearLayout {

    /**
     * 广告位名称
     */
    private var adSlotName: String = ""

    private var viewHolder: NativeAdViewHolder? = null

    /**
     * NativeAdViewHolder 中view的id -------->
     */
    private var adTitleId: Int = 0

    private var adTitleDescId: Int = 0

    private var adIconId = 0

    private var adMediaContentId = 0

    private var adCallToActionId = 0

    private var adRatingBarId = 0

    private var adRootView: View? = null
    /**
     * <-----------
     */

    private var autoPopulate = true

    constructor(context: Context?) : super(context)
    constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
    constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs) {
        init(attrs)
    }

    private fun init(attrs: AttributeSet?) {
        val typedArray: TypedArray = context.obtainStyledAttributes(attrs, R.styleable.NativeAdView)
        //获取到配置的广告名称
        adSlotName = typedArray.getString(R.styleable.NativeAdView_native_ad_slot_name) ?: ""

        val adUnitBean = AdUnitConfigManager.instance.getAdUnitBySlotName(adSlotNames = listOf(adSlotName)).getOrNull(0)
        if (adUnitBean == null){
            adLogE(AdManager.TAG, "配置的广告位数据不存在, 当前广告位:${adSlotName}")
        }
        when (adUnitBean?.getAdvertisers()) {
            Advertisers.Admob -> attachedAdvertisersNativeAdViewToRoot(typedArray, R.styleable.NativeAdView_native_admob_advertisers_root_view)
            Advertisers.CSJ -> adRootView = this
            Advertisers.AppLovin-> attachedAdvertisersNativeAdViewToRoot(typedArray, R.styleable.NativeAdView_native_app_lovin_advertisers_root_view)
            Advertisers.GroMore -> attachedAdvertisersNativeAdViewToRoot(typedArray, R.styleable.NativeAdView_native_gro_more_advertisers_root_view)
            Advertisers.AppLovinMax -> attachedAdvertisersNativeAdViewToRoot(typedArray, R.styleable.NativeAdView_native_app_lovin_max_advertisers_root_view)
            Advertisers.CUSTOM -> attachedAdvertisersNativeAdViewToRoot(typedArray, R.styleable.NativeAdView_native_custom_advertisers_root_view)
            else -> {}
        }

        adTitleId = typedArray.getResourceId(R.styleable.NativeAdView_ad_view_title, 0)
        adTitleDescId = typedArray.getResourceId(R.styleable.NativeAdView_ad_view_title_desc, 0)
        adIconId = typedArray.getResourceId(R.styleable.NativeAdView_ad_view_icon, 0)
        adMediaContentId = typedArray.getResourceId(R.styleable.NativeAdView_ad_view_media_content_group, 0)
        adCallToActionId = typedArray.getResourceId(R.styleable.NativeAdView_ad_view_call_to_action, 0)
        adRatingBarId = typedArray.getResourceId(R.styleable.NativeAdView_ad_view_rating_bar, 0)

        autoPopulate = typedArray.getBoolean(R.styleable.NativeAdView_ad_auto_populate, true)
        typedArray.recycle()

    }

    override fun addView(child: View?, params: ViewGroup.LayoutParams?) {
        if (childCount != 0 && getChildAt(0) is ViewGroup){
            //把写的原生广告子布局添加到对应的广告商ViewGroup中
            (getChildAt(0) as ViewGroup).addView(child, params)
        }else{
            //这里第一次会在 attachedAdvertisersNativeAdViewToRoot 中调用，把广告商的原生广告根布局添加进来
            super.addView(child, params)
        }
    }


    override fun onAttachedToWindow() {
        super.onAttachedToWindow()
        initViewHolder()
        if (autoPopulate){
            loadAd()
        }
    }

    private fun initViewHolder(){
        if (viewHolder == null){
            viewHolder = buildAdNativeViewHolder {
                this.titleView = findViewById(adTitleId)
                this.titleDescView = findViewById(adTitleDescId)
                this.iconView = findViewById(adIconId)
                this.callActionView = findViewById(adCallToActionId)
                this.ratingBar = findViewById(adRatingBarId)
                this.contentMediaGroup = findViewById(adMediaContentId)
                this.activity = getActivityFromView()
                this.adListener = object : NormalAdListener(){
                    override fun onAdDisLike() {
                        super.onAdDisLike()
                        isVisible = false
                        removeAllViews()
                    }
                }
            }
        }
    }

    private fun attachedAdvertisersNativeAdViewToRoot(typedArray: TypedArray, id: Int) {
        return typedArray.getResourceId(id, -1).let {
            if (it != -1) {
                LayoutInflater.from(context).inflate(it, this, true)
                adRootView = getChildAt(0)
            }
        }
    }

    private fun loadAd(){
        findViewTreeLifecycleOwner()?.lifecycleScope?.launch {
            val adResult = AdLoad.loadAd(context, adSlotName).firstOrNull()
            if (adResult != null && adResult is AdResult.Success && viewHolder != null && adRootView != null){
                AdLoad.populateNativeAdView(context, adResult, viewHolder!!, adRootView!!)
                isVisible = true
            }
        }
    }

    /**
     * 可以不使用View中的自动加载，在这里进行自行填充，非常适用于在RecyclerView中使用
     */
    fun populateNativeAd(adResult: AdResult.Success){
        initViewHolder()
        if (viewHolder!= null && adRootView != null){
            AdLoad.populateNativeAdView(context, adResult, viewHolder!!, adRootView!!)
        }
    }


    fun refreshAd(){
        loadAd()
    }

    fun removeAd(){
        isVisible = false
    }

}