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

import android.annotation.SuppressLint
import android.content.Context
import androidx.recyclerview.widget.RecyclerView
import com.gh.gamecenter.common.utils.DarkModeUtils
import com.gh.gamecenter.eventbus.EBDownloadStatus
import com.gh.gamecenter.eventbus.EBPackage
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.home.custom.IGameChangedNotifier
import com.lightgame.download.DownloadEntity

abstract class CustomBaseChildAdapter<T, VH : RecyclerView.ViewHolder>(
    val context: Context
) : RecyclerView.Adapter<VH>(),
    IGameChangedNotifier {

    protected val _dataList = arrayListOf<T>()
    val dataList: List<T> = _dataList

    private var darkMode = DarkModeUtils.isDarkModeOn(context)

    protected var _countAndKey: Pair<Int, String>? = null

    @SuppressLint("NotifyDataSetChanged")
    fun submitList(data: List<T>?, forceRefresh: Boolean = false) {
        _dataList.clear()
        data?.let(_dataList::addAll)

        if (forceRefresh) {
            notifyDataSetChanged()
        } else {
            checkResetData(data)
        }


        if (darkMode != DarkModeUtils.isDarkModeOn(context)) {
            darkMode = DarkModeUtils.isDarkModeOn(context)
        }
    }

    override fun getItemCount() = dataList.size

    open fun getItem(position: Int) = dataList[position]

    override fun notifyDownload(download: DownloadEntity) {
        notifyItemWithGameChanged(download.gameId, download.packageName)
    }

    override fun notifyDownloadDeleted(status: EBDownloadStatus) {
        notifyItemWithGameChanged(status.gameId, status.packageName)
    }

    override fun notifyInstalled(busFour: EBPackage) {
        notifyItemWithGameChanged(busFour.gameId ?: "", busFour.packageName)
    }

    private fun notifyItemWithGameChanged(gameId: String, packageName: String, block: ((GameEntity) -> Unit)? = null) {
        dataList.filterIsInstance<GameEntity>()
            .forEachIndexed { index, item ->
                val hasApk = item.getApk().any {
                    it.packageName == packageName
                }
                if (hasApk && item.id == gameId) {
                    block?.invoke(item)
                    notifyItemChanged(index)
                }
            }
    }

    open fun checkResetData(updates: List<T>?) {
        if (updates.isNullOrEmpty()) {
            _countAndKey = null
            notifyDataSetChanged()
            return
        }

        val countAndKey = _countAndKey ?: Pair(0, "")
        val (oldSize, oldKeys) = countAndKey

        val newSize = updates.size
        var newKeys = ""
        updates.forEach {
            newKeys += getKey(it)
        }

        if (oldSize == newSize) {
            if (oldKeys != newKeys || isDarkModeChange()) { // 数量不变，内容发生变化 || 切换浅色模式
                notifyItemRangeChanged(0, itemCount, "")
            }
        } else {// 数量发生变化
            notifyDataSetChanged()
        }
        _countAndKey = Pair(newSize, newKeys)
    }

    protected open fun getKey(t: T) = ""

    fun isDarkModeChange() = darkMode != DarkModeUtils.isDarkModeOn(context)
}