package com.gh.gamecenter.home.test_v2

import android.content.Context
import android.view.ViewGroup
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView.ViewHolder
import com.gh.common.exposure.IExposable
import com.gh.common.util.DownloadItemUtils
import com.gh.gamecenter.GameDetailActivity
import com.gh.gamecenter.common.exposure.ExposureSource
import com.gh.gamecenter.common.utils.toBinding
import com.gh.gamecenter.core.utils.StringUtils
import com.gh.gamecenter.entity.GameDataWrapper
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.feature.exposure.ExposureEvent
import com.gh.gamecenter.home.ExposureItemData
import com.lightgame.adapter.BaseRecyclerAdapter
import com.lightgame.download.DownloadEntity

/**
 * @author : liujiarui
 * date : 2023/3/6
 * description : 新游开测，游戏列表 adapter
 */
class HomeGameTestV2GameListRvAdapter(
    context: Context,
    private val mViewModel: HomeGameTestV2ViewModel,
    private val mBasicExposureSource: List<ExposureSource>,
    private val mOuterSequence: Int,
    var exposureItemData: ExposureItemData
) : BaseRecyclerAdapter<ViewHolder>(context), IExposable {

    private val mEntrance: String = "新游开测"

    private val mExposureEventMap = mutableMapOf<Int, ExposureEvent>()

    var mDataList = listOf<GameDataWrapper>()

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        return when (viewType) {
            0 -> HomeGameTestV2GameListSpaceViewHolder(parent.toBinding())
            1 -> HomeGameTestV2GameListPlaceHolderViewHolder(parent.toBinding())
            else -> HomeGameTestV2GameListViewHolder(parent.toBinding())
        }
    }

    override fun getItemCount(): Int {
        return mDataList.size
    }

    override fun getItemViewType(position: Int): Int {
        val data = mDataList[position]
        return when {
            data.isSpace -> 0
            data.isPlaceHolder -> 1
            else -> 2
        }
    }

    fun submitData(data: List<GameDataWrapper>) {
        val oldList = mDataList
        mDataList = data
        DiffUtil.calculateDiff(object : DiffUtil.Callback() {
            override fun getOldListSize(): Int {
                return oldList.size
            }

            override fun getNewListSize(): Int {
                return data.size
            }

            override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
                val oldItem = oldList[oldItemPosition]
                val newItem = data[newItemPosition]
                return oldItem.index == newItem.index
            }

            override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
                val oldItem = oldList[oldItemPosition]
                val newItem = data[newItemPosition]
                return oldItem.isSpace == newItem.isSpace
                        && oldItem.isPlaceHolder == newItem.isPlaceHolder
                        && oldItem.gameData?.id == newItem.gameData?.id
                        && oldItem.gameData?.name == newItem.gameData?.name
            }

        }, false).dispatchUpdatesTo(this)
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        val data = mDataList.getOrNull(position) ?: return
        if (holder is HomeGameTestV2GameListViewHolder) {
            val gameData = data.gameData ?: return
            holder.bindGameItem(gameData)
            initGameHolder(holder, gameData, position)
        } else if (holder is HomeGameTestV2GameListPlaceHolderViewHolder) {
            holder.bind()
        }
    }

    /**
     * 初始化上报事件，下载按钮点击事件，游戏详情点击事件，
     * 更新下载状态等
     */
    private fun initGameHolder(
        viewHolder: HomeGameTestV2GameListViewHolder,
        gameEntity: GameEntity,
        position: Int
    ) {
        val exposureEvent = putExposureEvent(gameEntity, position)
        //游戏下载事件上报
        DownloadItemUtils.setOnClickListener(
            mContext,
            viewHolder.gameDownloadBtn, gameEntity, viewHolder.bindingAdapterPosition, this,
            StringUtils.buildString(mEntrance, "+(新游开测[", position.toString(), "])"),
            location = StringUtils.buildString("新游开测:", gameEntity.name),
            traceEvent = exposureEvent
        )

        DownloadItemUtils.updateItem(
            mContext,
            gameEntity,
            viewHolder,
            //"star&brief" //是否显示评分。不加这句不显示评分
        )

        //游戏详情点击事件上报
        viewHolder.itemView.setOnClickListener {
            GameDetailActivity.startGameDetailActivity(
                mContext,
                gameEntity,
                StringUtils.buildString(mEntrance, "+(新游开测[", viewHolder.adapterPosition.toString(), "])"),
                traceEvent = exposureEvent
            )
        }
    }

    fun notifyItemByDownload(downloadEntity: DownloadEntity?) {
        if (downloadEntity == null) {
            notifyDataSetChanged()
        } else {
            mDataList.forEachIndexed { position, gameEntity ->
                if (downloadEntity.gameId == gameEntity.gameData?.id) {
                    notifyItemChanged(position)
                }
            }
        }
    }

    fun notifyChildItem(packageName: String) {
        mDataList.forEachIndexed { position, gameEntity ->
            gameEntity.gameData?.getApk()?.forEach { apkEntity ->
                if (apkEntity.packageName == packageName) {
                    notifyItemChanged(position)
                    return
                }
            }
        }
    }

    private fun putExposureEvent(
        gameEntity: GameEntity,
        position: Int
    ): ExposureEvent {
        val exposureSources = ArrayList<ExposureSource>()
        var timeType = mViewModel.getTimePointLiveData().value ?: "recommend"
        timeType = if (timeType == "recommend") {
            "推荐"
        } else {
            "全部-$timeType"
        }
        exposureSources.add(ExposureSource("新游开测", timeType))

        val exposureEvent = ExposureEvent.createEventWithSourceConcat(
            gameEntity = gameEntity.apply {
                outerSequence = mOuterSequence
                sequence = position
            },
            basicSource = mBasicExposureSource,
            source = exposureSources
        )
        mExposureEventMap[position] = exposureEvent
        //游戏曝光事件交给外层的adapter处理
        val list = mExposureEventMap.values.toList()
        val arrayList = arrayListOf(*list.toTypedArray())
        exposureItemData.exposureEventList = arrayList
        return exposureEvent
    }

    /**
     * 左右滑动曝光条目
     */
    fun exposureItem(firstItemPosition: Int) {
        val gameList = mDataList
        for (position in firstItemPosition..firstItemPosition + 2) {
            val gameEntity = gameList.getOrNull(position)?.gameData ?: continue
            putExposureEvent(gameEntity, position)
        }
    }

    override fun getEventByPosition(pos: Int): ExposureEvent? {
        return mExposureEventMap[pos]
    }

    override fun getEventListByPosition(pos: Int): List<ExposureEvent>? {
        return null
    }
}