package com.gh.gamecenter.home.custom.adapter

import android.content.Context
import android.view.ViewGroup
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView.ViewHolder
import com.gh.common.util.DownloadItemUtils
import com.gh.gamecenter.common.exposure.ExposureSource
import com.gh.gamecenter.common.utils.SensorsBridge
import com.gh.gamecenter.common.utils.toBinding
import com.gh.gamecenter.core.utils.StringUtils
import com.gh.gamecenter.entity.GameDataWrapper
import com.gh.gamecenter.eventbus.EBDownloadStatus
import com.gh.gamecenter.eventbus.EBPackage
import com.gh.gamecenter.feature.entity.CustomPageTrackData
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.feature.entity.PageLocation
import com.gh.gamecenter.feature.exposure.ExposureEvent
import com.gh.gamecenter.home.PageConfigure
import com.gh.gamecenter.home.custom.createExposureEvent
import com.gh.gamecenter.home.custom.eventlistener.OtherItemEventHelper
import com.gh.gamecenter.home.custom.model.CustomPageItem
import com.gh.gamecenter.home.test_v2.HomeGameTestV2GameListPlaceHolderViewHolder
import com.gh.gamecenter.home.test_v2.HomeGameTestV2GameListSpaceViewHolder
import com.gh.gamecenter.home.test_v2.HomeGameTestV2GameListViewHolder
import com.lightgame.download.DownloadEntity
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale

/**
 * @author : liujiarui
 * date : 2023/3/6
 * description : 新游开测，游戏列表 adapter
 */
class CustomHomeGameTestV2GameListRvAdapter(
    context: Context,
    private val childEventHelper: OtherItemEventHelper,
    private val linkText: String,
    private val pageLocation: PageLocation,
    private val pageConfigure: PageConfigure,
    private val componentPosition: Int,
    private val trackData: CustomPageTrackData,
) : CustomBaseChildAdapter<GameDataWrapper, ViewHolder>(context) {

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

    fun setData(data:List<GameDataWrapper>){
        val oldList = ArrayList(dataList)
        _dataList.clear()
        _dataList.addAll(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 onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        return when (viewType) {
            0 -> HomeGameTestV2GameListSpaceViewHolder(parent.toBinding())
            1 -> HomeGameTestV2GameListPlaceHolderViewHolder(parent.toBinding())
            else -> HomeGameTestV2GameListViewHolder(parent.toBinding())
        }
    }

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

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        val data = dataList.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(
            context,
            viewHolder.gameDownloadBtn, gameEntity, viewHolder.bindingAdapterPosition, this,
            StringUtils.buildString(mEntrance, "+(新游开测[", position.toString(), "])"),
            location = StringUtils.buildString("新游开测:", gameEntity.name),
            traceEvent = exposureEvent
        ) {
            childEventHelper.onDownloadButtonClick(position, gameEntity)
            SensorsBridge.trackColumnTestClick(
                location = "自定义页面",
                recommendType = linkText,
                text = "按钮",
                bottomTab = pageLocation.bottomTab,
                multiTabName = pageLocation.severalTabPageName,
                multiTabId = pageLocation.severalTabPageId,
                position = pageLocation.tabPosition,
                tabContent = pageLocation.tabContent,
                customPageName = pageLocation.pageName,
                customPageId = pageLocation.pageId,
                gameId = gameEntity.id,
                gameName = gameEntity.name ?: "",
            )
        }

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

        //游戏详情点击事件上报
        viewHolder.itemView.setOnClickListener {
            childEventHelper.navigateToGameDetailPageByGame(position, gameEntity)
            SensorsBridge.trackColumnTestClick(
                location = "自定义页面",
                recommendType = linkText,
                text = "游戏",
                bottomTab = pageLocation.bottomTab,
                multiTabName = pageLocation.severalTabPageName,
                multiTabId = pageLocation.severalTabPageId,
                position = pageLocation.tabPosition,
                tabContent = pageLocation.tabContent,
                customPageName = pageLocation.pageName,
                customPageId = pageLocation.pageId,
                gameId = gameEntity.id,
                gameName = gameEntity.name ?: "",
            )
        }
    }

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

    override fun notifyDownload(download: DownloadEntity) {
        dataList.forEachIndexed { index, item ->
            if (item.gameData?.id == download.gameId) {
                notifyItemChanged(index)
            }
        }
    }

    override fun notifyDownloadDeleted(status: EBDownloadStatus) {
        notifyChildItem(status.packageName)
    }

    override fun notifyInstalled(busFour: EBPackage) {
        notifyChildItem(busFour.packageName)
    }

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

    private fun putExposureEvent(
        gameEntity: GameEntity,
        position: Int
    ): ExposureEvent {
        val time = gameEntity.time?.time ?: 0L
        val date = Date(time * 1000L)
        val sdf = SimpleDateFormat("MM.dd", Locale.CHINA)
        val format = sdf.format(date)

        gameEntity.exposureEvent = createExposureEvent(
            gameEntity,
            listOf(ExposureSource("新游开测", "$linkText-$format")),
            pageConfigure.exposureSourceList,
            position,
            componentPosition,
            trackData
        )

        return gameEntity.exposureEvent!!
    }

}