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.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.utils.*
import com.gh.gamecenter.core.utils.EmptyCallback
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.SearchHistoryDao
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.ExposureSource
import com.gh.gamecenter.feature.exposure.ExposureType
import com.gh.gamecenter.feature.game.GameItemViewHolder
import com.gh.gamecenter.gamedetail.GameDetailFragment
import com.lightgame.download.DownloadEntity
import com.lightgame.utils.Util_System_Keyboard
import org.greenrobot.eventbus.EventBus

class SearchGameIndexAdapter(
    context: Context,
    val fragment: SearchGameIndexFragment,
    val entrance: String,
    val type: String
) : ListAdapter<SearchItemData>(context), IExposable {

    private val dao = SearchHistoryDao(mContext)
    private var exposureEventArray: SparseArray<ExposureEvent>? = null
    private var searchMap: ArrayMap<String, String> = ArrayMap()

    var key: String = ""

    val positionAndPackageMap = HashMap<String, Int>()

    override fun setListData(updateData: MutableList<SearchItemData>?) {
        exposureEventArray = SparseArray(updateData?.size ?: 0)
        // 记录游戏位置
        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)
        } else {
            val gameEntity = mEntityList[position].game!!

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

            if (holder is SearchGameIndexItemViewHolder) {
                val binding = holder.binding
                binding.gameItemIncluded.run {
                    gameIconView.displayGameIcon(gameEntity)
                    BindingAdapters.setGameName(gameName, gameEntity, false, null)
                    BindingAdapters.setTextSize(gameRating, if (gameEntity.commentCount > 3) 12 else 10)
                    BindingAdapters.setGameTags(labelList, gameEntity)
                    gameRating.setDrawableStart(if (gameEntity.commentCount > 3) 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) {
                            R.color.theme_font.toColor(mContext)
                        } else {
                            R.color.theme.toColor(
                                mContext
                            )
                        }
                    )
                    gameDes.text = gameEntity.decoratedDes
                    recommendStar.rating = gameEntity.recommendStar.toFloat()
                    GameItemViewHolder.initGameSubtitleAndAdLabel(
                        gameEntity,
                        gameSubtitleTv,
                        gameNameContainer,
                        gameName,
                        gameEntity.adIconActive,
                        adLabelTv
                    )
                }
                binding.topDivider.goneIf(position == 0)
                binding.gameItemIncluded.root.setPadding(
                    16F.dip2px(),
                    16F.dip2px(),
                    16F.dip2px(),
                    16F.dip2px()
                )
                holder.initServerType(gameEntity)

                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()
                                ) {
                                    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 ?: ""
                                        )
                                    }
                                }
                                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,
                                "",
                                "攻略",
                                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(), "])"
                                    ), GameDetailFragment.TAB_TRENDS, traceEvent = exposureEvent
                                )

                                gameEntity.run {
                                    NewLogUtils.logSearchTagClick(
                                        SearchType.fromString(this@SearchGameIndexAdapter.type).toChinese(),
                                        key,
                                        id,
                                        name ?: "",
                                        "",
                                        "攻略"
                                    )
                                }
                            }
                            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 ?: "",
                                        "",
                                        "礼包",
                                    )
                                }
                            }
                            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(), "])"
                                    ), GameDetailFragment.TAB_BBS, traceEvent = exposureEvent
                                )

                                gameEntity.run {
                                    NewLogUtils.logSearchTagClick(
                                        SearchType.fromString(this@SearchGameIndexAdapter.type).toChinese(),
                                        key,
                                        id,
                                        name ?: "",
                                        "",
                                        "论坛",
                                    )
                                }
                            }
                            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 ?: "",
                                            "",
                                            "开服表",
                                            "",
                                            ""
                                        )
                                    }
                                }
                                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))
                    }

                    if (SearchType.fromString(type) == SearchType.AUTO) {
                        //                    MtaHelper.onEvent("游戏搜索", "自动搜索", key)
                    }

                    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
                    )
                }


                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(),
                            "])"
                        ),
                        "搜索-列表:" + gameEntity.name!!,
                        exposureEvent,
                        null,
                        null,
                        object : EmptyCallback {
                            override fun onCallback() {
                                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)
                                    //                        MtaHelper.onEvent("游戏搜索", "自动搜索", key)
                                }

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

                    DownloadItemUtils.updateItem(
                        mContext,
                        gameEntity,
                        GameViewHolder(binding.gameItemIncluded),
                        true
                    )
                }
            } 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
                    )
                }
            }
        }
    }

    private fun getContentTagView(
        iconRes: Int,
        iconUrl: String,
        content: String,
        width: Int,
        marginRight: Int,
        clickListener: () -> 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()
            }
        }.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
    }

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

    override fun getEventListByPosition(pos: Int): List<ExposureEvent>? {
        return mEntityList[pos].exposureEventList
    }

    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) {
                    mEntityList[position].game!!.getEntryMap()[download.platform] = download
                    notifyItemChanged(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)
                }
            }
        }
    }
}