package com.gh.gamecenter.search

import android.graphics.*
import android.graphics.drawable.GradientDrawable
import android.graphics.drawable.ShapeDrawable
import android.graphics.drawable.shapes.RoundRectShape
import android.os.Bundle
import android.text.TextUtils
import android.view.Gravity
import android.view.View
import android.view.ViewGroup
import android.widget.CheckedTextView
import android.widget.TextView
import androidx.appcompat.content.res.AppCompatResources
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.content.ContextCompat
import androidx.viewpager.widget.PagerAdapter
import com.gh.common.constant.Config
import com.gh.common.exposure.ExposureManager
import com.gh.common.filter.RegionSettingHelper
import com.gh.common.util.DirectUtils
import com.gh.common.util.NewFlatLogUtils
import com.gh.gamecenter.R
import com.gh.gamecenter.SearchActivity
import com.gh.gamecenter.SearchType
import com.gh.gamecenter.common.base.fragment.BaseFragment
import com.gh.gamecenter.common.constant.EntranceConsts
import com.gh.gamecenter.common.exposure.ExposureSource
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.common.view.DrawableView
import com.gh.gamecenter.core.utils.DisplayUtils
import com.gh.gamecenter.core.utils.PageSwitchDataHelper
import com.gh.gamecenter.core.utils.StringUtils
import com.gh.gamecenter.databinding.FragmentSearchDefaultBinding
import com.gh.gamecenter.db.ISearchHistoryDao
import com.gh.gamecenter.db.SearchHistoryDao
import com.gh.gamecenter.eventbus.EBSearch
import com.gh.gamecenter.feature.entity.DiscoveryTagEntity
import com.gh.gamecenter.feature.entity.HotTagEntity
import com.gh.gamecenter.feature.entity.SettingsEntity
import com.gh.gamecenter.feature.exposure.ExposureEvent
import com.google.android.flexbox.FlexboxLayout
import com.google.android.material.tabs.TabLayout
import com.lightgame.utils.Util_System_Keyboard
import org.greenrobot.eventbus.EventBus
import org.json.JSONException
import org.json.JSONObject

open class SearchDefaultFragment : BaseFragment<Any>() {

    private var mHotTagList: List<HotTagEntity>? = null
    private var mDiscoveryTagList: List<DiscoveryTagEntity>? = null
    protected var mRankList: List<SettingsEntity.Search.RankList>? = null

    protected lateinit var mBinding: FragmentSearchDefaultBinding

    private var mViewModel: SearchDefaultViewModel? = null

    private var mIsGameSearch = false // 是否为游戏搜索

    private var mSourceEntrance: String = ""

    val defaultViewModel: SearchDefaultViewModel?
        get() = mViewModel

    // FlexboxLayout:maxLine 不符合需求
    protected val mFlexMaxHeight = DisplayUtils.dip2px(57F)

    protected val mHotAndDiscoveryFlexMaxHeight = DisplayUtils.dip2px(88F)

    private val mDao by lazy { provideDao() }

    private val mHotTagClickListener: (HotTagEntity) -> Unit = { tag ->
        NewFlatLogUtils.logSearchHotTagClick(
            tag.name ?: "",
            tag.type ?: "",
            tag.link ?: "",
            tag.text ?: ""
        )
        DataLogUtils.uploadHotTagLog(context, tag.name)
        PageSwitchDataHelper.pushCurrentPageData(
            hashMapOf(
                Pair(PageSwitchDataHelper.PAGE_BUSINESS_TYPE, "游戏搜索-热门标签"),
                Pair(PageSwitchDataHelper.PAGE_BUSINESS_ID, tag.id ?: ""),
                Pair(PageSwitchDataHelper.PAGE_BUSINESS_NAME, tag.name ?: " ")
            )
        )
        SensorsBridge.trackEvent("SearchLabelClick", "label_name", tag.name ?: "", "label_id", tag.id ?: "")
        val exposureEvent = ExposureEvent.createEvent(
            null,
            source = listOf(ExposureSource("首页搜索", ""), ExposureSource("热门标签", tag.name ?: ""))
        )
        DirectUtils.directToLinkPage(requireContext(), tag, "(搜索-${tag.name})", "", exposureEvent) // 不需要path
    }

