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.view.isVisible
import androidx.recyclerview.widget.RecyclerView
import com.gh.common.databind.BindingAdapters
import com.gh.common.exposure.IExposable
import com.gh.common.filter.RegionSettingHelper
import com.gh.common.util.DirectUtils
import com.gh.common.util.DownloadItemUtils
import com.gh.common.util.LogUtils
import com.gh.common.util.NewLogUtils
import com.gh.gamecenter.GameDetailActivity
import com.gh.gamecenter.R
import com.gh.gamecenter.SearchType
import com.gh.gamecenter.adapter.viewholder.GameViewHolder
import com.gh.gamecenter.adapter.viewholder.SearchHistoryViewHolder
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.exposure.ExposureSource
import com.gh.gamecenter.common.json.json
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.core.utils.SPUtils
import com.gh.gamecenter.core.utils.StringUtils
import com.gh.gamecenter.databinding.FmSearchHistoryItemBinding
import com.gh.gamecenter.databinding.LayoutSearchGameContentTagBinding
import com.gh.gamecenter.databinding.SearchGameIndexItemBinding
import com.gh.gamecenter.databinding.SearchSubjectItemBinding
import com.gh.gamecenter.db.ISearchHistoryDao
import com.gh.gamecenter.eventbus.EBDownloadStatus
import com.gh.gamecenter.eventbus.EBSearch
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.gamedetail.entity.GameDetailTabEntity
import com.lightgame.download.DownloadEntity
import com.lightgame.utils.Util_System_Keyboard
import org.greenrobot.eventbus.EventBus

