package com.gh.gamecenter.discovery

import android.content.Context
import android.util.SparseArray
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.gh.common.constant.Config
import com.gh.common.databind.BindingAdapters
import com.gh.common.exposure.IExposable
import com.gh.common.util.DirectUtils
import com.gh.common.util.DownloadItemUtils
import com.gh.common.util.HomeBottomBarHelper
import com.gh.common.util.NewFlatLogUtils
import com.gh.gamecenter.BlockActivity
import com.gh.gamecenter.GameDetailActivity
import com.gh.gamecenter.R
import com.gh.gamecenter.adapter.viewholder.GameViewHolder
import com.gh.gamecenter.common.base.BaseRecyclerViewHolder
import com.gh.gamecenter.common.baselist.ListAdapter
import com.gh.gamecenter.common.baselist.LoadStatus
import com.gh.gamecenter.common.constant.ItemViewType
import com.gh.gamecenter.common.exposure.ExposureSource
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.common.viewholder.FooterViewHolder
import com.gh.gamecenter.core.utils.StringUtils
import com.gh.gamecenter.databinding.DiscoveryGameItemBinding
import com.gh.gamecenter.databinding.ItemRecommendInterestBinding
import com.gh.gamecenter.databinding.ItemRecommendInterestFooterBinding
import com.gh.gamecenter.databinding.ItemRecommendInterestImageBinding
import com.gh.gamecenter.discovery.DiscoveryFragment.Companion.INTERESTED_GAME_REQUEST_CODE
import com.gh.gamecenter.discovery.interestedgame.InterestedGameActivity
import com.gh.gamecenter.entity.DiscoveryGameCardLabel
import com.gh.gamecenter.eventbus.EBDownloadStatus
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.feature.exposure.ExposureConstants
import com.gh.gamecenter.feature.exposure.ExposureEvent
import com.gh.gamecenter.feature.exposure.ExposureType
import com.gh.gamecenter.feature.exposure.IExposureProvider
import com.gh.gamecenter.feature.game.GameItemViewHolder
import com.lightgame.download.DownloadEntity

