package com.gh.gamecenter.search

import android.content.Context
import android.util.SparseArray
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.LinearLayout
import androidx.collection.ArrayMap
import androidx.core.content.ContextCompat
import androidx.core.view.isVisible
import androidx.recyclerview.widget.RecyclerView
import com.gh.ad.AdDelegateHelper
import com.gh.common.databind.BindingAdapters
import com.gh.common.filter.RegionSettingHelper
import com.gh.common.util.*
import com.gh.common.util.LogUtils
import com.gh.common.util.NewFlatLogUtils
import com.gh.common.util.NewLogUtils
import com.gh.gamecenter.GameDetailActivity
import com.gh.gamecenter.R
import com.gh.gamecenter.SearchActivity
import com.gh.gamecenter.SearchType
import com.gh.gamecenter.adapter.viewholder.GameViewHolder
import com.gh.gamecenter.adapter.viewholder.SearchGameFooterViewHolder
import com.gh.gamecenter.common.base.GlobalActivityManager
import com.gh.gamecenter.common.baselist.ListAdapter
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.constant.ItemViewType
import com.gh.gamecenter.common.entity.SimpleGameEntity
import com.gh.gamecenter.common.entity.SuggestType
import com.gh.gamecenter.common.exposure.ExposureSource
import com.gh.gamecenter.common.json.json
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.common.viewholder.FooterViewHolder
import com.gh.gamecenter.core.runOnIoThread
import com.gh.gamecenter.core.utils.DisplayUtils
import com.gh.gamecenter.core.utils.SPUtils
import com.gh.gamecenter.core.utils.StringUtils
import com.gh.gamecenter.databinding.*
import com.gh.gamecenter.db.ISearchHistoryDao
import com.gh.gamecenter.eventbus.EBDownloadStatus
import com.gh.gamecenter.eventbus.EBSearch
import com.gh.gamecenter.eventbus.EBStartupAcceleration
import com.gh.gamecenter.feature.entity.AcctGameInfo
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.feature.exposure.ExposureEvent
import com.gh.gamecenter.feature.exposure.ExposureType
import com.gh.gamecenter.feature.game.GameItemViewHolder
import com.gh.gamecenter.feature.minigame.MiniGameItemHelper
import com.gh.gamecenter.feature.view.DownloadButton
import com.gh.gamecenter.gamedetail.accelerator.GameDetailAcceleratorUiHelper.Companion.DISTRICT_SERVER_EMPTY
import com.gh.gamecenter.gamedetail.accelerator.GameDetailAcceleratorUiHelper.Companion.DISTRICT_SERVER_HAVA
import com.gh.gamecenter.gamedetail.accelerator.GameDetailAcceleratorUiHelper.Companion.SCENE_TYPE_NO_GUIDE_LAYER
import com.gh.gamecenter.gamedetail.accelerator.GameDetailAcceleratorUiHelper.Companion.SOURCE_ENTRANCE_SEARCH
import com.gh.gamecenter.gamedetail.accelerator.chain.AcceleratorClient
import com.gh.gamecenter.gamedetail.accelerator.chain.AcceleratorValidator
import com.gh.gamecenter.gamedetail.accelerator.dialog.AcceleratorZoneDialogFragment
import com.gh.gamecenter.gamedetail.accelerator.dialog.StartingAcceleratorDialogFragment
import com.gh.gamecenter.gamedetail.entity.GameDetailTabEntity
import com.gh.gamecenter.help.HelpAndFeedbackBridge
import com.gh.gamecenter.minigame.MiniGameSearchResultFragment
import com.halo.assistant.accelerator.repository.AcceleratorDataHolder
import com.lightgame.download.DownloadEntity
import com.lightgame.utils.Util_System_Keyboard
import org.greenrobot.eventbus.EventBus
import kotlin.collections.set

