package com.gh.gamecenter.search

import android.content.Context
import android.graphics.Rect
import android.view.LayoutInflater
import android.view.View
import androidx.collection.ArrayMap
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.gh.common.databind.BindingAdapters
import com.gh.common.util.DirectUtils
import com.gh.common.util.NewFlatLogUtils
import com.gh.gamecenter.SearchType
import com.gh.gamecenter.common.exposure.ExposureSource
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.core.utils.HtmlUtils
import com.gh.gamecenter.databinding.ItemSearchFirstBannerBinding
import com.gh.gamecenter.databinding.ItemSearchFirstCardBinding
import com.gh.gamecenter.databinding.SearchGameFirstItemBinding
import com.gh.gamecenter.db.ISearchHistoryDao
import com.gh.gamecenter.feature.entity.FirstSetting
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.feature.exposure.ExposureEvent
import com.gh.gamecenter.feature.exposure.ExposureType
import com.gh.gamecenter.feature.game.GameItemViewHolder
import com.gh.gamecenter.feature.exposure.IExposureProvider
import com.gh.gamecenter.search.SearchGameResultAdapter.Companion.setItemCLick
import com.gh.gamecenter.search.SearchGameResultAdapter.Companion.showContentTag
import com.lzf.easyfloat.utils.DisplayUtils

class SearchGameFirstItemViewHolder(
    private val type: String,
    private val searchMap: ArrayMap<String, String>,
    private val entrance: String,
    private val sourceEntrance: String,
    private val fragment: Fragment,
    val binding: SearchGameFirstItemBinding,
    private val dao: ISearchHistoryDao
) : RecyclerView.ViewHolder(binding.root), IExposureProvider {

    private var contentTag: GameEntity.ContentTag? = null
    private var game: GameEntity? = null
    private var key: String = ""

    private val bannerBinding by lazy {
        val inflater = LayoutInflater.from(binding.root.context)
        ItemSearchFirstBannerBinding.inflate(inflater, binding.llFirstSettingContainer, false)
    }

    private val bannerController = BannerController(bannerBinding.vpBanner, bannerBinding.bannerIndicator) {
        SearchGameFirstBannerAdapter { position, bannerItem ->
            // 点击banner图
            game?.let {
                val link = bannerItem.link ?: return@let
                // 阿里云埋点
                NewFlatLogUtils.logGameSearchFirstGameBannerClick(
                    it.id,
                    HtmlUtils.stripHtml(it.name),
                    position + 1,
                    link.type,
                    link.link,
                    link.text
                )
                //  神策埋点
                SensorsBridge.trackGameSearchFirstGameBannerClick(
                    it.id,
                    HtmlUtils.stripHtml(it.name),
                    position,
                    link.type,
                    link.link,
                    link.text
                )
                dao.add(key)
                DirectUtils.directToLinkPage(binding.root.context, link, "搜索banner", "")
            }

        }
    }

    private val cardBinding by lazy {
        val inflater = LayoutInflater.from(binding.root.context)
        ItemSearchFirstCardBinding.inflate(inflater, binding.llFirstSettingContainer, false)
    }

    private val rvCardsAdapter by lazy {
        SearchGameFirstCardsAdapter { position, cardItem ->
            // 点击横向卡片
            game?.let {
                val link = cardItem.link ?: return@let
                // 阿里云埋点
                NewFlatLogUtils.logGameSearchFirstGameCardClick(
                    it.id,
                    HtmlUtils.stripHtml(it.name),
                    cardItem.cardName,
                    position,
                    link.type,
                    link.link,
                    link.text
                )
                // 神策埋点
                SensorsBridge.trackGameSearchFirstGameCardClick(
                    it.id,
                    HtmlUtils.stripHtml(it.name),
                    position,
                    link.type,
                    link.link,
                    link.text
                )
                dao.add(key)
                DirectUtils.directToLinkPage(binding.root.context, link, "搜索卡片栏", "")
            }
        }
    }

    init {
        fragment.lifecycle.addObserver(bannerController)
    }

    fun bind(
        key: String,
        item: SearchItemData?,
        downloadListener: (ExposureEvent) -> Unit
    ) {
        item ?: return
        val gameEntity = item.game ?: return
        game = gameEntity
        this.key = key

        val context = binding.root.context
        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(context)
                } else {
                    com.gh.gamecenter.common.R.color.primary_theme.toColor(context)
                }
            )
            gameDes.text = gameEntity.decoratedDes
            recommendStar.rating = gameEntity.recommendStar.toFloat()
            GameItemViewHolder.initGameSubtitleAndAdLabel(
                gameEntity,
                gameSubtitleTv,
                gameNameContainer,
                gameName,
                gameEntity.adIconActive,
                adLabelTv
            )
        }
        binding.gameItemIncluded.root.setPadding(16F.dip2px(), 0, 16F.dip2px(), 0)
        SearchGameIndexItemViewHolder.initServerType(gameEntity, binding.gameItemIncluded)

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

        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 != contentTag) {
                contentTag = gameEntity.contentTag
                showContentTag(
                    entrance,
                    type,
                    key,
                    bindingAdapterPosition,
                    exposureEvent,
                    gameEntity,
                    tagContainer,
                    sourceEntrance,
                    0
                )
            }
        }

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

        downloadListener(exposureEvent)

        binding.llFirstSettingContainer.removeAllViews()
        gameEntity.firstSetting?.let {
            if (it.showBannerFirst) {
                addBanner(it.banner)
                addCard(it.card)
            } else {
                addCard(it.card)
                addBanner(it.banner)
            }
        }
    }

    private fun addCard(card: FirstSetting.Card?) {
        card ?: return
        binding.llFirstSettingContainer.addView(cardBinding.root)
        cardBinding.tvTitle.text = card.title
        if (cardBinding.rvCards.adapter == null) {
            cardBinding.rvCards.adapter = rvCardsAdapter
            cardBinding.rvCards.layoutManager =
                LinearLayoutManager(binding.root.context, RecyclerView.HORIZONTAL, false)
        }
        if (cardBinding.rvCards.itemDecorationCount == 0) {
            cardBinding.rvCards.addItemDecoration(CardItemDecoration(binding.root.context))
        }
        rvCardsAdapter.setData(card.preview)
    }

    private fun addBanner(banner: List<FirstSetting.Banner>?) {
        banner ?: return
        binding.llFirstSettingContainer.addView(bannerBinding.root)
        bannerController.bind(banner)
    }

    fun onAttach(recyclerView: RecyclerView?) {
        bannerController.onViewAttachedToWindow(recyclerView)
    }

    fun onDetach(recyclerView: RecyclerView?) {
        bannerController.onViewDetachedFromWindow(recyclerView)
    }

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

    class CardItemDecoration(context: Context) : RecyclerView.ItemDecoration() {

        private val dp8 = DisplayUtils.dp2px(context, 8f)

        override fun getItemOffsets(outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State) {
            super.getItemOffsets(outRect, view, parent, state)
            outRect.left = if (parent.getChildAdapterPosition(view) == 0) {
                0
            } else {
                dp8
            }
        }
    }
}