class DiscoveryAdapter(
    context: Context,
    private val mFragment: DiscoveryFragment,
    private val mViewModel: DiscoveryViewModel,
    private val mBaseExposureSource: ArrayList<ExposureSource>,
    private val mOuterSequence: Int,
    private val mEntrance: String,
    private val mDislikeCallback: (anchorView: View, itemData: DiscoveryItemData) -> Unit
) : ListAdapter<DiscoveryItemData>(context), IExposable {

    private val mExposureEventSparseArray: SparseArray<ExposureEvent> = SparseArray()

    override fun getItemViewType(position: Int): Int {
        val value = mViewModel.loadStatusLiveData.value
        if (position == itemCount - 1) {
            if (value == LoadStatus.INIT_OVER || value == LoadStatus.LIST_OVER) {
                return ITEM_DIRECT_GAME_BLOCK
            }
            return ItemViewType.ITEM_FOOTER
        }
        val itemData = mEntityList[position]
        return when {
            itemData.interestCardLabels != null -> {
                ITEM_RECOMMEND_INTEREST
            }

            itemData.interestImageCardLabel != null -> {
                ITEM_RECOMMEND_INTEREST_IMAGE
            }

            else -> {
                ItemViewType.GAME_NORMAL
            }
        }
    }

    override fun areItemsTheSame(oldItem: DiscoveryItemData?, newItem: DiscoveryItemData?): Boolean {
        if (oldItem?.gameEntity != null && newItem?.gameEntity != null) {
            return oldItem.gameEntity.id == newItem.gameEntity.id
        }
        if (oldItem?.interestCardLabels != null && newItem?.interestCardLabels != null) {
            return oldItem.interestCardLabels.firstOrNull()?.id == newItem.interestCardLabels.firstOrNull()?.id
        }
        if (oldItem?.interestImageCardLabel != null && newItem?.interestImageCardLabel != null) {
            return oldItem.interestImageCardLabel.id == newItem.interestImageCardLabel.id
        }
        return false
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
        return when (viewType) {
            ItemViewType.GAME_NORMAL -> {
                DiscoveryGameViewHolder(parent.toBinding())
            }

            ItemViewType.ITEM_FOOTER -> {
                FooterViewHolder(mLayoutInflater.inflate(com.gh.gamecenter.common.R.layout.refresh_footerview, parent, false))
            }

            ITEM_DIRECT_GAME_BLOCK -> {
                DirectGameBlockViewHolder(parent.toBinding())
            }

            ITEM_RECOMMEND_INTEREST -> {
                RecommendInterestViewHolder(parent.toBinding())
            }

            ITEM_RECOMMEND_INTEREST_IMAGE -> {
                RecommendInterestImageViewHolder(parent.toBinding())
            }

            else -> {
                throw NullPointerException()
            }
        }
    }

    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
        when (holder) {
            is DiscoveryGameViewHolder -> {
                val itemData = mEntityList[position]
                val gameEntity = itemData.gameEntity!!
                DownloadItemUtils.updateItem(mContext, gameEntity, holder, "star")
                holder.bindGameItem(gameEntity)
                val type = when (gameEntity.type) {
                    "recommend" -> "专题推荐"
                    "ad" -> "游戏广告"
                    "filter" -> "算法过滤"
                    else -> ""
                }
                val exposureSources = ArrayList<ExposureSource>().apply {
                    add(ExposureSource("发现", type))
                }
                val event = ExposureEvent.createEventWithSourceConcat(
                    gameEntity.apply {
                        sequence = position
                        if (mOuterSequence >= 0) {
                            outerSequence = mOuterSequence
                        }
                        subPageCode = ExposureConstants.DISCOVERY
                    },
                    mBaseExposureSource,
                    exposureSources,
                    null,
                    ExposureType.EXPOSURE
                )
                mExposureEventSparseArray.put(position, event)

                holder.itemView.setOnClickListener {
                    SensorsBridge.trackGameExploreClick(
                        "游戏",
                        "详情页",
                        gameId = gameEntity.id,
                        gameName = gameEntity.name ?: "",
                    )
                    GameDetailActivity.startGameDetailActivity(
                        mContext,
                        gameEntity,
                        StringUtils.buildString("(${mEntrance}", "-列表[", (position).toString(), "])"),
                        traceEvent = event
                    )
                }
                holder.itemView.setOnLongClickListener {
                    mDislikeCallback.invoke(holder.itemView, itemData)
                    true
                }
                DownloadItemUtils.setOnClickListener(
                    mContext,
                    holder.binding.downloadBtn,
                    gameEntity,
                    position,
                    this,
                    StringUtils.buildString("(${mEntrance}", "-列表[", (position).toString(), "])"),
                    location = StringUtils.buildString(mEntrance, ":", gameEntity.name),
                    traceEvent = event
                ) {
                    SensorsBridge.trackGameExploreClick(
                        "按钮",
                        "详情页",
                        gameId = gameEntity.id,
                        gameName = gameEntity.name ?: "",
                    )
                }
            }

            is RecommendInterestViewHolder -> {
                holder.binding.root.setBackgroundColor(com.gh.gamecenter.common.R.color.ui_surface.toColor(mContext))
                holder.binding.backgroundView.background = com.gh.gamecenter.common.R.drawable.bg_shape_space_radius_8.toDrawable(mContext)
                holder.binding.interestTv.setTextColor(com.gh.gamecenter.common.R.color.text_primary.toColor(mContext))
                val labels = mEntityList[position].interestCardLabels ?: return
                val labelTvList = arrayListOf(holder.binding.labelTv1, holder.binding.labelTv2, holder.binding.labelTv3)
                labelTvList.forEachIndexed { index, labelTv ->
                    labelTv.goneIf(labels.size < index + 1) {
                        labelTv.setTextColor(com.gh.gamecenter.common.R.color.text_secondary.toColor(mContext))
                        labelTv.background = R.drawable.bg_shape_white_radius_4.toDrawable(mContext)
                        labelTv.setDrawableEnd(R.drawable.ic_interest_arrow)
                        labels[index].text = labels[index].linkText
                        labelTv.text = labels[index].title
                        labelTv.setOnClickListener {
                            val link = labels[index]
                            SensorsBridge.trackGameExploreClick(
                                "内容标签",
                                "详情页",
                                linkType = link.type ?: "",
                                linkId = link.link ?: "",
                                linkText = link.text ?: "",
                                buttonType = link.title ?: ""
                            )
                            DirectUtils.directToLinkPage(holder.binding.root.context, link, mEntrance, "")
                            logDiscoverPageRecommendedInterestCardClick(
                                mEntityList[position].cardPosition,
                                link
                            )
                        }
                    }
                }
            }

            is RecommendInterestImageViewHolder -> {
                holder.binding.root.setBackgroundColor(com.gh.gamecenter.common.R.color.ui_surface.toColor(mContext))
                val label = mEntityList[position].interestImageCardLabel ?: return
                label.text = label.linkText
                holder.binding.root.setOnClickListener {
                    SensorsBridge.trackGameExploreClick(
                        "内容标签",
                        "详情页",
                        linkType = label.type ?: "",
                        linkId = label.link ?: "",
                        linkText = label.text ?: "",
                    )
                    DirectUtils.directToLinkPage(holder.binding.root.context, label, mEntrance, "")
                    logDiscoverPageRecommendedInterestCardClick(mEntityList[position].cardPosition, label)
                }
            }

            is DirectGameBlockViewHolder -> {
                holder.binding.run {
                    val userInterestedGame = Config.getUserInterestedGame()
                    val padTop = if (userInterestedGame) 0 else 16F.dip2px()
                    root.setPadding(16F.dip2px(), padTop, 16F.dip2px(), 16F.dip2px())
                    root.setBackgroundColor(com.gh.gamecenter.common.R.color.ui_surface.toColor(mContext))
                    interestedGameTv.goneIf(!userInterestedGame) {
                        interestedGameTv.text = mContext.getString(R.string.interested_game_footer_hint).fromHtml()
                        interestedGameTv.setOnClickListener {
                            SensorsBridge.trackGameExploreClick(
                                "偏好设置",
                                "详情页",
                            )
                            mContext.ifLogin("发现页-底部") {
                                mFragment.startActivityForResult(
                                    InterestedGameActivity.getIntent(
                                        mContext,
                                        "发现页-底部"
                                    ),
                                    INTERESTED_GAME_REQUEST_CODE
                                )
                                NewFlatLogUtils.logInterestedGameClick("发现页底部")
                            }
                        }
                    }
                    recommendIv.setOnClickListener {

                        val blockData = HomeBottomBarHelper.getDefaultGameBarData()
                        SensorsBridge.trackGameExploreClick(
                            "内容标签",
                            "详情页",
                            linkType = blockData.type ?: "",
                            linkId = blockData.link ?: "",
                            linkText = blockData.text ?: ""
                        )
                        mContext.startActivity(
                            BlockActivity.getIntent(
                                mContext,
                                blockData,
                                mBaseExposureSource,
                                mEntrance
                            )
                        )
                        NewFlatLogUtils.logDiscoverPageJumpGamesLibraries()
                    }
                }
            }

            is FooterViewHolder -> {
                holder.initFooterViewHolder(mIsLoading, mIsNetworkError, mIsOver)
            }
        }
    }

    private fun logDiscoverPageRecommendedInterestCardClick(
        position: Int?,
        label: DiscoveryGameCardLabel
    ) {
        if (position == null) return
        NewFlatLogUtils.logDiscoverPageRecommendedInterestCardClick(
            position,
            label.text ?: "",
            label.type ?: "",
            label.link ?: "",
            "发现详情页"
        )
    }

    override fun getItemCount(): Int {
        return if (mEntityList == null || mEntityList.isEmpty()) return 0 else mEntityList.size + 1
    }

    fun notifyItemByDownload(download: DownloadEntity) {
        val positionAndPackageMap = mViewModel.positionAndPackageMap
        for (key in positionAndPackageMap.keys) {
            if (key.contains(download.packageName)) {
                val position = positionAndPackageMap[key]
                if (position != null && mEntityList != null && position < mEntityList.size) {
                    mEntityList[position].gameEntity?.let {
                        it.getEntryMap()[download.platform] = download
                    }
                    notifyItemChanged(position)
                }
            }
        }
    }

    fun notifyItemAndRemoveDownload(status: EBDownloadStatus) {
        val positionAndPackageMap = mViewModel.positionAndPackageMap
        for (key in positionAndPackageMap.keys) {
            if (key.contains(status.packageName)) {
                val position = positionAndPackageMap[key]
                if (position != null && mEntityList != null && position < mEntityList.size) {
                    mEntityList[position].gameEntity?.let {
                        it.getEntryMap().remove(status.platform)
                    }
                    notifyItemChanged(position)
                }
            }
        }
    }

    fun clearPositionAndPackageMap() {
        mViewModel.positionAndPackageMap.clear()
    }

    override fun getEventByPosition(pos: Int): ExposureEvent? {
        return mExposureEventSparseArray.get(pos)
    }

    override fun getEventListByPosition(pos: Int): List<ExposureEvent>? {
        return null
    }

    class DiscoveryGameViewHolder(val binding: DiscoveryGameItemBinding) : GameViewHolder(binding.root), IExposureProvider {
        private var boundedGameEntity: GameEntity? = null

        init {
            gameDownloadBtn = binding.downloadBtn
            gameDes = binding.gameDes
            gameRating = binding.gameRating
            recommendContainer = binding.recommendContainer
            recommendIv = binding.recommendIv
            multiVersionDownloadTv = binding.multiVersionDownloadTv
            gameDownloadTips = binding.downloadTipsLottie
        }

        fun bindGameItem(gameEntity: GameEntity) {
            boundedGameEntity = gameEntity
            binding.run {
                root.background = com.gh.gamecenter.common.R.drawable.reuse_listview_item_style.toDrawable(root.context)
                gameKaifuType.setBackgroundColor(com.gh.gamecenter.common.R.color.primary_theme.toColor(root.context))
                gameName.setTextColor(com.gh.gamecenter.common.R.color.text_primary.toColor(root.context))
                gameDes.setTextColor(com.gh.gamecenter.common.R.color.text_tertiary.toColor(root.context))

                gameIconView.displayGameIcon(gameEntity)
                gameRating.textSize = if (gameEntity.commentCount > 3) 12F else 10F
                BindingAdapters.setGameName(gameName, gameEntity, false)
                gameRating.setDrawableStart(if (gameEntity.commentCount > 3) com.gh.gamecenter.feature.R.drawable.game_horizontal_rating.toDrawable() else null)
                gameRating.text = if (gameEntity.commentCount > 3) {
                    if (gameEntity.star == 10.0F) "10" else gameEntity.star.toString()
                } else {
                    ""
                }
                gameRating.setPadding(0, 0, if (gameEntity.commentCount > 3) 8F.dip2px() else 0, 0)
                gameRating.setTextColor(
                    if (gameEntity.commentCount > 3) {
                        com.gh.gamecenter.common.R.color.text_theme.toColor(binding.root.context)
                    } else {
                        com.gh.gamecenter.common.R.color.primary_theme.toColor(binding.root.context)
                    }
                )
                gameDes.visibleIf(gameEntity.recommendTag.isNotEmpty()) {
                    gameDes.text = "根据 “${gameEntity.recommendTag}” 兴趣推荐"
                }
                if (gameEntity.type == "ad" && gameEntity.adIconActive) {
                    recommendReasonTv.visibility = View.GONE
                } else {
                    recommendReasonTv.visibility = View.GONE
                    if (gameEntity.columnRank != null) {
                        recommendReasonTv.text =
                            "${gameEntity.columnRank!!.name}·第${gameEntity.columnRank!!.position}名"
                        recommendReasonTv.setTextColor(com.gh.gamecenter.common.R.color.secondary_yellow.toColor(binding.root.context))
                        recommendReasonTv.setDrawableStart(R.drawable.ic_discovery_rank)
                        recommendReasonTv.background =
                            R.drawable.bg_discovery_recommend.toDrawable(binding.root.context)
                        recommendReasonTv.visibility = View.VISIBLE
                    } else if (gameEntity.type == "recommend") {
                        recommendReasonTv.text = "其他玩家推荐"
                        recommendReasonTv.setTextColor(com.gh.gamecenter.common.R.color.text_theme.toColor(binding.root.context))
                        recommendReasonTv.removeDrawable()
                        recommendReasonTv.background = R.drawable.bg_discovery_rank.toDrawable(binding.root.context)
                        recommendReasonTv.visibility = View.VISIBLE
                    }
                }
                //type: recommend 专题游戏 | ad 广告游戏 | filter 算法游戏
                GameItemViewHolder.initGameSubtitleAndAdLabel(
                    gameEntity,
                    gameSubtitleTv,
                    gameNameContainer,
                    gameName,
                    gameEntity.type == "ad" && gameEntity.adIconActive,
                    adLabelTv
                )
            }
        }

        override fun provideExposureData(): ExposureEvent? {
            return boundedGameEntity?.exposureEvent?.getFreshExposureEvent()
        }
    }

    class RecommendInterestViewHolder(val binding: ItemRecommendInterestBinding) :
        BaseRecyclerViewHolder<Any>(binding.root)

    class RecommendInterestImageViewHolder(val binding: ItemRecommendInterestImageBinding) :
        BaseRecyclerViewHolder<Any>(binding.root)

    class DirectGameBlockViewHolder(val binding: ItemRecommendInterestFooterBinding) :
        BaseRecyclerViewHolder<Any>(binding.root)

    companion object {
        const val ITEM_RECOMMEND_INTEREST = 200
        const val ITEM_RECOMMEND_INTEREST_IMAGE = 201
        const val ITEM_DIRECT_GAME_BLOCK = 202
    }
}