    private val mDiscoveryTagClickListener: (DiscoveryTagEntity, Int) -> Unit = { tag, position ->
        val keyword = tag.keyword
        if (keyword.isNotEmpty()) {
            PageSwitchDataHelper.pushCurrentPageData(
                hashMapOf(
                    Pair(PageSwitchDataHelper.PAGE_BUSINESS_TYPE, "游戏搜索-搜索发现"),
                    Pair(PageSwitchDataHelper.PAGE_BUSINESS_ID, tag.id ?: ""),
                    Pair(PageSwitchDataHelper.PAGE_BUSINESS_NAME, tag.text ?: " ")
                )
            )
            SensorsBridge.trackEvent("SearchLabelClick", "label_name", tag.text ?: "", "label_id", tag.id ?: "")
            SensorsBridge.trackSearchDiscoveryClick(
                labelName = tag.text ?: "",
                labelId = tag.id ?: "",
                searchContent = keyword,
                position = position
            )
            mViewModel?.add(keyword)
            EventBus.getDefault().post(EBSearch(SearchType.DISCOVERY.value, keyword))
            Util_System_Keyboard.hideSoftKeyboardByIBinder(context, mBinding.historyFlex.windowToken)
        }
    }

    override fun getLayoutId(): Int {
        return R.layout.fragment_search_default
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        mViewModel = provideViewModel()

        mIsGameSearch = arguments?.getBoolean(KEY_IS_GAME_SEARCH) ?: false
        mSourceEntrance = arguments?.getString(EntranceConsts.KEY_SOURCE_ENTRANCE) ?: ""

    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        initView()
    }

    protected open fun initView() {
        mBinding = FragmentSearchDefaultBinding.bind(mCachedView)
        mRankList = Config.getSettings()?.search?.rankList?.apply {
            forEachIndexed { outIndex, rankList ->
                rankList.isShowIcon = !rankList.content.any { it.icon.isBlank() }
                var i = 0
                while (i < rankList.content.size) {
                    if (RegionSettingHelper.shouldThisGameBeFiltered(rankList.content[i].linkGame?.id)) {
                        rankList.content.removeAt(i)
                        i--
                    }
                    i++
                }
                rankList.content.forEachIndexed { index, rank ->
                    val source = listOf(ExposureSource("首页搜索 -> 搜索榜单", "${rankList.title}-${rank.name}"))
                    if (rank.link.type == "game") {
                        rank.exposureEvent = ExposureEvent.createEvent(
                            rank.linkGame?.toGameEntity()?.apply {
                                outerSequence = outIndex
                                sequence = index
                            },
                            source
                        )
                    } else {
                        rank.exposureEvent = ExposureEvent.createEvent(null, source)
                    }
                }
            }
        }
        mViewModel?.isExistRankList = mRankList?.isNotEmpty() == true

        mHotTagList = Config.getSettings()?.search?.hotTag
        mDiscoveryTagList = Config.getSettings()?.search?.discoveryTag
        mViewModel?.isExistHotAndDiscoveryTag =
            mHotTagList?.isNotEmpty() == true || mDiscoveryTagList?.isNotEmpty() == true

        updateHistorySearchView(null)
        mViewModel?.historySearchLiveData?.observe(viewLifecycleOwner) {
            updateHistorySearchView(it)
        }

        mBinding.hotAndDiscoveryTagFlexContainer.setLimitHeight(mHotAndDiscoveryFlexMaxHeight)
        createHotAndDiscoveryFlexContent(
            mBinding.hotAndDiscoveryTagFlex,
            getHotTagList(),
            getDiscoveryTagList(),
            hotTagClickListener = mHotTagClickListener,
            discoveryTagClickListener = mDiscoveryTagClickListener
        )
        initHeadView()
        initRankViewPager()
    }

    protected open fun initHeadView() {
        mBinding.historyHeadContainer.run {
            headTitle.text = getString(R.string.search_history)
            headTitle.textSize = 16F
            headActionTv.text = "清空"
            headActionTv.setTextColor(com.gh.gamecenter.common.R.color.text_tertiary.toColor(requireContext()))
            headActionTv.setDrawableStart(
                AppCompatResources.getDrawable(
                    requireContext(),
                    R.drawable.search_history_delete
                )
            )
            headActionTv.setOnClickListener {
                DialogHelper.showCenterWarningDialog(
                    requireContext(),
                    "清空记录",
                    "确定清空历史搜索记录？",
                    confirmClickCallback = {
                        mViewModel?.deleteAll()
                        mViewModel?.isExistHistory = false
                        updateView()
                    })
            }
        }
        mBinding.hotHeadContainer.headTitle.text = getString(R.string.search_hot)
        mBinding.hotHeadContainer.headTitle.textSize = 16F
        mBinding.hotHeadContainer.headActionTv.visibility = View.GONE
        mBinding.hotAndDiscoveryTagHeadContainer.headTitle.text = getString(R.string.search_discovery_tag)
        mBinding.hotAndDiscoveryTagHeadContainer.headTitle.textSize = 16F
        mBinding.hotAndDiscoveryTagHeadContainer.headActionTv.visibility = View.GONE
    }

