package com.gh.gamecenter.game.rank

import android.content.Context
import android.util.SparseArray
import android.view.View
import android.view.ViewGroup
import androidx.core.util.forEach
import com.gh.common.exposure.ExposureEvent
import com.gh.common.util.DirectUtils
import com.gh.gamecenter.R
import com.gh.gamecenter.common.base.BaseRecyclerViewHolder
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.common.view.AsyncCell
import com.gh.gamecenter.core.runOnIoThread
import com.gh.gamecenter.core.runOnUiThread
import com.gh.gamecenter.databinding.RankCollectionItemBinding
import com.gh.gamecenter.entity.SubjectEntity
import com.gh.gamecenter.eventbus.EBDownloadStatus
import com.lightgame.adapter.BaseRecyclerAdapter
import com.lightgame.download.DownloadEntity

class RankCollectionAdapter(
    context: Context,
    private var mSubjectEntity: SubjectEntity,
    private var clickClosure: (SubjectEntity) -> Unit
) : BaseRecyclerAdapter<RankCollectionAdapter.RankCollectionItemViewHolder>(context) {

    private val mViewHolderList = SparseArray<RankCollectionItemViewHolder>()
    var exposureEventList: ArrayList<ExposureEvent>? = null

    override fun onCreateViewHolder(
        parent: ViewGroup,
        viewType: Int
    ): RankCollectionItemViewHolder {
        return RankCollectionItemViewHolder(
            RankCollectionItemCell(mContext).apply { inflate() }
        ).apply {
            mViewHolderList.put(mViewHolderList.size(), this)
        }
    }

    override fun onBindViewHolder(holder: RankCollectionItemViewHolder, position: Int) {
        val column = mSubjectEntity.columns[position]
        holder.initPackageAndPosition(column)
        (holder.itemView as RankCollectionItemCell).bindWhenInflated {
            (holder.itemView as RankCollectionItemCell).binding?.run {
                val marginLeft = if (position == 0) 16F.dip2px() else 8F.dip2px()
                val marginRight = if (position == itemCount - 1) 16F.dip2px() else 0
                root.layoutParams = (root.layoutParams as ViewGroup.MarginLayoutParams).apply {
                    leftMargin = marginLeft
                    rightMargin = marginRight
                }

                background.hierarchy?.setPlaceholderImage(R.drawable.bg_rank_list.toDrawable(mContext))
                if (column.background.isNotEmpty() && !DarkModeUtils.isDarkModeOn(mContext)) {
                    ImageUtils.display(background, column.background)
                } else {
                    ImageUtils.display(background, "")
                }
                rankTitle.text = column.name
                rankTitle.setOnClickListener {
                    clickClosure.invoke(column)
                    DirectUtils.directToColumnCollection(
                        mContext,
                        mSubjectEntity.id ?: "",
                        -1,
                        "(专题合集-排行榜)",
                        column.name ?: ""
                    )
                }

                rankListContainer.run {
                    val gameList = column.data ?: arrayListOf()
                    runOnIoThread(true) {
                        if (childCount == 0) {
                            for (i in 0..MAX_RANK_ITEM_COUNT) {
                                val gameItem = RankGameItem(RankGameItemUi(context))
                                holder.gameItemList.add(gameItem)
                                runOnUiThread {
                                    addView(gameItem.rankItemUi.root)
                                }
                            }
                        }

                        // 更新 item
                        runOnUiThread {
                            for (i in 0..MAX_RANK_ITEM_COUNT) {
                                if (i < gameList.size) {
                                    holder.gameItemList[i].rankItemUi.root.visibility = View.VISIBLE
                                    holder.gameItemList[i].updateGameItem(
                                        holder.gameItemList[i].rankItemUi,
                                        gameList[i],
                                        exposureEventList,
                                        i,
                                        column.name ?: ""
                                    )
                                } else {
                                    // 数量变化，复用时隐藏多余的
                                    holder.gameItemList[i].rankItemUi.root.visibility = View.GONE
                                }
                            }
                        }
                    }
                }
            }
        }
    }

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

    fun notifyItemByDownload(download: DownloadEntity) {
        mViewHolderList.forEach { _, it ->
            it.notifyItemByDownload(download)
        }
    }

    fun notifyItemAndRemoveDownload(status: EBDownloadStatus) {
        mViewHolderList.forEach { _, it ->
            it.notifyItemAndRemoveDownload(status)
        }
    }

    fun notifyChildItem() {
        mViewHolderList.forEach { _, it ->
            it.checkResetData()
        }
    }

    fun checkResetData(updateDate: SubjectEntity) {
        val updateId = updateDate.id
        val id = mSubjectEntity.id
        mSubjectEntity = updateDate

        if (updateId != id) {
            notifyDataSetChanged()
        } else {
            mViewHolderList.forEach { position, viewHolder ->
                viewHolder.checkResetData(updateDate.columns.safelyGetInRelease(position))
                (viewHolder.itemView as RankCollectionItemCell).binding?.run {
                    background.hierarchy?.setPlaceholderImage(R.drawable.bg_rank_list.toDrawable(mContext))
                    rankTitle.setTextColor(R.color.text_title.toColor(root.context))
                    rankTitleIndicator.setTextColor(R.color.text_title.toColor(root.context))
                    for (item in viewHolder.gameItemList) {
                        item.rankItemUi.orderTv.setTextColor(R.color.title.toColor(root.context))
                        item.rankItemUi.nameTv.setTextColor(R.color.text_title.toColor(root.context))
                    }
                }
            }
        }
    }

    companion object {
        const val MAX_RANK_ITEM_COUNT = 5
    }

    private inner class RankCollectionItemCell(context: Context) : AsyncCell(context) {
        var binding: RankCollectionItemBinding? = null

        override val layoutId = R.layout.rank_collection_item
        override val switchToWrapContentWhenInflated = true
        override fun createDataBindingView(view: View): View? {
            binding = RankCollectionItemBinding.bind(view)
            return view.rootView
        }
    }

    inner class RankCollectionItemViewHolder(view: View) :
        BaseRecyclerViewHolder<Any>(view) {

        private var countAndKey: Pair<Int, String>? = null

        val positionAndPackageMap = HashMap<String, Int>()
        var gameItemList = arrayListOf<RankGameItem>()
        var columnName = ""

        var mRankSubjectEntity: SubjectEntity? = null

        fun initPackageAndPosition(rankSubjectEntity: SubjectEntity) {
            mRankSubjectEntity = rankSubjectEntity

            val dataList = mRankSubjectEntity?.data ?: return

            var dataIds = ""
            dataList.forEach {
                dataIds += it.id
            }
            if (dataIds.isNotEmpty()) countAndKey = Pair(dataList.size, dataIds)

            positionAndPackageMap.clear()
            // 记录游戏位置
            for (i in dataList.indices) {
                val gameEntity = dataList[i]
                var packages = gameEntity.id
                for (apkEntity in gameEntity.getApk()) {
                    packages += apkEntity.packageName
                }
                positionAndPackageMap[packages + i] = i
            }
        }

        fun notifyItemByDownload(download: DownloadEntity) {
            val dataList = mRankSubjectEntity?.data ?: return

            for (key in positionAndPackageMap.keys) {
                if (key.contains(download.packageName) && key.contains(download.gameId)) {
                    val position = positionAndPackageMap[key]
                    if (position != null && position < dataList.size) {
                        dataList[position].getEntryMap()[download.platform] = download
                        gameItemList.safelyGetInRelease(position)?.run {
                            updateGameItem(
                                this.rankItemUi,
                                dataList[position],
                                exposureEventList,
                                position,
                                mRankSubjectEntity?.name ?: ""
                            )
                        }
                    }
                }
            }
        }

        fun notifyItemAndRemoveDownload(status: EBDownloadStatus) {
            val dataList = mRankSubjectEntity?.data ?: return

            for (key in positionAndPackageMap.keys) {
                if (key.contains(status.packageName) && key.contains(status.gameId)) {
                    val position = positionAndPackageMap[key]
                    if (position != null && position < dataList.size) {
                        dataList[position].getEntryMap().remove(status.platform)
                        gameItemList.safelyGetInRelease(position)?.run {
                            updateGameItem(
                                this.rankItemUi,
                                dataList[position],
                                exposureEventList,
                                position,
                                mRankSubjectEntity?.name ?: ""
                            )
                        }
                    }
                }
            }
        }

        fun checkResetData(rankSubjectEntity: SubjectEntity? = mRankSubjectEntity) {
            rankSubjectEntity ?: return

            var dataIds = ""
            mRankSubjectEntity = rankSubjectEntity
            mRankSubjectEntity?.data?.forEach { dataIds += it.id }

            for ((index, game) in mRankSubjectEntity?.data!!.withIndex()) {
                // 因为卡片用了懒加载，所以存在页面还没添加便调用的情况，需特殊处理越界问题
                if (index >= gameItemList.size) return

                gameItemList.safelyGetInRelease(index)?.run {
                    updateGameItem(
                        this.rankItemUi,
                        game,
                        exposureEventList,
                        index,
                        mRankSubjectEntity?.name ?: ""
                    )
                }
            }

            // 重新刷新数据标识
            countAndKey = Pair(mRankSubjectEntity?.data!!.size, dataIds)
        }

    }
}