class SearchGameResultAdapter(
    context: Context,
    val fragment: SearchGameResultFragment,
    private val dao: ISearchHistoryDao,
    val listViewModel: SearchGameResultViewModel,
    val entrance: String,
    var type: String,
    val sourceEntrance: String
) : ListAdapter<SearchItemData>(context) {

    private var searchMap: ArrayMap<String, String> = ArrayMap()
    private var _recyclerView: RecyclerView? = null
    private var gameIdBeingAccelerated = ""

    var key: String = ""

    val positionAndPackageMap = HashMap<String, Int>()

    private val adIdSet = hashSetOf<String>() // 记录展示过的广告id

    private val isNormalGameSearchPage: Boolean
        get() = fragment !is MiniGameSearchResultFragment

    fun clearAdIdSet() {
        adIdSet.clear()
    }

    override fun setListData(updateData: MutableList<SearchItemData>?) {
        gameIdBeingAccelerated = AcceleratorDataHolder.instance.getAcceleratingGameId()
        // 记录游戏位置
        if (updateData != null) {
            positionAndPackageMap.clear()
            for (i in 0 until updateData.size) {
                val gameEntity = updateData[i].game
                if (gameEntity != null) {
                    var packages = gameEntity.id
                    for (apkEntity in gameEntity.getApk()) {
                        packages += apkEntity.packageName
                    }
                    gameEntity.sequence = i
                    positionAndPackageMap[packages + i] = i

                    if (RegionSettingHelper.shouldGameOfThisCategoryUseMirrorInfo(
                            gameEntity.category ?: ""
                        )
                    ) {
                        gameEntity.useMirrorInfo = true
                    }
                } else if (updateData[i].subject != null) {
                    updateData[i].subject!!.games.forEach { game ->
                        var packages = game.id
                        for (apkEntity in game.getApk()) {
                            packages += apkEntity.packageName
                        }
                        positionAndPackageMap[packages + i] = i
                    }
                }
            }
        }
        super.setListData(updateData)
    }

    override fun areItemsTheSame(oldItem: SearchItemData?, newItem: SearchItemData?): Boolean {
        return when {
            oldItem?.subject != null && newItem?.subject != null -> {
                oldItem.subject.columnId == newItem.subject.columnId
                        && oldItem.subject.games == newItem.subject.games
            }

            oldItem?.game != null && newItem?.game != null -> {
                oldItem.game == newItem.game
            }

            else -> super.areItemsTheSame(oldItem, newItem)
        }
    }

    override fun areContentsTheSame(oldItem: SearchItemData?, newItem: SearchItemData?): Boolean {
        return when {
            oldItem?.subject != null && newItem?.subject != null -> {
                oldItem.subject.columnId == newItem.subject.columnId
                        && oldItem.subject.games == newItem.subject.games
            }

            oldItem?.game != null && newItem?.game != null -> {
                oldItem.game == newItem.game
            }

            else -> super.areContentsTheSame(oldItem, newItem)
        }
    }

    override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
        return when (viewType) {
            ItemViewType.GAME_SUBJECT -> {
                val itemView = mLayoutInflater.inflate(R.layout.search_subject_item, viewGroup, false)
                SearchSubjectItemViewHolder(SearchSubjectItemBinding.bind(itemView))
            }

            ITEM_GAME_FIRST -> {
                val binding = SearchGameFirstItemBinding.inflate(mLayoutInflater, viewGroup, false)
                SearchGameFirstItemViewHolder(
                    type,
                    searchMap,
                    entrance,
                    sourceEntrance,
                    fragment,
                    binding,
                    dao
                )
            }

            ItemViewType.ITEM_BODY -> {
                val itemView = mLayoutInflater.inflate(R.layout.search_game_index_item, viewGroup, false)
                SearchGameIndexItemViewHolder(SearchGameIndexItemBinding.bind(itemView))
            }

            ITEM_AD -> {
                val itemView = mLayoutInflater.inflate(R.layout.search_game_ad_item, viewGroup, false)
                SearchGameAdItemViewHolder(SearchGameAdItemBinding.bind(itemView))
            }

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

            else -> {
                val view = mLayoutInflater.inflate(R.layout.search_game_footer, viewGroup, false)
                SearchGameFooterViewHolder(SearchGameFooterBinding.bind(view))
            }
        }
    }

    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
        when (holder) {
            is SearchSubjectItemViewHolder -> {
                val itemData = mEntityList[position]
                if (itemData.subject == null || itemData.subject.games.isEmpty()) {
                    holder.binding.topDivider.visibility = View.GONE
                    holder.binding.bottomDivider.visibility = View.GONE
                    holder.binding.headContainer.root.visibility = View.GONE
                    holder.binding.subjectRv.visibility = View.GONE
                } else {
                    holder.binding.headContainer.root.visibility = View.VISIBLE
                    holder.binding.subjectRv.visibility = View.VISIBLE

                    holder.binding.run {
                        when {
                            position == 0 -> topDivider.visibility = View.GONE
                            position > 0 -> {
                                val gameEntity = mEntityList[position - 1].game
                                if (gameEntity != null) {
                                    val isShowTag = gameEntity.contentTag != null
                                            && (gameEntity.contentTag!!.custom.isNotEmpty()
                                            || gameEntity.contentTag!!.zone.link.isNotEmpty()
                                            || gameEntity.contentTag!!.isLibaoExists
                                            || gameEntity.contentTag!!.server)
                                    val isShowTagByMirror =
                                        if (gameEntity.shouldUseMirrorInfo()) isShowTag && gameEntity.obtainMirrorData()?.contentTagStatus == "on" else isShowTag
                                    if (isShowTagByMirror) {
                                        topDivider.visibility = View.GONE
                                    } else {
                                        topDivider.visibility = View.VISIBLE
                                    }
                                } else {
                                    topDivider.visibility = View.GONE
                                }
                            }
                        }
                        bottomDivider.visibility = View.VISIBLE
                    }
                    holder.bindSubjectItem(
                        mContext,
                        itemData,
                        SearchType.fromString(type).toChinese(),
                        key,
                        dao,
                        sourceEntrance = sourceEntrance
                    )
                }
            }

            is SearchGameFirstItemViewHolder -> {
                val item = mEntityList[position]
                val gameEntity = item.game
                gameEntity ?: return
                holder.bind(key, item) { exposureEvent ->
                    setDownloadBtn(
                        entrance,
                        type,
                        key,
                        searchMap,
                        exposureEvent,
                        position,
                        holder.binding.gameItemIncluded,
                        item,
                        mContext,
                        this,
                        sourceEntrance
                    )
                }
            }

            is SearchGameIndexItemViewHolder -> {
//                val padTop= if (position == 0) 16F.dip2px() else 12F.dip2px()
//                holder.itemView.setPadding(16F.dip2px(), padTop, 16F.dip2px(), 12F.dip2px())
                bindGameItem(holder)
            }

            is SearchGameAdItemViewHolder -> {
                val adEntity = mEntityList[position].ad
                val adConfig = mEntityList[position].adConfig
                val slotId = adEntity?.slotId ?: ""
                val adContainer = holder.binding.adContainer
                val screenWidthInDp = DisplayUtils.getScreenWidthInDp(fragment.activity)

                if (adContainer.tag == slotId) {
                    // 广告 slotId 没有变，不管它
                } else {
                    adContainer.tag = slotId
                    val onAdShowAction: () -> Unit = {
                        if (!adIdSet.contains(adConfig?.id)) {
                            SensorsBridge.trackEvent("ThirdPartyAdShow",
                                json {
                                    "ad_source" to adEntity?.sourceName
                                    "ad_id" to slotId
                                    "ad_format" to adConfig?.typeChinese
                                    "ad_placement" to "搜索结果"
                                    "ad_space_id" to adConfig?.id
                                    "ad_space_name" to adConfig?.name
                                    "position" to adConfig?.position
                                }
                            )
                        }
                        adIdSet.add(adConfig?.id ?: "")
                    }
                    val onAdClickAction = {
                        SensorsBridge.trackEvent("ThirdPartyAdClick",
                            json {
                                "ad_source" to adEntity?.sourceName
                                "ad_id" to slotId
                                "ad_format" to adConfig?.typeChinese
                                "ad_placement" to "搜索结果"
                                "ad_space_id" to adConfig?.id
                                "ad_space_name" to adConfig?.name
                                "position" to adConfig?.position
                            }
                        )
                    }
                    AdDelegateHelper.requestThirdPartyFlowAd(
                        fragment,
                        slotId,
                        adContainer,
                        screenWidthInDp,
                        onAdShowAction,
                        onAdClickAction
                    ) {

                    }
                }
            }

            is FooterViewHolder -> holder.initFooterViewHolder(listViewModel, mIsLoading, mIsNetworkError, mIsOver)
            is SearchGameFooterViewHolder -> bindFooterItem(holder)
        }
    }

    override fun onAttachedToRecyclerView(recyclerView: RecyclerView) {
        super.onAttachedToRecyclerView(recyclerView)
        _recyclerView = recyclerView
    }

    override fun onDetachedFromRecyclerView(recyclerView: RecyclerView) {
        super.onDetachedFromRecyclerView(recyclerView)
        _recyclerView = null
        recyclerView.clearOnScrollListeners()
    }

    override fun onViewAttachedToWindow(holder: RecyclerView.ViewHolder) {
        super.onViewAttachedToWindow(holder)
        when (holder) {
            is SearchGameFirstItemViewHolder -> {
                holder.onAttach(_recyclerView)
            }
        }
    }

    override fun onViewDetachedFromWindow(holder: RecyclerView.ViewHolder) {
        super.onViewDetachedFromWindow(holder)
        if (holder is SearchGameFirstItemViewHolder) {
            holder.onDetach(_recyclerView)
        }
    }

    private fun bindFooterItem(holder: SearchGameFooterViewHolder) {
        holder.binding.skipFunction.setOnClickListener {
            LogUtils.uploadSearchGame("ask_more_func", " 搜索页", key, SearchType.fromString(type).toChinese())
            HelpAndFeedbackBridge.startSuggestionActivity(mContext, SuggestType.FUNCTION, "", "求功能：$key")
        }
        holder.binding.skipGame.setOnClickListener {
            LogUtils.uploadSearchGame("ask_more_games", " 搜索页", key, SearchType.fromString(type).toChinese())
            HelpAndFeedbackBridge.startSuggestionActivity(
                mContext,
                SuggestType.UPDATE,
                null,
                null,
                SimpleGameEntity(name = key)
            )
        }
        fragment.showAd(holder.binding.hintText, true)
    }

    private fun bindGameItem(holder: SearchGameIndexItemViewHolder) {
        val binding = holder.binding
        val item = mEntityList[holder.bindingAdapterPosition]
        val gameEntity = item.game ?: return

        holder.bindData(gameEntity)
        binding.gameItemIncluded.run {
            gameIconView.displayGameIcon(gameEntity)
            gameRating.textSize = if (gameEntity.commentCount > 3) 12F else 10F
            BindingAdapters.setGameName(gameName, gameEntity, false)
            BindingAdapters.setGameTags(labelList, gameEntity, "")
            gameRating.setDrawableStart(if (gameEntity.commentCount > 3) com.gh.gamecenter.feature.R.drawable.game_horizontal_rating.toDrawable() else null)
            gameRating.setPadding(0, 0, if (gameEntity.commentCount > 3) 8F.dip2px() else 0, 0)
            gameRating.text = if (gameEntity.commentCount > 3) {
                if (gameEntity.star == 10.0F) "10" else gameEntity.star.toString()
            } else ""
            gameRating.setTextColor(
                if (gameEntity.commentCount > 3) {
                    com.gh.gamecenter.common.R.color.text_theme.toColor(mContext)
                } else {
                    com.gh.gamecenter.common.R.color.primary_theme.toColor(
                        mContext
                    )
                }
            )
            gameDes.text = gameEntity.decoratedDes
            recommendStar.rating = gameEntity.recommendStar.toFloat()
            GameItemViewHolder.initGameSubtitleAndAdLabel(
                gameEntity,
                gameSubtitleTv,
                gameNameContainer,
                gameName,
                gameEntity.adIconActive,
                adLabelTv
            )
            MiniGameItemHelper.setMiniGameUsage(gamePlayCount, gameEntity)
            officialEntryIv.isVisible = gameEntity.officialEntry
        }
        binding.gameItemIncluded.root.setPadding(16F.dip2px(), 0, 16F.dip2px(), 0)
        SearchGameIndexItemViewHolder.initServerType(gameEntity, binding.gameItemIncluded)

        val exposureSources = ArrayList<ExposureSource>()
        exposureSources.add(ExposureSource("首页搜索", ""))
        // ~~曝光去掉搜索关键字避免出现很多路径附带~~ #734 又恢复了
        exposureSources.add(ExposureSource(SearchType.fromString(type).toChinese(), key))
        val exposureEvent = ExposureEvent.createEvent(
            gameEntity,
            exposureSources, null,
            ExposureType.EXPOSURE
        )
        exposureEvent.payload.searchContent = key

        runOnIoThread(isLightWeightTask = true) {
            if (!gameEntity.adGroupId.isEmpty() && !gameEntity.isAdRequestReported) {
                AdHelper.reportAdRequest(exposureEvent)
                gameEntity.isAdRequestReported = true
            }
        }

        binding.run {
            val isShowTag = gameEntity.contentTag != null
                    && (gameEntity.contentTag!!.custom.isNotEmpty()
                    || gameEntity.contentTag!!.zone.link.isNotEmpty()
                    || gameEntity.contentTag!!.isLibaoExists
                    || gameEntity.contentTag!!.server
                    || gameEntity.contentTag!!.isBbsExists)
            val isShowTagByMirror =
                if (gameEntity.shouldUseMirrorInfo()) isShowTag && gameEntity.obtainMirrorData()?.contentTagStatus == "on" else isShowTag
            tagContainer.goneIf(!isShowTagByMirror)
            if (isShowTagByMirror && gameEntity.contentTag != holder.contentTag) {
                holder.contentTag = gameEntity.contentTag
                bottomDivider.visibility = View.VISIBLE
                showContentTag(
                    entrance,
                    type,
                    key,
                    holder.bindingAdapterPosition,
                    exposureEvent,
                    gameEntity,
                    tagContainer,
                    sourceEntrance,
                    item.gamePosition
                )
            } else {
                bottomDivider.visibility = View.GONE
            }
        }

        binding.root.setOnClickListener {
            dao.add(key)
            setItemCLick(
                entrance,
                type,
                key,
                searchMap,
                exposureEvent,
                item,
                holder.bindingAdapterPosition,
                mContext,
                sourceEntrance
            )
        }

        setDownloadBtn(
            entrance,
            type,
            key,
            searchMap,
            exposureEvent,
            holder.bindingAdapterPosition,
            binding.gameItemIncluded,
            item,
            mContext,
            this,
            sourceEntrance
        )
    }

    override fun getItemViewType(position: Int): Int {
        if (position > itemCount) ItemViewType.ITEM_BODY

        return if (position == itemCount - 1) {
            if (mIsOver) {
                ITEM_SEARCH_FOOTER
            } else {
                ItemViewType.ITEM_FOOTER
            }
        } else {
            val data = mEntityList[position]
            when {
                data.subject != null -> ItemViewType.GAME_SUBJECT
                data.ad != null -> ITEM_AD
                data.isShowFirstSetting -> ITEM_GAME_FIRST
                else -> ItemViewType.ITEM_BODY
            }
        }
    }

    override fun getItemCount(): Int {
        return if (mEntityList.isNotEmpty()) mEntityList.size + FOOTER_ITEM_COUNT else 0
    }

    fun notifyItemByDownload(download: DownloadEntity) {
        for (key in positionAndPackageMap.keys) {
            if (key.contains(download.packageName) && key.contains(download.gameId)) {
                val position = positionAndPackageMap[key]
                if (position != null && position < itemCount && getItemViewType(position) == ItemViewType.GAME_SUBJECT) {
                    val view = _recyclerView?.layoutManager?.findViewByPosition(position)
                    val adapter = view?.findViewById<RecyclerView>(R.id.subjectRv)?.adapter
                    if (adapter != null && adapter is SearchSubjectAdapter) {
                        adapter.notifyItemByDownload(download)
                    }
                } else if (position != null && mEntityList != null && position < mEntityList.size && mEntityList[position].game != null) {
                    DownloadItemUtils.processDate(mEntityList[position].game!!, download, this, position)
                }
            }
        }
    }

    fun notifyItemAndRemoveDownload(status: EBDownloadStatus) {
        for (key in positionAndPackageMap.keys) {
            if (key.contains(status.packageName) && key.contains(status.gameId)) {
                val position = positionAndPackageMap[key]
                if (position != null && getItemViewType(position) == ItemViewType.GAME_SUBJECT) {
                    val view = _recyclerView?.layoutManager?.findViewByPosition(position)
                    val adapter = view?.findViewById<RecyclerView>(R.id.subjectRv)?.adapter
                    if (adapter != null && adapter is SearchSubjectAdapter) {
                        adapter.notifyChildItem(status.packageName)
                    }
                } else if (position != null && mEntityList != null && position < mEntityList.size && mEntityList[position].game != null) {
                    mEntityList[position].game!!.getEntryMap().remove(status.platform)
                    notifyItemChanged(position)
                }
            }
        }
    }

    fun notifyItemAndStartupAcceleration(acctGameInfo: EBStartupAcceleration) {
        if (isNormalGameSearchPage) {
            positionAndPackageMap.keys.forEach {
                if (it.contains(acctGameInfo.acctGameInfo.gameId)) {
                    val position = positionAndPackageMap[it]
                    if (position != null && mEntityList != null && position < mEntityList.size && mEntityList[position].game != null) {
                        mEntityList[position].game!!.lastAcctGame = acctGameInfo.acctGameInfo
                        notifyItemChanged(position)
                    }
                }
            }
        }
    }

    fun notifyItemAccelerationState() {
        val lastGameId = gameIdBeingAccelerated
        val currentGameId = AcceleratorDataHolder.instance.getAcceleratingGameId()
        gameIdBeingAccelerated = currentGameId

        fun refreshAccelerationState(gameId: String) {
            positionAndPackageMap.keys.forEach {
                if (it.contains(gameId)) {
                    val position = positionAndPackageMap[it]
                    if (position != null && mEntityList != null && position < mEntityList.size && mEntityList[position].game != null) {
                        notifyItemChanged(position)
                    }
                }
            }
        }
        if (lastGameId.isNotBlank()) {
            refreshAccelerationState(lastGameId)
        }
        if (currentGameId.isNotBlank()) {
            refreshAccelerationState(currentGameId)
        }
    }

    fun isLoadOver(): Boolean {
        return mIsOver
    }

    companion object {
        private const val ITEM_SEARCH_FOOTER = 109
        private const val ITEM_AD = 923
        private const val ITEM_GAME_FIRST = 924

        fun showContentTag(
            entrance: String,
            type: String,
            key: String,
            position: Int,
            exposureEvent: ExposureEvent,
            gameEntity: GameEntity,
            tagContainer: LinearLayout,
            sourceEntrance: String,
            gamePosition: Int
        ) {
            val context = tagContainer.context
            val layoutInflater = LayoutInflater.from(context)
            val screenWidth = context.resources.displayMetrics.widthPixels
            val tagWidth = (screenWidth - (16F * 2 + 8F * 3).dip2px()) / 4
            tagContainer.removeAllViews()
            run outside@{
                gameEntity.contentTag!!.custom.forEach {
                    val customView = getContentTagView(
                        -1,
                        it.icon.url,
                        it.text,
                        tagWidth,
                        if (tagContainer.childCount == 3) 0 else 8F.dip2px(),
                        layoutInflater
                    ) { view ->
                        DirectUtils.directToLinkPage(
                            context,
                            it.link,
                            entrance,
                            "",
                            "${sourceEntrance}搜索-搜索结果-内容标签"
                        )

                        gameEntity.run {
                            NewLogUtils.logSearchTagClick(
                                SearchType.fromString(type).toChinese(),
                                key,
                                id,
                                name ?: "",
                                it.id,
                                it.text,
                                it.link.link ?: "",
                                it.link.type ?: "",
                                it.link.text ?: ""
                            )
                            SensorsBridge.trackEvent("GameSearchContentLabelClick", json {
                                "game_id" to id
                                "game_name" to name
                                "game_position" to gamePosition
                                "link_position" to tagContainer.indexOfChild(view)
                                "link_type" to it.link.type
                                "link_id" to it.link.link
                                "link_text" to it.link.text
                                "button_name" to it.text
                            })
                        }
                    }

                    tagContainer.addView(customView)
                    if (tagContainer.childCount >= 4) return@outside
                }
            }

            if (tagContainer.childCount < 4 && gameEntity.contentTag!!.zone.link.isNotEmpty()) {
                val zoneView = getContentTagView(
                    R.drawable.ic_label_zone,
                    "",
                    gameEntity.contentTag!!.zone.customName.ifEmpty { "攻略" },
                    tagWidth,
                    if (tagContainer.childCount == 3) 0 else 8F.dip2px(),
                    layoutInflater
                ) {
                    GameDetailActivity.startGameDetailActivity(
                        context, gameEntity,
                        StringUtils.buildString(
                            entrance, "+(搜索-列表[", key, "=", "$type=",
                            (position + 1).toString(), "])"
                        ), GameDetailTabEntity.TYPE_ZONE, traceEvent = exposureEvent
                    )

                    gameEntity.run {
                        NewLogUtils.logSearchTagClick(
                            SearchType.fromString(type).toChinese(),
                            key,
                            id,
                            name ?: "",
                            "",
                            "攻略",
                        )
                        SensorsBridge.trackEvent("GameSearchContentLabelClick", json {
                            "game_id" to id
                            "game_name" to name
                            "game_position" to gamePosition
                            "link_position" to tagContainer.indexOfChild(it)
                            "button_name" to gameEntity.contentTag!!.zone.customName.ifEmpty { "攻略" }
                        })
                    }
                }
                tagContainer.addView(zoneView)
            }

            if (tagContainer.childCount < 4 && gameEntity.contentTag!!.isLibaoExists) {
                val libaoView = getContentTagView(
                    R.drawable.ic_label_libao,
                    "",
                    "礼包",
                    tagWidth,
                    if (tagContainer.childCount == 3) 0 else 8F.dip2px(),
                    layoutInflater
                ) {
                    GameDetailActivity.startGameDetailActivity(
                        context, gameEntity,
                        StringUtils.buildString(
                            entrance, "+(搜索-列表[", key, "=", "$type=",
                            (position + 1).toString(), "])"
                        ), scrollToLibao = true, traceEvent = exposureEvent
                    )

                    gameEntity.run {
                        NewLogUtils.logSearchTagClick(
                            SearchType.fromString(type).toChinese(),
                            key,
                            id,
                            name ?: "",
                            "",
                            "礼包",
                        )
                        SensorsBridge.trackEvent("GameSearchContentLabelClick", json {
                            "game_id" to id
                            "game_name" to name
                            "game_position" to gamePosition
                            "link_position" to tagContainer.indexOfChild(it)
                            "button_name" to "礼包"
                        })
                    }
                }
                tagContainer.addView(libaoView)
            }

            if (tagContainer.childCount < 4 && gameEntity.contentTag!!.isBbsExists && !gameEntity.shouldUseMirrorInfo()) {
                val serverView = getContentTagView(
                    R.drawable.ic_label_bbs,
                    "",
                    "论坛",
                    tagWidth,
                    if (tagContainer.childCount == 3) 0 else 8F.dip2px(),
                    layoutInflater
                ) {
                    GameDetailActivity.startGameDetailActivity(
                        context, gameEntity,
                        StringUtils.buildString(
                            entrance, "+(搜索-列表[", key, "=", "$type=",
                            (position + 1).toString(), "])"
                        ), GameDetailTabEntity.TYPE_BBS, traceEvent = exposureEvent
                    )

                    gameEntity.run {
                        NewLogUtils.logSearchTagClick(
                            SearchType.fromString(type).toChinese(),
                            key,
                            id,
                            name ?: "",
                            "",
                            "论坛",
                        )
                        SensorsBridge.trackEvent("GameSearchContentLabelClick", json {
                            "game_id" to id
                            "game_name" to name
                            "game_position" to gamePosition
                            "link_position" to tagContainer.indexOfChild(it)
                            "button_name" to "论坛"
                        })
                    }
                }
                tagContainer.addView(serverView)
            }

            if (tagContainer.childCount < 4 && gameEntity.contentTag!!.server) {
                if (!gameEntity.shouldUseMirrorInfo() || (gameEntity.shouldUseMirrorInfo() && gameEntity.obtainMirrorData()?.mirrorServer?.calendar?.isNotEmpty() == true)) {
                    val serverView = getContentTagView(
                        R.drawable.ic_label_server,
                        "",
                        "开服表",
                        tagWidth,
                        if (tagContainer.childCount == 3) 0 else 8F.dip2px(),
                        layoutInflater
                    ) {
                        GameDetailActivity.startGameDetailActivity(
                            context, gameEntity,
                            StringUtils.buildString(
                                entrance, "+(搜索-列表[", key, "=", "$type=",
                                (position + 1).toString(), "])"
                            ), scrollToServer = true, traceEvent = exposureEvent
                        )

                        gameEntity.run {
                            NewLogUtils.logSearchTagClick(
                                SearchType.fromString(type).toChinese(),
                                key,
                                id,
                                name ?: "",
                                "",
                                "开服表",
                            )
                            SensorsBridge.trackEvent("GameSearchContentLabelClick", json {
                                "game_id" to id
                                "game_name" to name
                                "game_position" to gamePosition
                                "link_position" to tagContainer.indexOfChild(it)
                                "button_name" to "开服表"
                            })
                        }
                    }
                    tagContainer.addView(serverView)
                }
            }

        }

        fun setItemCLick(
            entrance: String,
            type: String,
            key: String,
            searchMap: ArrayMap<String, String>,
            exposureEvent: ExposureEvent,
            item: SearchItemData,
            position: Int,
            context: Context,
            sourceEntrance: String
        ) {
            val gameEntity = item.game ?: return
            if (searchMap[gameEntity.id] == null) {
                EventBus.getDefault().post(EBSearch("search", gameEntity.id, gameEntity.name))
                searchMap[gameEntity.id] = gameEntity.name
            } else {
                EventBus.getDefault().post(EBSearch("click", gameEntity.id, gameEntity.name))
            }

            if (gameEntity.isMiniGame()) {
                SensorsBridge.trackMiniGameSearchResultClick(
                    GlobalActivityManager.getCurrentPageEntity().pageId,
                    GlobalActivityManager.getCurrentPageEntity().pageName,
                    sourceEntrance,
                    key,
                    SearchActivity.toTrackSearchType(type),
                    gameEntity.id,
                    gameEntity.name ?: "",
                    gameEntity.categoryChinese,
                    position
                )
                MiniGameItemHelper.launchMiniGame(gameEntity)
                MiniGameItemHelper.trackMiniGameClick(
                    gameEntity = gameEntity,
                    location = "小游戏搜索结果列表",
                    searchContent = key,
                )
            } else {
                SensorsBridge.trackGameSearchResultClick(
                    GlobalActivityManager.getCurrentPageEntity().pageId,
                    GlobalActivityManager.getCurrentPageEntity().pageName,
                    sourceEntrance,
                    key,
                    SearchActivity.toTrackSearchType(type),
                    gameEntity.id,
                    gameEntity.name ?: "",
                    gameEntity.categoryChinese,
                    position,
                    gameEntity.adGroupId
                )
                GameDetailActivity.startGameDetailActivity(
                    context, gameEntity,
                    StringUtils.buildString(
                        entrance, "+(搜索-列表[", key, "=", type, "=",
                        (position + 1).toString(), "])"
                    ),
                    traceEvent = exposureEvent
                )
            }

            LogUtils.uploadSearchClick(
                "search_click",
                "搜索页",
                key,
                SearchType.fromString(type).toChinese(),
                gameEntity.id,
                gameEntity.name,
                gameEntity.getMirrorPosition(),
                gameEntity.adIconActive,
                gameEntity.adSpaceId,
                gameEntity.gameAdSourceId
            )
            val adConfig = item.adConfig
            if (adConfig != null) {
                NewFlatLogUtils.logClickGameAd(
                    adConfig.id,
                    adConfig.name,
                    "游戏搜索",
                    adConfig.typeChinese,
                    adConfig.ownerAd?.id ?: "",
                    adConfig.ownerAd?.sourceName ?: "",
                    gameEntity.id,
                    gameEntity.name ?: ""
                )
            }
        }


        fun setDownloadBtn(
            entrance: String,
            type: String,
            key: String,
            searchMap: ArrayMap<String, String>,
            exposureEvent: ExposureEvent,
            position: Int,
            binding: SearchGameItemBinding,
            item: SearchItemData,
            context: Context,
            adapter: SearchGameResultAdapter,
            sourceEntrance: String
        ) {
            val gameEntity = item.game ?: return
            if (SPUtils.getBoolean(Constants.SP_TEENAGER_MODE)) {
                binding.downloadBtn.visibility = View.GONE
            } else {
                val adConfig = item.adConfig
                binding.downloadBtn.visibility = View.VISIBLE
                DownloadItemUtils.setOnClickListener(
                    context,
                    binding.downloadBtn,
                    gameEntity,
                    position,
                    adapter,
                    StringUtils.buildString(
                        entrance,
                        "+(搜索-列表[",
                        key,
                        "=",
                        type,
                        "=",
                        "${position + 1}",
                        "])"
                    ),
                    location = "搜索-列表:${gameEntity.name ?: ""}",
                    traceEvent = exposureEvent,
                    clickCallback = {
                        if (adConfig != null) {
                            NewFlatLogUtils.logClickGameAd(
                                adConfig.id,
                                adConfig.name,
                                "游戏搜索",
                                adConfig.typeChinese,
                                adConfig.ownerAd?.id ?: "",
                                adConfig.ownerAd?.sourceName ?: "",
                                gameEntity.id,
                                gameEntity.name ?: ""
                            )
                        }
                        if (gameEntity.isMiniGame()) {
                            MiniGameItemHelper.trackMiniGameClick(
                                gameEntity = gameEntity,
                                location = "小游戏搜索结果列表",
                                searchContent = key,
                            )

                            SensorsBridge.trackMiniGameSearchResultClick(
                                GlobalActivityManager.getCurrentPageEntity().pageId,
                                GlobalActivityManager.getCurrentPageEntity().pageName,
                                sourceEntrance,
                                key,
                                SearchActivity.toTrackSearchType(type),
                                gameEntity.id,
                                gameEntity.name ?: "",
                                gameEntity.categoryChinese,
                                position
                            )
                        } else {
                            SensorsBridge.trackGameSearchResultClick(
                                GlobalActivityManager.getCurrentPageEntity().pageId,
                                GlobalActivityManager.getCurrentPageEntity().pageName,
                                sourceEntrance,
                                key,
                                SearchActivity.toTrackSearchType(type),
                                gameEntity.id,
                                gameEntity.name ?: "",
                                gameEntity.categoryChinese,
                                position,
                                gameEntity.adGroupId
                            )
                        }


                    },
                    refreshCallback = null
                ) {
                    Util_System_Keyboard.hideSoftKeyboardByIBinder(
                        context,
                        binding.downloadBtn.windowToken
                    )

                    if (searchMap[gameEntity.id] == null) {
                        EventBus.getDefault().post(EBSearch("search", gameEntity.id, gameEntity.name))
                        searchMap[gameEntity.id] = gameEntity.name
                    }

                    LogUtils.uploadSearchClick(
                        "search_click",
                        "搜索页",
                        key,
                        SearchType.fromString(type).toChinese(),
                        gameEntity.id,
                        gameEntity.name,
                        gameEntity.getMirrorPosition(),
                        gameEntity.adIconActive,
                        gameEntity.adSpaceId,
                        gameEntity.gameAdSourceId
                    )
                }

                val viewHolder = GameViewHolder(binding.root).apply {
                    gameDownloadBtn = binding.downloadBtn
                    gameDes = binding.gameDes
                    gameDownloadTips = binding.downloadTipsLottie
                    multiVersionDownloadTv = binding.multiVersionDownloadTv
                    gameRating = binding.gameRating
                    recommendContainer = binding.recommendContainer
                    recommendTv = binding.recommendTv
                    recommendIv = binding.recommendIv
                    recommendStarInfo = binding.recommendStarInfo
                }

                binding.downloadBtn.visibility = View.VISIBLE
                DownloadItemUtils.updateItem(
                    context,
                    gameEntity,
                    viewHolder,
                    listener = object : DownloadButton.OnUpdateListener {
                        override fun completion(text: String) {
                            // 如果下载按钮状态为启动，则需要判断是否需要显示加速按钮
                            showSpeedButton(
                                text,
                                gameEntity,
                                adapter.listViewModel,
                                binding
                            )
                        }

                    })
                binding.downloadBtn.putWidgetBusinessName("搜索列表")
            }
        }

        private fun showSpeedButton(
            text: String,
            gameEntity: GameEntity,
            viewModel: SearchGameResultViewModel,
            binding: SearchGameItemBinding
        ) {
            val isNewUser = AcceleratorDataHolder.instance.isNewUser
            if (text == "启动" && !gameEntity.isVGamePreferred() && gameEntity.canSpeed) {
                val context = binding.root.context
                binding.tvFreeVipTag.goneIf(
                    AcceleratorDataHolder.instance.hasAcctGameInfoInLocal ||
                            (CheckLoginUtils.isLogin() && !isNewUser)
                )
                binding.tvSpeed.goneIf(false)
                binding.downloadBtn.goneIf(true)

                val serviceArea = gameEntity.serviceArea
                val hasMutualityZone = serviceArea.size > 1

                val lastAcctGame = gameEntity.lastAcctGame
                val isCurrentGameAccelerating = AcceleratorDataHolder.instance.isCurrentGameAccelerating(gameEntity.id)

                if (isCurrentGameAccelerating) {
                    binding.vSelectRegion.goneIf(true)
                    binding.tvSelectRegion.goneIf(true)
                    binding.tvSpeed.setBackgroundResource(com.gh.gamecenter.common.R.drawable.bg_common_button_light_fill_blue)
                    binding.tvSpeed.text = R.string.accelerating.toResString()
                    binding.tvSpeed.setTextColor(com.gh.gamecenter.common.R.color.text_theme.toColor(context))
                    val drawable = ContextCompat.getDrawable(context, R.drawable.ic_basic_accelerator)
                    drawable?.setTint(com.gh.gamecenter.common.R.color.text_theme.toColor(context))
                    binding.tvSpeed.setDrawableStart(drawable)

                } else {
                    binding.vSelectRegion.goneIf(!hasMutualityZone)
                    binding.tvSelectRegion.goneIf(!hasMutualityZone)
                    binding.tvSelectRegion.text = lastAcctGame?.zoneName ?: R.string.select_the_region.toResString()
                    binding.tvSpeed.setBackgroundResource(com.gh.gamecenter.common.R.drawable.bg_common_button_fill_gradient_blue)
                    binding.tvSpeed.text = R.string.network_acceleration.toResString()
                    binding.tvSpeed.setTextColor(com.gh.gamecenter.common.R.color.text_aw_primary.toColor(context))
                    val drawable = ContextCompat.getDrawable(context, R.drawable.ic_basic_accelerator)
                    drawable?.setTint(com.gh.gamecenter.common.R.color.text_aw_primary.toColor(context))
                    binding.tvSpeed.setDrawableStart(drawable)
                }

                binding.tvSpeed.setOnClickListener {
                    val districtServer = when {
                        hasMutualityZone && lastAcctGame != null -> lastAcctGame.zoneName
                        hasMutualityZone -> DISTRICT_SERVER_EMPTY
                        else -> DISTRICT_SERVER_HAVA
                    }
                    SensorsBridge.trackNetworkAccelerationButtonClick(
                        gameEntity.getUniquePackageName() ?: "",
                        gameEntity.id,
                        gameEntity.name ?: "",
                        AcceleratorDataHolder.instance.memberType,
                        districtServer,
                        SCENE_TYPE_NO_GUIDE_LAYER,
                        SOURCE_ENTRANCE_SEARCH
                    )
                    if (CheckLoginUtils.isLogin()) {
                        when {
                            !hasMutualityZone -> {
                                // 单区服，直接启动
                                val zoneInfo = gameEntity.serviceArea.firstOrNull() ?: AcctGameInfo.ZoneInfo(0)
                                startAccelerating(gameEntity, context, zoneInfo, false)
                            }

                            lastAcctGame != null -> {
                                // 多区服，有缓存的加速记录
                                startAccelerating(gameEntity, context, lastAcctGame.zoneInfo, true)
                            }

                            else -> {
                                // 多区服，没有缓存的加速记录
                                AcceleratorZoneDialogFragment.show(
                                    context,
                                    null,
                                    gameEntity.serviceArea.toArrayList(),
                                    gameEntity,
                                    SOURCE_ENTRANCE_SEARCH
                                )
                            }
                        }

                    } else {
                        CheckLoginUtils.checkLogin(context, null, true, "") {
                        }
                    }
                }
                binding.tvSpeed.isClickable = !isCurrentGameAccelerating

                binding.vSelectRegion.setOnClickListener {
                    context.ifLogin("[网络加速]") {
                        AcceleratorZoneDialogFragment.show(
                            context,
                            lastAcctGame?.zoneInfo?.id,
                            gameEntity.serviceArea.toArrayList(),
                            gameEntity,
                            SOURCE_ENTRANCE_SEARCH
                        )
                    }
                }


            } else {
                binding.tvFreeVipTag.goneIf(true)
                binding.tvSpeed.goneIf(true)
                binding.vSelectRegion.goneIf(true)
                binding.tvSelectRegion.goneIf(true)
            }
        }

        private fun startAccelerating(
            gameEntity: GameEntity,
            context: Context,
            zoneInfo: AcctGameInfo.ZoneInfo,
            hasMultiZone: Boolean
        ) {
            val request = AcceleratorValidator.Request(
                gameEntity,
                SOURCE_ENTRANCE_SEARCH
            )
            AcceleratorClient.newInstance()
                .execute(context, request, object : AcceleratorValidator.ValidateListener {
                    override fun finished(context: Context) {
                        StartingAcceleratorDialogFragment.show(
                            context,
                            zoneInfo,
                            gameEntity,
                            true,
                            hasMultiZone,
                            SOURCE_ENTRANCE_SEARCH
                        )
                    }
                })
        }

        private fun getContentTagView(
            iconRes: Int,
            iconUrl: String,
            content: String,
            width: Int,
            marginRight: Int,
            layoutInflater: LayoutInflater,
            clickListener: (View) -> Unit
        ): View {
            return LayoutSearchGameContentTagBinding.inflate(layoutInflater).apply {
                root.layoutParams = LinearLayout.LayoutParams(width, 28F.dip2px()).apply { rightMargin = marginRight }
                when {
                    iconUrl.isNotEmpty() -> ImageUtils.display(tagIv, iconUrl)
                    iconRes != -1 -> ImageUtils.display(tagIv, iconRes)
                }
                tagTv.text = content
                root.setOnClickListener {
                    clickListener.invoke(it)
                }
            }.root
        }
    }

    class SearchGameAdItemViewHolder(var binding: SearchGameAdItemBinding) : RecyclerView.ViewHolder(binding.root)

}