    protected open fun initRankViewPager() {
        mRankList = mRankList?.filter { it.content.isNotEmpty() }?.take(6)
        if (mRankList.isNullOrEmpty()) return

        mBinding.run {
            val screenWidth = resources.displayMetrics.widthPixels
            val viewPagerWidth = screenWidth - 16F.dip2px() - 16F.dip2px()
            val pageWidth = screenWidth - 16F.dip2px() - 64F.dip2px()
            val pageRatio = pageWidth.toFloat() / viewPagerWidth
            val normalPageOffset = pageWidth + 12F.dip2px()
            val lastPageOffset = pageWidth - (64F.dip2px() - 12F.dip2px()) + 16F.dip2px()
            val lastPositionRatio = lastPageOffset.toFloat() / normalPageOffset

            rankTabIndicator.run {
                setupWithTabLayout(rankTabLayout)
                setupWithViewPager(rankViewPager)
                setIndicatorWidth(20)
                setIndicatorLastPositionRatio(lastPositionRatio)
            }
            rankViewPager.run {
                visibility = View.VISIBLE
                offscreenPageLimit = mRankList!!.size
                pageMargin = 12F.dip2px()
                adapter = provideAdapter(pageRatio)
                postExposureEvent(0)
                doOnPageSelected {
                    postExposureEvent(it)

                    val title = mRankList?.safelyGetInRelease(it)?.title ?: ""

                    val trackEvent = JSONObject()
                    try {
                        trackEvent.put("list_name", title)
                        trackEvent.put("position", it + 1)
                    } catch (e: JSONException) {
                        e.printStackTrace()
                    }

                    if (mIsGameSearch) {
                        NewFlatLogUtils.logSearchClickRank(title, (it + 1).toString())
                    }

                    SensorsBridge.trackEvent("GameListPageSelected", trackEvent)
                }
            }

            rankTabLayout.run {
                setupWithViewPager(rankViewPager)
                for (i in 0 until tabCount) {
                    val tab = getTabAt(i) ?: continue
                    val tabTitle = if (tab.text != null) tab.text.toString() else ""
                    tab.text = tabTitle
                }
                getTabAt(0)?.run { updateTabStyle(this, true) }
                addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener {
                    override fun onTabSelected(tab: TabLayout.Tab?) {
                        updateTabStyle(tab, true)
                    }

                    override fun onTabUnselected(tab: TabLayout.Tab?) {
                        updateTabStyle(tab, false)
                    }

                    override fun onTabReselected(tab: TabLayout.Tab?) {
                        updateTabStyle(tab, true)
                    }
                })
                handleTabLayoutBorder()
            }
        }
    }

    private fun handleTabLayoutBorder() {
        mBinding.rankTabLayout.run {
            post {
                val screenWidth = resources.displayMetrics.widthPixels
                val tabLayoutWidth = getTabLayoutWidth()
                if (screenWidth >= tabLayoutWidth) {
                    (layoutParams as ViewGroup.MarginLayoutParams).apply {
                        leftMargin = 8F.dip2px()
                        rightMargin = 8F.dip2px()
                        layoutParams = this
                    }
                    clipToPadding = true
                } else {
                    val paddingOffset = (tabLayoutWidth - screenWidth) / 2
                    if (paddingOffset < 8F.dip2px()) {
                        (layoutParams as ViewGroup.MarginLayoutParams).apply {
                            leftMargin = 8F.dip2px() - paddingOffset
                            rightMargin = 8F.dip2px() - paddingOffset
                            layoutParams = this
                        }
                        setPadding(paddingOffset, 16F.dip2px(), paddingOffset, 0)
                    } else {
                        setPadding(8F.dip2px(), 16F.dip2px(), 8F.dip2px(), 0)
                    }
                    clipToPadding = false
                }

                mBinding.rankTabIndicator.generatePath(mBinding.rankViewPager.currentItem, 0F)
            }
        }
    }

    private fun getTabLayoutWidth(): Int {
        mBinding.rankTabLayout.run {
            var tabLayoutWidth = 8F.dip2px() + 8F.dip2px()
            if (childCount > 0) {
                val viewGroup = getChildAt(0) as ViewGroup
                for (i in 0 until viewGroup.childCount) {
                    val tab = viewGroup.getChildAt(i) ?: continue
                    tabLayoutWidth += tab.width
                }
            }
            return tabLayoutWidth
        }
    }

    fun updateTabStyle(tab: TabLayout.Tab?, isChecked: Boolean) {
        tab?.customView?.findViewById<CheckedTextView>(R.id.tabTitle)?.isChecked = isChecked
    }

    fun updateView() {
        mBinding.historyHeadContainer.root.visibility =
            if (mViewModel?.isExistHistory == true) View.VISIBLE else View.GONE
        mBinding.historyFlex.visibility = if (mViewModel?.isExistHistory == true) View.VISIBLE else View.GONE
        mBinding.hotAndDiscoveryTagHeadContainer.root.layoutParams =
            (mBinding.hotAndDiscoveryTagHeadContainer.root.layoutParams as ConstraintLayout.LayoutParams).apply {
                setMargins(
                    0,
                    if (mViewModel?.isExistHistory == true) 16F.dip2px() else 0,
                    0,
                    0
                )
            }
        mBinding.hotHeadContainer.root.layoutParams =
            (mBinding.hotHeadContainer.root.layoutParams as ConstraintLayout.LayoutParams).apply {
                setMargins(
                    0,
                    if (mViewModel?.isExistHistory == false && mViewModel?.isExistHotAndDiscoveryTag == false) 16F.dip2px() else 0,
                    0,
                    0
                )
            }
        mBinding.hotAndDiscoveryTagHeadContainer.root.visibility =
            if (mViewModel?.isExistHotAndDiscoveryTag == true) View.VISIBLE else View.GONE
        mBinding.hotAndDiscoveryTagFlex.visibility =
            if (mViewModel?.isExistHotAndDiscoveryTag == true) View.VISIBLE else View.GONE
        mBinding.hotHeadContainer.root.visibility =
            if (mViewModel?.isExistHotSearch == true) View.VISIBLE else View.GONE
        mBinding.hotList.visibility = if (mViewModel?.isExistHotSearch == true) View.VISIBLE else View.GONE
        mBinding.rankTabLayout.visibility = if (mViewModel?.isExistRankList == true) View.VISIBLE else View.GONE
        mBinding.rankTabIndicator.visibility = if (mViewModel?.isExistRankList == true) View.VISIBLE else View.GONE
        mBinding.rankViewPager.visibility = if (mViewModel?.isExistRankList == true) View.VISIBLE else View.GONE
    }

    protected open fun updateHistorySearchView(historyList: List<String>?) {
        mViewModel?.isExistHistory = historyList?.isNotEmpty() == true
        updateView()
        if (historyList != null) {
            mBinding.historyFlexContainer.setLimitHeight(DisplayUtils.dip2px(88F))
            createFlexContent(mBinding.historyFlex, historyList, clickListener = {
                val key = historyList[it]
                mViewModel?.add(key)
                EventBus.getDefault().post(EBSearch("history", key))
                Util_System_Keyboard.hideSoftKeyboardByIBinder(context, mBinding.historyFlex.windowToken)
            })
        }
    }

    private fun getHotTagList(): List<HotTagEntity> {
        val list = ArrayList<HotTagEntity>()
        if (mHotTagList != null) {
            for (entity in mHotTagList!!) {
                if (list.size == 8) break // 最多显示8个热门标签
                entity.name?.let { list.add(entity) }
            }
        }
        return list
    }

    private fun getDiscoveryTagList(): List<DiscoveryTagEntity> {
        val list = ArrayList<DiscoveryTagEntity>()
        if (mDiscoveryTagList != null) {
            for (entity in mDiscoveryTagList!!) {
                entity.text?.let { list.add(entity) }
            }
        }
        return list
    }


    fun createFlexContent(
        flexView: FlexboxLayout,
        contentList: List<String>?,
        clickListener: (Int) -> Unit
    ) {

        if (contentList.isNullOrEmpty()) return
        flexView.removeAllViews()

        for (index in 0 until contentList.count()) {
            val flexCell = TextView(context)
            flexView.addView(flexCell)

            val params = FlexboxLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, 24F.dip2px())
            flexCell.layoutParams = params

            flexCell.setSingleLine()
            flexCell.ellipsize = TextUtils.TruncateAt.END
            flexCell.gravity = Gravity.CENTER
            flexCell.textSize = 12F
            flexCell.text = StringUtils.shrinkStringWithDot(contentList[index], 6)
            flexCell.setTextColor(com.gh.gamecenter.common.R.color.text_secondary.toColor(requireContext()))
            flexCell.setPadding(8F.dip2px(), 0, 8F.dip2px(), 0)
            flexCell.background = if (mIsDarkModeOn) GradientDrawable().apply {
                setStroke(0.5F.dip2px(), Color.parseColor("#21FFFFFF"))
                cornerRadius = 999F
            } else DrawableView.getStrokeDrawable(com.gh.gamecenter.common.R.color.text_dddddd, 0.5F)
            flexCell.setOnClickListener {
                clickListener.invoke(index)
            }
        }
    }

    private fun createHotAndDiscoveryFlexContent(
        flexView: FlexboxLayout,
        hotTagList: List<HotTagEntity>,
        discoveryTagList: List<DiscoveryTagEntity>,
        hotTagClickListener: (HotTagEntity) -> Unit,
        discoveryTagClickListener: (DiscoveryTagEntity, Int) -> Unit
    ) {
        if (hotTagList.isEmpty() && discoveryTagList.isEmpty()) return

        flexView.removeAllViews()

        createHotFlexContent(flexView, hotTagList, hotTagClickListener)

        createDiscoveryFlexContent(flexView, discoveryTagList, discoveryTagClickListener)
    }

    private fun createHotFlexContent(
        flexView: FlexboxLayout,
        contentList: List<HotTagEntity>?,
        clickListener: (HotTagEntity) -> Unit
    ) {
        if (contentList.isNullOrEmpty()) return

        for (index in 0 until contentList.count()) {
            val flexCell = TextView(context)
            flexView.addView(flexCell)

            flexCell.layoutParams = FlexboxLayout.LayoutParams(
                ViewGroup.LayoutParams.WRAP_CONTENT, 24F.dip2px()
            )

            createSmartHotTagStyle(flexCell, contentList[index])

            flexCell.setOnClickListener {
                clickListener.invoke(contentList[index])
            }
        }
    }

    private fun createDiscoveryFlexContent(
        flexView: FlexboxLayout,
        contentList: List<DiscoveryTagEntity>?,
        clickListener: (DiscoveryTagEntity, Int) -> Unit
    ) {
        if (contentList.isNullOrEmpty()) return

        for (index in 0 until contentList.count()) {
            val flexCell = TextView(context)
            flexView.addView(flexCell)

            flexCell.layoutParams = FlexboxLayout.LayoutParams(
                ViewGroup.LayoutParams.WRAP_CONTENT, 24F.dip2px()
            )

            createSmartDiscoverTagStyle(flexCell, contentList[index])

            flexCell.setPadding(8F.dip2px(), 0, 8F.dip2px(), 0)
            flexCell.background = if (mIsDarkModeOn) GradientDrawable().apply {
                setStroke(0.5F.dip2px(), Color.parseColor("#21FFFFFF"))
                cornerRadius = 999F
            } else DrawableView.getStrokeDrawable(com.gh.gamecenter.common.R.color.text_dddddd, 0.5F)
            flexCell.setOnClickListener {
                clickListener.invoke(contentList[index], index)
            }
        }
    }

    private fun createSmartHotTagStyle(flexCell: TextView, entity: HotTagEntity) {
        flexCell.compoundDrawablePadding = 4F.dip2px()
        flexCell.gravity = Gravity.CENTER_VERTICAL
        flexCell.textSize = 12F
        flexCell.text = StringUtils.shrinkStringWithDot(entity.name, 6)
        flexCell.setPadding(8F.dip2px(), 0, 8F.dip2px(), 0)
        val colors =
            intArrayOf(
                com.gh.gamecenter.common.R.color.text_FFB749.toColor(requireContext()),
                com.gh.gamecenter.common.R.color.text_FF6D3C.toColor(requireContext())
            )
        val position = floatArrayOf(0F, 1F)
        val linearGradient = LinearGradient(
            0F,
            0F,
            flexCell.paint.textSize * flexCell.text.length,
            0F,
            colors,
            position,
            Shader.TileMode.CLAMP
        )
        val shapeRadius = floatArrayOf(999F, 999F, 999F, 999F, 999F, 999F, 999F, 999F)
        val strokeWidth = 0.5F.dip2px().toFloat()
        val shape = RoundRectShape(shapeRadius, RectF(strokeWidth, strokeWidth, strokeWidth, strokeWidth), shapeRadius)
        flexCell.background = ShapeDrawable(shape).apply {
            paint.shader = linearGradient
        }
        if (entity.isGuessSearch) {
            flexCell.setTextColor(Color.WHITE)
            flexCell.typeface = Typeface.DEFAULT_BOLD
            flexCell.setDrawableStart(R.drawable.ic_smart_search)
            flexCell.paint.shader = linearGradient
        } else {
            flexCell.setTextColor(
                ContextCompat.getColor(
                    requireContext(),
                    com.gh.gamecenter.common.R.color.text_secondary
                )
            )
        }
        flexCell.invalidate()
    }

    private fun createSmartDiscoverTagStyle(flexCell: TextView, entity: DiscoveryTagEntity) {
        val labelIcon = when (entity.recommendType) {
            "hot" -> R.drawable.ic_search_hot
            "new" -> R.drawable.ic_search_new
            "surge", "rise" -> R.drawable.ic_search_rise
            "update" -> R.drawable.ic_search_update
            else -> -1
        }
        if (labelIcon != -1) {
            flexCell.setDrawableEnd(labelIcon.toDrawable())
            flexCell.compoundDrawablePadding = 4F.dip2px()
        }
        flexCell.setSingleLine()
        flexCell.ellipsize = TextUtils.TruncateAt.END
        flexCell.gravity = Gravity.CENTER
        flexCell.textSize = 12F
        flexCell.text = entity.text
        flexCell.setTextColor(com.gh.gamecenter.common.R.color.text_secondary.toColor(requireContext()))
        flexCell.setPadding(8F.dip2px(), 0, 8F.dip2px(), 0)
        flexCell.background = if (mIsDarkModeOn) GradientDrawable().apply {
            setStroke(0.5F.dip2px(), Color.parseColor("#21FFFFFF"))
            cornerRadius = 999F
        } else DrawableView.getStrokeDrawable(com.gh.gamecenter.common.R.color.text_dddddd, 0.5F)
    }

    private fun postExposureEvent(index: Int) {
        mRankList?.safelyGetInRelease(index)?.content?.forEach {
            if (it.link.type == "game") {
                it.exposureEvent?.run {
                    ExposureManager.log(this)
                }
            }
        }
    }

    override fun onDarkModeChanged() {
        super.onDarkModeChanged()
        initHeadView()

        mBinding.rankTabLayout.setTabTextColors(
            com.gh.gamecenter.common.R.color.text_tertiary.toColor(requireContext()),
            com.gh.gamecenter.common.R.color.text_primary.toColor(requireContext())
        )

        mBinding.rootContainer.setBackgroundColor(com.gh.gamecenter.common.R.color.ui_surface.toColor(requireContext()))
        mBinding.hotList.adapter?.run {
            notifyItemRangeChanged(0, itemCount)
        }
        mViewModel?.historySearchLiveData?.value?.let { updateHistorySearchView(it) }
        createHotAndDiscoveryFlexContent(
            mBinding.hotAndDiscoveryTagFlex,
            getHotTagList(),
            getDiscoveryTagList(),
            hotTagClickListener = mHotTagClickListener,
            discoveryTagClickListener = mDiscoveryTagClickListener
        )
    }

    protected open fun provideDao(): ISearchHistoryDao =
        (activity as? SearchActivity)?.mDao ?: SearchHistoryDao(requireContext())

    protected open fun provideAdapter(pageRatio: Float): PagerAdapter =
        SearchDefaultRankListAdapter(
            requireContext(),
            mViewModel!!,
            mRankList!!,
            pageRatio,
            mIsGameSearch,
            mSourceEntrance
        )

    private fun provideViewModel(): SearchDefaultViewModel {
        val factory = SearchDefaultViewModel.Factory(mDao)
        return viewModelProvider(factory)
    }

    companion object {
        const val KEY_IS_GAME_SEARCH = "key_is_game_search"
    }
}