package com.gh.gamecenter.search

import android.content.Context
import android.util.SparseArray
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.SearchGameFooterViewHolder
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.SuggestType
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.common.viewholder.FooterViewHolder
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.LayoutSearchGameContentTagBinding
import com.gh.gamecenter.databinding.SearchGameFooterBinding
import com.gh.gamecenter.databinding.SearchGameIndexItemBinding
import com.gh.gamecenter.databinding.SearchSubjectItemBinding
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.gh.gamecenter.help.HelpAndFeedbackBridge
import com.lightgame.download.DownloadEntity
import com.lightgame.utils.Util_System_Keyboard
import org.greenrobot.eventbus.EventBus

class SearchGameResultAdapter(
    context: Context,
    val fragment: SearchGameResultFragment,
    val listViewModel: SearchGameResultViewModel,
    val entrance: String,
    val type: String
) : ListAdapter<SearchItemData>(context), IExposable {

    private var searchMap: ArrayMap<String, String> = ArrayMap()
    private var exposureEventArray: SparseArray<ExposureEvent>? = null
    private val ITEM_SEARCH_FOOTER = 109

    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 areItemsTheSame(oldItem: SearchItemData?, newItem: SearchItemData?): Boolean {
        return when {
            oldItem?.subject != null && newItem?.subject != null -> {
                oldItem.subject.columnId == newItem.subject.columnId
            }

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

            ItemViewType.ITEM_BODY -> {
                val itemView = mLayoutInflater.inflate(R.layout.search_game_index_item, viewGroup, false)
                SearchGameIndexItemViewHolder(SearchGameIndexItemBinding.bind(itemView))
            }
            ItemViewType.ITEM_FOOTER -> {
                val itemView = mLayoutInflater.inflate(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 -> {
                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, mEntityList[position], SearchType.fromString(type).toChinese(), key)
            }
            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 FooterViewHolder -> holder.initFooterViewHolder(listViewModel, mIsLoading, mIsNetworkError, mIsOver)
            is SearchGameFooterViewHolder -> bindFooterItem(holder)
        }
    }

    private fun bindFooterItem(holder: SearchGameFooterViewHolder) {
        holder.binding.skipFunction.setOnClickListener {
            LogUtils.uploadSearchGame("ask_more_func", " 搜索页", key, SearchType.fromString(type).toChinese())
            HelpAndFeedbackBridge.startSuggestionActivity(mContext, SuggestType.functionSuggest, "求功能：")
        }
        holder.binding.skipGame.setOnClickListener {
            LogUtils.uploadSearchGame("ask_more_games", " 搜索页", key, SearchType.fromString(type).toChinese())
            HelpAndFeedbackBridge.startSuggestionActivity(mContext, SuggestType.gameCollect, "求游戏：")
        }
        fragment.showAd(holder.binding.hintText, true)
    }

    private fun bindGameItem(holder: SearchGameIndexItemViewHolder) {
        val binding = holder.binding
        val gameEntity = mEntityList[holder.adapterPosition].game!!
        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.gameItemIncluded.root.setPadding(16F.dip2px(), 16F.dip2px(), 16F.dip2px(), 16F.dip2px())
        holder.initServerType(gameEntity)

        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
        )
        exposureEventArray!!.put(holder.adapterPosition, exposureEvent)

        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
                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()
                        ) {
                            DirectUtils.directToLinkPage(
                                mContext,
                                it.link,
                                entrance,
                                ""
                            )

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

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

                            gameEntity.run {
                                NewLogUtils.logSearchTagClick(
                                    SearchType.fromString(this@SearchGameResultAdapter.type).toChinese(),
                                    key,
                                    id,
                                    name ?: "",
                                    "",
                                    "开服表",
                                )
                            }
                        }
                        tagContainer.addView(serverView)
                    }
                }
            } else {
                bottomDivider.visibility = View.GONE
            }
        }

        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.adapterPosition + 1).toString(), "])"
                ),
                traceEvent = exposureEvent
            )
//            mDao.add(gameEntity.nameWithoutSuffix)

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

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

        }

        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.adapterPosition + 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
                        }

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

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

            DownloadItemUtils.updateItem(mContext, gameEntity, GameViewHolder(binding.gameItemIncluded), true)
        }
    }

    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 {
        return if (position == itemCount - 1) {
            if (mIsOver) {
                ITEM_SEARCH_FOOTER
            } else {
                ItemViewType.ITEM_FOOTER
            }
        } else {
            val data = mEntityList[position]
            if (data.subject != null) {
                ItemViewType.GAME_SUBJECT
            } else {
                ItemViewType.ITEM_BODY
            }
        }
    }

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

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

    fun isLoadOver(): Boolean {
        return mIsOver
    }
}