package com.gh.gamecenter.category2

import android.content.Context
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.gh.common.databind.BindingAdapters
import com.gh.common.util.AdHelper
import com.gh.common.util.DownloadItemUtils
import com.gh.gamecenter.GameDetailActivity
import com.gh.gamecenter.adapter.viewholder.GameViewHolder
import com.gh.gamecenter.common.base.BaseRecyclerViewHolder
import com.gh.gamecenter.common.baselist.ListAdapter
import com.gh.gamecenter.common.constant.ItemViewType
import com.gh.gamecenter.common.exposure.ExposureSource
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.common.view.DrawableView
import com.gh.gamecenter.common.viewholder.FooterViewHolder
import com.gh.gamecenter.core.runOnIoThread
import com.gh.gamecenter.core.utils.PageSwitchDataHelper
import com.gh.gamecenter.core.utils.StringUtils
import com.gh.gamecenter.databinding.CategoryGameItemBinding
import com.gh.gamecenter.eventbus.EBDownloadStatus
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.exposure.IExposureProvider
import com.gh.gamecenter.feature.game.GameItemViewHolder
import com.lightgame.download.DownloadEntity
import org.json.JSONException
import org.json.JSONObject

class CategoryV2ListAdapter(
    context: Context,
    private val mViewModel: CategoryV2ListViewModel,
    private val mCategoryViewModel: CategoryV2ViewModel,
    private val mEntrance: String?,
    private var mLastPageDataMap: HashMap<String, String>? = null
) : ListAdapter<GameEntity>(context) {

    val positionAndPackageMap = HashMap<String, Int>()

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

    fun clearPositionAndPackageMap() {
        positionAndPackageMap.clear()
    }

    override fun areItemsTheSame(oldItem: GameEntity?, newItem: GameEntity?): Boolean {
        return oldItem?.id == newItem?.id
    }

    override fun getItemViewType(position: Int): Int {
        if (position == itemCount - 1) {
            return ItemViewType.ITEM_FOOTER
        }
        return ItemViewType.GAME_NORMAL
    }

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

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

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

    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
        if (holder is CategoryGameItemViewHolder) {
            holder.itemView.setPadding(16F.dip2px(), 8F.dip2px(), 16F.dip2px(), 8F.dip2px())
            val gameEntity = mEntityList[position]

            holder.bindGameItem(gameEntity)
            holder.initServerType(gameEntity)

            val categoryTitle = mCategoryViewModel.pageName
            val selectedCategoryName = mCategoryViewModel.selectedSidebarsName
            val selectedSubCatalogName =
                mCategoryViewModel.selectedSubCategories.value?.joinToString("-") { it.category.name ?: "" }
            val sortType = mViewModel.gameFiltered.sortType.value
            val sortSize = mViewModel.gameFiltered.size.text

            val exposureSources = ArrayList<ExposureSource>()
            if (!mViewModel.exposureSourceList.isNullOrEmpty()) {
                exposureSources.addAll(mViewModel.exposureSourceList!!)
            }
            exposureSources.add(ExposureSource("分类", categoryTitle))
            exposureSources.add(ExposureSource(selectedCategoryName))
            exposureSources.add(ExposureSource("二级分类详情", "$selectedSubCatalogName+$sortType+$sortSize"))

            val event =
                ExposureEvent.createEvent(gameEntity, exposureSources, null, ExposureType.EXPOSURE)
                    .apply {
                        mLastPageDataMap?.let {
                            payload.sourcePage = it[PageSwitchDataHelper.PAGE_BUSINESS_TYPE]
                            payload.sourcePageId = it[PageSwitchDataHelper.PAGE_BUSINESS_ID]
                            payload.sourcePageName = it[PageSwitchDataHelper.PAGE_BUSINESS_NAME]
                        }
                    }

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

            holder.itemView.setOnClickListener {
                GameDetailActivity.startGameDetailActivity(
                    mContext,
                    gameEntity,
                    StringUtils.buildString(
                        mEntrance,
                        "+(",
                        selectedCategoryName,
                        ":列表[",
                        selectedSubCatalogName,
                        "=",
                        sortType,
                        "=",
                        (position + 1).toString(),
                        "])"
                    ),
                    traceEvent = event
                )
            }
            DownloadItemUtils.setOnClickListener(
                mContext,
                holder.binding.downloadBtn,
                gameEntity,
                position,
                this,
                StringUtils.buildString(
                    StringUtils.buildString(
                        mEntrance,
                        "+(",
                        selectedCategoryName,
                        ":列表[",
                        selectedSubCatalogName,
                        "=",
                        sortType,
                        "=",
                        (position + 1).toString(),
                        "])"
                    )
                ),
                location = StringUtils.buildString(selectedSubCatalogName, ":", gameEntity.name),
                traceEvent = event,
            ) {
                val trackEvent = JSONObject()
                try {
                    trackEvent.put("navigation_bar_name", mCategoryViewModel.selectedSidebarsName)
                    trackEvent.put(
                        "game_tag",
                        (mCategoryViewModel.selectedSubCategories.value ?: listOf())
                            .map {
                                it.category.name
                            })
                    trackEvent.put("game_status", gameEntity.category)
                    trackEvent.put(
                        "inclusion_size",
                        gameEntity.getApk().firstOrNull()?.size ?: ""
                    )
                } catch (e: JSONException) {
                    e.printStackTrace()
                }
                SensorsBridge.trackEvent("ClassificationFilterCriteriaSelected", trackEvent)
            }

            DownloadItemUtils.updateItem(
                mContext,
                gameEntity,
                CategoryGameViewHolder(holder.binding),
                "star&brief"
            )

            holder.binding.downloadBtn.putWidgetBusinessName("分类列表")
        } else if (holder is FooterViewHolder) {
            holder.run {
                initItemPadding()
                initFooterViewHolder(mViewModel, mIsLoading, mIsNetworkError, mIsOver)
                hint.textSize = 12F
                hint.setTextColor(com.gh.gamecenter.common.R.color.text_tertiary.toColor(mContext))
            }
        }
    }

    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].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].getEntryMap().remove(status.platform)
                    notifyItemChanged(position)
                }
            }
        }
    }

    inner class CategoryGameItemViewHolder(val binding: CategoryGameItemBinding) :
        BaseRecyclerViewHolder<Any>(binding.root), IExposureProvider {

        private var boundedGameEntity: GameEntity? = null

        fun bindGameItem(gameEntity: GameEntity) {
            boundedGameEntity = gameEntity
            binding.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.text = if (gameEntity.commentCount > 3) {
                    if (gameEntity.star == 10.0F) "10" else gameEntity.star.toString()
                } else ""
                gameRating.setPadding(0, 0, if (gameEntity.commentCount > 3) 8F.dip2px() else 0, 0)
                gameRating.setTextColor(
                    if (gameEntity.commentCount > 3) com.gh.gamecenter.common.R.color.text_theme.toColor(mContext) else com.gh.gamecenter.common.R.color.primary_theme.toColor(
                        mContext
                    )
                )
                gameDes.text = gameEntity.decoratedDes

                GameItemViewHolder.initGameSubtitleAndAdLabel(gameEntity, gameSubtitleTv)
            }
        }

        fun initServerType(gameEntity: GameEntity) {
            val serverLabel = gameEntity.serverLabel
            when {
                gameEntity.test != null -> {
                    binding.gameKaifuType.visibility = View.GONE
                    binding.gameKaifuType.text = ""
                }

                serverLabel != null -> {
                    binding.gameKaifuType.visibility = View.VISIBLE
                    binding.gameKaifuType.text = serverLabel.value
                    if (gameEntity.isUseDefaultServerStyle()) {
                        binding.gameKaifuType.background =
                            com.gh.gamecenter.feature.R.drawable.server_label_default_bg.toDrawable(binding.root.context)
                        binding.gameKaifuType.setTextColor(
                            com.gh.gamecenter.common.R.color.text_secondary.toColor(
                                binding.root.context
                            )
                        )
                    } else {
                        binding.gameKaifuType.background = DrawableView.getServerDrawable(serverLabel.color)
                        binding.gameKaifuType.setTextColor(com.gh.gamecenter.common.R.color.white.toColor(binding.root.context))
                    }
                }

                else -> binding.gameKaifuType.visibility = View.GONE
            }

            // 由于RecyclerView的复用机制 需要每次测量gameName的宽
            binding.gameName.requestLayout()
        }

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

    inner class CategoryGameViewHolder(val binding: CategoryGameItemBinding) : GameViewHolder(binding.root) {
        init {
            gameDownloadBtn = binding.downloadBtn
            gameDes = binding.gameDes
            gameRating = binding.gameRating
            recommendContainer = binding.recommendContainer
            recommendTv = binding.recommendTv
            recommendIv = binding.recommendIv
            multiVersionDownloadTv = binding.multiVersionDownloadTv
            gameDownloadTips = binding.downloadTipsLottie
        }
    }
}