class SearchGameIndexAdapter(
    context: Context,
    val fragment: SearchGameIndexFragment,
    private val dao: ISearchHistoryDao,
    val entrance: String,
    val type: String,
    val sourceEntrance: String
) : ListAdapter<SearchItemData>(context) {

    private var searchMap: ArrayMap<String, String> = ArrayMap()

    var key: String = ""

    val positionAndPackageMap = HashMap<String, Int>()

    override fun setListData(updateData: MutableList<SearchItemData>?) {
        // 记录游戏位置
        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
                    }
                }
            }
        }
        super.setListData(updateData)
    }

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

            ItemViewType.GAME_NORMAL -> {
                val itemView = LayoutInflater.from(viewGroup.context)
                    .inflate(R.layout.search_game_index_item, viewGroup, false)
                SearchGameIndexItemViewHolder(SearchGameIndexItemBinding.bind(itemView))
            }

            else -> {
                SearchHistoryViewHolder(FmSearchHistoryItemBinding.inflate(mLayoutInflater, viewGroup, false))
            }
        }
    }

    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
        if (holder is SearchSubjectItemViewHolder) {
            holder.binding.topDivider.goneIf(position == 0)
            holder.bindSubjectItem(
                mContext,
                mEntityList[position],
                SearchType.fromString(type).toChinese(),
                key,
                dao,
                sourceEntrance
            )
        } else {
            val gameEntity = mEntityList[position].game!!
            val gamePosition = mEntityList[position].gamePosition

            val exposureSources = ArrayList<ExposureSource>()
            exposureSources.add(ExposureSource("首页搜索", ""))
            exposureSources.add(ExposureSource(SearchType.fromString(type).toChinese(), key))
            val exposureEvent = ExposureEvent.createEvent(
                gameEntity,
                exposureSources,
                null,
                ExposureType.EXPOSURE
            )
            exposureEvent.payload.searchContent = key

            if (holder is SearchGameIndexItemViewHolder) {
                val binding = holder.binding
                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.topDivider.goneIf(position == 0)
                binding.gameItemIncluded.root.setPadding(
                    16F.dip2px(),
                    0,
                    16F.dip2px(),
                    0
                )
                SearchGameIndexItemViewHolder.initServerType(gameEntity, binding.gameItemIncluded)

                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) {
                        val screenWidth = mContext.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()
                                ) { view ->
                                    dao.add(key)
                                    DirectUtils.directToLinkPage(
                                        mContext,
                                        it.link,
                                        entrance,
                                        ""
                                    )

                                    gameEntity.run {
                                        NewLogUtils.logSearchTagClick(
                                            SearchType.fromString(this@SearchGameIndexAdapter.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()
                            ) {
                                dao.add(key)
                                GameDetailActivity.startGameDetailActivity(
                                    mContext, gameEntity,
                                    StringUtils.buildString(
                                        entrance, "+(搜索-列表[", key, "=", "$type=",
                                        (holder.adapterPosition + 1).toString(), "])"
                                    ), GameDetailTabEntity.TYPE_ZONE, traceEvent = exposureEvent
                                )

                                gameEntity.run {
                                    NewLogUtils.logSearchTagClick(
                                        SearchType.fromString(this@SearchGameIndexAdapter.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()
                            ) {
                                dao.add(key)
                                GameDetailActivity.startGameDetailActivity(
                                    mContext, gameEntity,
                                    StringUtils.buildString(
                                        entrance, "+(搜索-列表[", key, "=", "$type=",
                                        (holder.adapterPosition + 1).toString(), "])"
                                    ), scrollToLibao = true, traceEvent = exposureEvent
                                )

                                gameEntity.run {
                                    NewLogUtils.logSearchTagClick(
                                        SearchType.fromString(this@SearchGameIndexAdapter.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()
                            ) {
                                dao.add(key)
                                GameDetailActivity.startGameDetailActivity(
                                    mContext, gameEntity,
                                    StringUtils.buildString(
                                        entrance, "+(搜索-列表[", key, "=", "$type=",
                                        (holder.adapterPosition + 1).toString(), "])"
                                    ), GameDetailTabEntity.TYPE_BBS, traceEvent = exposureEvent
                                )

                                gameEntity.run {
                                    NewLogUtils.logSearchTagClick(
                                        SearchType.fromString(this@SearchGameIndexAdapter.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()
                                ) {
                                    dao.add(key)
                                    GameDetailActivity.startGameDetailActivity(
                                        mContext, gameEntity,
                                        StringUtils.buildString(
                                            entrance, "+(搜索-列表[", key, "=", "$type=",
                                            (holder.adapterPosition + 1).toString(), "])"
                                        ), scrollToServer = true, traceEvent = exposureEvent
                                    )

                                    gameEntity.run {
                                        NewLogUtils.logSearchTagClick(
                                            SearchType.fromString(this@SearchGameIndexAdapter.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)
                            }
                        }
                    }
                }

                holder.itemView.setOnClickListener {
                    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))
                    }

                    GameDetailActivity.startGameDetailActivity(
                        mContext, gameEntity,
                        StringUtils.buildString(
                            entrance, "+(搜索-列表[", key, "=", "$type=",
                            (holder.getAdapterPosition() + 1).toString(), "])"
                        ), traceEvent = exposureEvent
                    )

                    dao.add(key)

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


                if (SPUtils.getBoolean(Constants.SP_TEENAGER_MODE)) {
                    binding.gameItemIncluded.downloadBtn.visibility = View.GONE
                } else {
                    binding.gameItemIncluded.downloadBtn.visibility = View.VISIBLE
                    DownloadItemUtils.setOnClickListener(
                        mContext,
                        binding.gameItemIncluded.downloadBtn,
                        gameEntity,
                        holder.adapterPosition,
                        this,
                        StringUtils.buildString(
                            entrance,
                            "+(搜索-列表[",
                            key,
                            "=",
                            type,
                            "=",
                            (holder.getAdapterPosition() + 1).toString(),
                            "])"
                        ),
                        location = "搜索-列表:${gameEntity.name ?: ""}",
                        traceEvent = exposureEvent,
                        clickCallback = null,
                        refreshCallback = null
                    ) {
                        Util_System_Keyboard.hideSoftKeyboardByIBinder(
                            mContext,
                            binding.gameItemIncluded.downloadBtn.windowToken
                        )

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

                        if (SearchType.fromString(type) == SearchType.AUTO) {
                            dao.add(key)
                        }

                        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.gameItemIncluded.root).apply {
                        gameDownloadBtn = binding.gameItemIncluded.downloadBtn
                        gameDes = binding.gameItemIncluded.gameDes
                        gameDownloadTips = binding.gameItemIncluded.downloadTipsLottie
                        multiVersionDownloadTv = binding.gameItemIncluded.multiVersionDownloadTv
                        gameRating = binding.gameItemIncluded.gameRating
                        recommendContainer = binding.gameItemIncluded.recommendContainer
                        recommendTv = binding.gameItemIncluded.recommendTv
                        recommendIv = binding.gameItemIncluded.recommendIv
                        recommendStarInfo = binding.gameItemIncluded.recommendStarInfo
                    }
                    DownloadItemUtils.updateItem(
                        mContext,
                        gameEntity,
                        viewHolder
                    )
                }
            } else if (holder is SearchHistoryViewHolder) {
                GameItemViewHolder.initGameSubtitleAndAdLabel(
                    gameEntity,
                    holder.binding.gameSubtitleTv,
                    holder.binding.gameNameContainer,
                    holder.binding.searchHistoryName,
                    gameEntity.adIconActive,
                    holder.binding.adLabelTv,
                )
                holder.binding.searchHistoryName.text = gameEntity.name
                holder.binding.root.setOnClickListener {
                    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))
                    }

                    GameDetailActivity.startGameDetailActivity(
                        mContext, gameEntity,
                        StringUtils.buildString(
                            entrance, "+(搜索-列表[", key, "=", type, "=",
                            (holder.getAdapterPosition() + 1).toString(), "])"
                        ), traceEvent = exposureEvent
                    )
                    dao.add(key)

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

    private fun getContentTagView(
        iconRes: Int,
        iconUrl: String,
        content: String,
        width: Int,
        marginRight: Int,
        clickListener: (View) -> Unit
    ): View {
        return LayoutSearchGameContentTagBinding.inflate(mLayoutInflater).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
    }

    override fun getItemViewType(position: Int): Int {
        val data = mEntityList[position]
        return when {
            data.subject != null -> ItemViewType.GAME_SUBJECT
            position == 0 || position == 1 || position == 2 -> ItemViewType.GAME_NORMAL
            else -> ItemViewType.SEARCH_NORMAL
        }
    }

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

    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 && 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 && mEntityList != null && position < mEntityList.size && mEntityList[position].game != null) {
                    mEntityList[position].game!!.getEntryMap().remove(status.platform)
                    notifyItemChanged(position)
                }
            }
        }
    }
}