package com.gh.gamecenter.game.vertical

import android.content.Context
import android.graphics.drawable.Drawable
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.gh.common.databind.BindingAdapters
import com.gh.common.util.DownloadItemUtils
import com.gh.gamecenter.R
import com.gh.gamecenter.adapter.viewholder.GameViewHolder
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.common.view.AsyncUi
import com.gh.gamecenter.entity.SubjectEntity
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.feature.game.GameItemViewHolder
import com.lightgame.adapter.BaseRecyclerAdapter
import com.lightgame.download.DownloadEntity

class GameVerticalAdapter(
    context: Context,
    private var mSubjectEntity: SubjectEntity,
    private var mItemClick: (Int, GameEntity) -> Unit,
    private var mTransparentBackground: Boolean = false
) : BaseRecyclerAdapter<GameVerticalAdapter.SimpleGameItemViewHolder>(context) {

    private val mMaxWidth = mContext.resources.displayMetrics.widthPixels
    private var countAndKey: Pair<Int, String>? = null
    private var mDarkMode = DarkModeUtils.isDarkModeOn(context)

    init {
        var dataIds = ""
        mSubjectEntity.data?.forEach {
            dataIds += it.id
        }
        if (dataIds.isNotEmpty()) countAndKey = Pair(mSubjectEntity.data?.size ?: 0, dataIds)
    }

    fun getIndex(): Int {
        if (mSubjectEntity.data!!.isNotEmpty()) {
            return if (mSubjectEntity.data!![0].image.isNullOrEmpty()) 0 else 1
        }
        return 0
    }

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

    override fun getItemCount(): Int {
        return mSubjectEntity.data!!.size - getIndex()
    }

    override fun onBindViewHolder(holder: SimpleGameItemViewHolder, position: Int) {
        if (mTransparentBackground) holder.itemView.setBackgroundColor(R.color.transparent.toColor())

        val paddingStart = 16F.dip2px()
        val isEndOfRow = position >= if (itemCount % mSubjectEntity.list == 0) {
            itemCount - mSubjectEntity.list
        } else {
            itemCount - itemCount % mSubjectEntity.list
        }
        // 你可能会问为什么这下面会有一些，"加1减1" 的魔法。没错，这里的 "加1减1"就是为了规避 bug，做出的一些 UI 补偿
        // bug 的表现可以 checkout https://git.shanqu.cc/android/playground/-/tree/test-snap_adapter_culprit 代码，然后滑动到最后一列体验一下
        var paddingEnd = if (isEndOfRow) 16F.dip2px() else 0F.dip2px()

        holder.itemView.layoutParams = if (!isEndOfRow) {
            paddingEnd += 1
            ViewGroup.LayoutParams(mMaxWidth - 24F.dip2px(), ViewGroup.LayoutParams.WRAP_CONTENT)
        } else {
            ViewGroup.LayoutParams(mMaxWidth - 1, ViewGroup.LayoutParams.WRAP_CONTENT)
        }

        val gameEntity = mSubjectEntity.data!![position + getIndex()]
        val subjectData = gameEntity.subjectData!!

        (holder.itemView as AsyncGameItemUi).bindWhenInflated {
            (holder.itemView as AsyncGameItemUi).ui!!.run {
                gameNameTv.setTextColor(R.color.text_title.toColor(mContext))
                serverTypeTv.setTextColor(R.color.theme.toColor(mContext))
                downloadTv.background = R.drawable.download_button_normal_style.toDrawable(mContext)
                gameDesTv.setTextColor(R.color.text_subtitleDesc.toColor(mContext))

                BindingAdapters.setGameName(
                    gameNameTv,
                    gameEntity,
                    false,
                    subjectData.isShowSuffix
                )
                BindingAdapters.setGame(iconIv, gameEntity)
                BindingAdapters.setGameTags(gameTagContainer, gameEntity)
                GameItemViewHolder.initServerType(gameNameTv, serverTypeTv, gameEntity)
                gameDesTv.text = gameEntity.decoratedDes
                GameItemViewHolder.initGameSubtitleAndAdLabel(
                    gameEntity,
                    gameSubtitleTv,
                    gameNameContainer,
                    gameNameTv,
                    gameEntity.adIconActive,
                    adLabelTv
                )

                var gameRatingPaddingEnd = 0
                var gameRatingDrawableStart: Drawable? = null
                var gameRatingTextColor = R.color.theme.toColor(mContext)
                var gameRatingText = ""

                gameRatingTv.textSize = if (gameEntity.commentCount > 3) 12F else 10F

                if (gameEntity.commentCount > 3) {
                    gameRatingPaddingEnd = 8F.dip2px()
                    gameRatingDrawableStart = R.drawable.game_horizontal_rating.toDrawable()
                    gameRatingTextColor = R.color.theme_font.toColor(mContext)
                    gameRatingText =
                        if (gameEntity.star == 10.0F) "10" else gameEntity.star.toString()
                }

                gameRatingTv.setDrawableStart(gameRatingDrawableStart)
                gameRatingTv.setPadding(0, 0, gameRatingPaddingEnd, 0)
                gameRatingTv.setTextColor(gameRatingTextColor)
                gameRatingTv.text = gameRatingText

                // Fuck this view holder
                val tempViewHolder =
                    holder.placeholderGameViewHolder ?: GameViewHolder(this@run.root).apply {
                        holder.placeholderGameViewHolder = this
                    }
                tempViewHolder.gameDes = gameDesTv
                tempViewHolder.gameDownloadBtn = downloadTv
                tempViewHolder.multiVersionDownloadTv = multiVersionDownloadTv
                tempViewHolder.gameDownloadTips = downloadTipsLottie
                tempViewHolder.gameLabelList = gameTagContainer
                tempViewHolder.recommendIv = recommendIv
                tempViewHolder.recommendTv = recommendTv
                tempViewHolder.recommendContainer = recommendConstraintLayout
                tempViewHolder.gameServerType = serverTypeTv

                DownloadItemUtils.updateItem(
                    mContext,
                    gameEntity,
                    tempViewHolder,
                    !gameEntity.isPluggable,
                    subjectData.briefStyle
                )

                DownloadItemUtils.setOnClickListener(
                    mContext, downloadTv, gameEntity, position,
                    this@GameVerticalAdapter, "", "", gameEntity.exposureEvent
                )

                root.setPadding(paddingStart, 8F.dip2px(), paddingEnd, 8F.dip2px())
            }
        }

        holder.itemView.setOnClickListener {
            mItemClick.invoke(position % mSubjectEntity.list, gameEntity)
        }
    }

    fun checkResetData(updateData: SubjectEntity) {
        var dataIds = ""
        mSubjectEntity.data?.forEach {
            dataIds += it.id
        }

        mSubjectEntity = updateData
        if ((countAndKey?.first == updateData.data?.size && countAndKey?.second != dataIds) || mDarkMode != DarkModeUtils.isDarkModeOn(
                mContext
            )
        ) { // 数量不变,内容发生改变
            notifyItemRangeChanged(0, itemCount)
            mDarkMode = DarkModeUtils.isDarkModeOn(mContext)
        } else if (countAndKey?.first != updateData.data?.size) { // 数量发生改变
            notifyDataSetChanged()
        }

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

    fun notifyItemByDownload(downloadEntity: DownloadEntity?) {
        if (downloadEntity == null) {
            notifyDataSetChanged()
        } else {
            for (position in mSubjectEntity.data!!.indices) {
                val entity = mSubjectEntity.data!![position]
                if (downloadEntity.gameId == entity.id) {
                    notifyItemChanged(position - getIndex())
                    return
                }
            }
        }
    }

    fun notifyChildItem(packageName: String) {
        for (position in mSubjectEntity.data!!.indices) {
            val entity = mSubjectEntity.data!![position]
            for (apk in entity.getApk()) {
                if (apk.packageName == packageName) {
                    notifyItemChanged(position - getIndex())
                    return
                }
            }
        }
    }

    class AsyncGameItemUi(context: Context) : AsyncUi<GameItemUi>(context) {
        override fun provideUi(context: Context) = GameItemUi(context)
    }

    class SimpleGameItemViewHolder(view: AsyncGameItemUi) :
        RecyclerView.ViewHolder(view) {
        var placeholderGameViewHolder: GameViewHolder? = null
    }

}