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

import android.content.Context
import android.view.View
import android.view.ViewGroup
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.databinding.RankCollectionItemCustomBinding
import com.gh.gamecenter.eventbus.EBDownloadStatus
import com.gh.gamecenter.eventbus.EBPackage
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.feature.exposure.ExposureEvent
import com.gh.gamecenter.feature.exposure.IExposureListProvider
import com.gh.gamecenter.game.rank.CustomRankGameItem
import com.gh.gamecenter.game.rank.RankGameItemUi
import com.gh.gamecenter.home.custom.IGameChangedNotifier
import com.gh.gamecenter.home.custom.eventlistener.GameSubjectCollectionEventHelper
import com.gh.gamecenter.home.custom.model.CustomPageData
import com.gh.gamecenter.home.custom.model.CustomSubjectCollectionItem
import com.lightgame.download.DownloadEntity

class CustomRankCollectionAdapter(
    context: Context,
    private val eventHelper: GameSubjectCollectionEventHelper
) : CustomBaseChildAdapter<CustomPageData.LinkColumnCollection.CustomSubjectEntity, CustomRankCollectionAdapter.RankCollectionItemViewHolder>(
    context
) {

    private val viewHolderList = arrayListOf<RankCollectionItemViewHolder>()

    private var _data: CustomSubjectCollectionItem? = null

    fun setData(data: CustomSubjectCollectionItem) {
        _data = data
        submitList(data.data.data)
    }

    override fun getKey(t: CustomPageData.LinkColumnCollection.CustomSubjectEntity): String {
        return t.id
    }

    override fun onCreateViewHolder(
        parent: ViewGroup,
        viewType: Int
    ): RankCollectionItemViewHolder {
        return RankCollectionItemViewHolder(RankCollectionItemCell(context).apply { inflate() })
    }

    override fun onBindViewHolder(holder: RankCollectionItemViewHolder, position: Int) {
        val subjectEntity = getItem(position)
        holder.initPackageAndPosition(subjectEntity)
        (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(this@CustomRankCollectionAdapter.context))
                if (subjectEntity.image.isNotEmpty() && !DarkModeUtils.isDarkModeOn(context)) {
                    ImageUtils.display(background, subjectEntity.image)
                } else {
                    background.tag = null
                    background.setImageURI("")
                }
                val title = if (subjectEntity.title.length > 12) {
                    "${subjectEntity.title.substring(0, 12)}..."
                } else {
                    subjectEntity.title
                }
                rankTitle.text = title
                rankTitle.setTextColor(com.gh.gamecenter.common.R.color.text_primary.toColor(context))
                rankTitle.setOnClickListener {
                    eventHelper.navigateSubjectCollectionPage(position, subjectEntity)
                }
                rankTitleIndicator.setTextColor(com.gh.gamecenter.common.R.color.text_primary.toColor(context))

                rankListContainer.run {
                    val gameList = subjectEntity.games

                    if (childCount == 0) {
                        for (i in 0..MAX_RANK_ITEM_COUNT) {
                            val gameItem = CustomRankGameItem(RankGameItemUi(context))
                            holder.gameItemList.add(gameItem)
                            addView(gameItem.rankItemUi.root)
                        }
                    }

                    // 更新 item
                    for (i in 0..MAX_RANK_ITEM_COUNT) {
                        if (i < gameList.size) {
                            with(holder.gameItemList[i]) {
                                rankItemUi.root.visibility = View.VISIBLE
                                updateGameItem(
                                    holder.gameItemList[i].rankItemUi,
                                    gameList[i],
                                    _data?.exposureEventList,
                                    i,
                                    subjectEntity,
                                    eventHelper
                                )
                                rankItemUi.orderTv.setTextColor(com.gh.gamecenter.common.R.color.title.toColor(root.context))
                                rankItemUi.nameTv.setTextColor(com.gh.gamecenter.common.R.color.text_primary.toColor(root.context))
                            }
                        } else {
                            // 数量变化，复用时隐藏多余的
                            holder.gameItemList[i].rankItemUi.root.visibility = View.GONE
                        }
                    }
                }
            }
        }
    }

    override fun notifyDownload(download: DownloadEntity) {
        viewHolderList.forEach {
            it.notifyDownload(download)
        }
    }

    override fun notifyDownloadDeleted(status: EBDownloadStatus) {
        viewHolderList.forEach {
            it.notifyDownloadDeleted(status)
        }
    }

    override fun notifyInstalled(busFour: EBPackage) {
        super.notifyInstalled(busFour)
        viewHolderList.forEach {
            it.notifyInstalled(busFour)
        }
    }

    override fun onViewAttachedToWindow(holder: RankCollectionItemViewHolder) {
        super.onViewAttachedToWindow(holder)
        viewHolderList.add(holder)
    }

    override fun onViewDetachedFromWindow(holder: RankCollectionItemViewHolder) {
        super.onViewDetachedFromWindow(holder)
        viewHolderList.remove(holder)
    }

    companion object {
        const val MAX_RANK_ITEM_COUNT = 5
    }

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

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

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

        val gameItemList = arrayListOf<CustomRankGameItem>()

        private var subjectEntity: CustomPageData.LinkColumnCollection.CustomSubjectEntity? = null

        fun initPackageAndPosition(subjectEntity: CustomPageData.LinkColumnCollection.CustomSubjectEntity) {
            this.subjectEntity = subjectEntity
        }

        override fun notifyDownload(download: DownloadEntity) {
            notifyItemWithGameChanged(download.gameId, download.packageName) {
                it.getEntryMap()[download.platform] = download
            }
        }

        override fun notifyDownloadDeleted(status: EBDownloadStatus) {
            notifyItemWithGameChanged(status.gameId, status.packageName) {
                it.getEntryMap().remove(status.platform)
            }
        }

        override fun notifyInstalled(busFour: EBPackage) {
            checkResetData()
        }

        private fun notifyItemWithGameChanged(
            gameId: String,
            packageName: String,
            block: ((GameEntity) -> Unit)? = null
        ) {
            subjectEntity?.games?.forEachIndexed { index, item ->
                val hasPackageName = item.getApk().any {
                    it.packageName == packageName
                }
                if (hasPackageName && item.id == gameId) {
                    block?.invoke(item)
                    gameItemList.safelyGetInRelease(index)?.run {
                        updateGameItem(
                            this.rankItemUi,
                            item,
                            _data?.exposureEventList,
                            index,
                            subjectEntity,
                            eventHelper
                        )
                    }
                }
            }
        }

        private fun checkResetData(rankSubjectEntity: CustomPageData.LinkColumnCollection.CustomSubjectEntity? = subjectEntity) {
            rankSubjectEntity ?: return
            subjectEntity = rankSubjectEntity

            rankSubjectEntity.games.forEachIndexed { index, item ->
                // 因为卡片用了懒加载，所以存在页面还没添加便调用的情况，需特殊处理越界问题
                if (index >= gameItemList.size) {
                    return@forEachIndexed
                }

                gameItemList.safelyGetInRelease(index)?.run {
                    updateGameItem(
                        this.rankItemUi,
                        item,
                        _data?.exposureEventList,
                        index,
                        rankSubjectEntity,
                        eventHelper
                    )
                }
            }
        }

        override fun provideExposureData(): ExposureEvent? = null

        override fun provideExposureDataList(): List<ExposureEvent>? {
            return subjectEntity?.games?.map {
                it.exposureEvent?.getFreshExposureEvent()!!
            }
        }
    }
}