package com.gh.gamecenter.wrapper

import android.graphics.Typeface
import android.os.Build
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewStub
import android.widget.LinearLayout
import androidx.core.graphics.ColorUtils
import androidx.core.view.updateLayoutParams
import androidx.fragment.app.Fragment
import androidx.viewpager.widget.ViewPager
import com.gh.common.iinterface.IMultiTab
import com.gh.common.iinterface.ISmartRefreshContent
import com.gh.common.iinterface.ISuperiorChain
import com.gh.common.prioritychain.PriorityChain
import com.gh.common.util.ViewPagerFragmentHelper
import com.gh.gamecenter.R
import com.gh.gamecenter.common.base.adapter.FragmentStateAdapter
import com.gh.gamecenter.common.base.fragment.BaseLazyFragment
import com.gh.gamecenter.common.base.fragment.ToolbarFragment
import com.gh.gamecenter.common.constant.EntranceConsts
import com.gh.gamecenter.common.databinding.ReuseLoadingBinding
import com.gh.gamecenter.common.databinding.ReuseNoConnectionBinding
import com.gh.gamecenter.common.databinding.ReuseNoneDataBinding
import com.gh.gamecenter.common.exposure.ExposureSource
import com.gh.gamecenter.common.json.json
import com.gh.gamecenter.common.pagelevel.IPageLevelProvider
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.common.view.TabIndicatorView
import com.gh.gamecenter.common.view.WrapContentDraweeView
import com.gh.gamecenter.databinding.TabItemMainBinding
import com.gh.gamecenter.entity.BottomTab
import com.gh.gamecenter.entity.MultiTabNav
import com.gh.gamecenter.fragment.ReloadFragment
import com.gh.gamecenter.home.custom.CustomPageFragment
import com.google.android.material.tabs.TabLayout
import kotlin.math.abs

/**
 * 多Tab导航页 基类
 */
abstract class BaseTabWrapperFragment : BaseLazyFragment(), IMultiTab {
    protected var viewPager: ViewPager? = null
    protected var tabLayout: TabLayout? = null
    protected var indicatorView: TabIndicatorView? = null
    protected var noDataStub: ViewStub? = null
    protected var noConnectionStub: ViewStub? = null
    protected var loadingStub: ViewStub? = null
    protected var noConnectionBinding: ReuseNoConnectionBinding? = null
    protected var noDataBinding: ReuseNoneDataBinding? = null
    protected var loadingBinding: ReuseLoadingBinding? = null

    protected var tabBindingList = arrayListOf<TabItemMainBinding>()
    protected var tabImageStyleList = arrayListOf<Int>()

    protected var fragmentList = ArrayList<Fragment>()

    protected var multiTabNavId = ""
    protected var multiTabNavName = ""
    protected var bottomTabId = ""
    protected var bottomTabName = ""
    protected var bottomTabIndex = -1
    protected var defaultSelectedTab = -1
    protected var lastSelectedPosition = 0

    protected var backgroundColor: Int = 0
    protected var backgroundWhiteColor: Int = 0
    protected var amwayPrimaryColor: Int = 0
    protected var tabDefaultColor: Int = 0
    protected var tabSelectedColor: Int = 0
    protected var tabDefaultLightColor: Int = 0
    protected val currentFragment: Fragment?
        get() = fragmentList.getOrNull(viewPager?.currentItem ?: 0)

    abstract fun provideViewModel(): TabWrapperViewModel
    protected open fun provideTabLayout(): TabLayout? = mCachedView.findViewById(R.id.tabLayout)
    protected open fun provideViewPager(): ViewPager? = mCachedView.findViewById(R.id.viewPager)
    protected open fun provideIndicatorView(): TabIndicatorView? = mCachedView.findViewById(R.id.indicatorView)
    protected open fun provideIndicatorWidth(): Int = DEFAULT_INDICATOR_WIDTH
    protected open fun provideTabTextSize(): Float = DEFAULT_TAB_TEXT_SIZE
    protected open fun provideTabDefaultColor(): Int = TAB_DEFAULT_COLOR
    protected open fun provideTabSelectedColor(): Int = TAB_SELECTED_COLOR

    override fun provideMultiTabId(): String = multiTabNavId
    override fun provideMultiTabName(): String = multiTabNavName
    override fun provideCurrentTabEntity(): MultiTabNav.LinkMultiTabNav? = getCurrentTabEntity()
    override fun provideLastSelectedPosition(): Int = lastSelectedPosition

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        savedInstanceState?.let { defaultSelectedTab = it.getInt(LAST_SELECTED_POSITION) }
        multiTabNavId = arguments?.getString(EntranceConsts.KEY_MULTI_TAB_NAV_ID, "") ?: ""
        multiTabNavName = arguments?.getString(EntranceConsts.KEY_MULTI_TAB_NAV_NAME, "") ?: ""
        bottomTabName = arguments?.getString(EntranceConsts.KEY_BOTTOM_TAB_NAME, "") ?: ""
        bottomTabId = arguments?.getString(EntranceConsts.KEY_BOTTOM_TAB_ID, "") ?: ""
        bottomTabIndex = arguments?.getInt(EntranceConsts.KEY_BOTTOM_TAB_INDEX, -1) ?: -1
    }

    override fun onSaveInstanceState(outState: Bundle) {
        viewPager?.let { outState.putInt(LAST_SELECTED_POSITION, it.currentItem) }
        super.onSaveInstanceState(outState)
    }

    override fun onFragmentFirstVisible() {
        super.onFragmentFirstVisible()
        noDataStub = mCachedView.findViewById(R.id.reuse_no_data_stub)
        noConnectionStub = mCachedView.findViewById(R.id.reuse_no_connection_stub)
        loadingStub = mCachedView.findViewById(R.id.reuse_loading_stub)
        showLoading(true)

        backgroundColor = com.gh.gamecenter.common.R.color.ui_background.toColor(requireContext())
        backgroundWhiteColor = com.gh.gamecenter.common.R.color.ui_surface.toColor(requireContext())
        amwayPrimaryColor = com.gh.gamecenter.common.R.color.amway_primary_color.toColor(requireContext())
        tabDefaultColor = provideTabDefaultColor().toColor(requireContext())
        tabSelectedColor = provideTabSelectedColor().toColor(requireContext())
        tabDefaultLightColor = TAB_DEFAULT_COLOR_LIGHT.toColor(requireContext())

        if (multiTabNavId.isNotEmpty()) {
            provideViewModel().tabListLiveData.observe(viewLifecycleOwner) {
                if (defaultSelectedTab == -1) {
                    defaultSelectedTab = provideViewModel().defaultTabPosition
                }

                initViewPager(ArrayList(it))

                // 当 tab 少于或等于一个的时候隐藏顶部 tab 栏，停用 nestedScroll
                if (it.size <= 1) {
                    hideTab()
                }

                showNoConnection(false)
                showLoading(false)
                showNoData(it.isEmpty())
            }

            provideViewModel().errorLiveData.observe(viewLifecycleOwner) {
                showLoading(false)
                showNoData(false)
                showNoConnection(true)
            }

            SensorsBridge.trackEvent(
                "ViewSeveralTabPage",
                "bottom_tab",
                bottomTabName,
                "several_tab_page_name",
                multiTabNavName,
                "several_tab_page_id",
                multiTabNavId,
                "source_entrance",
                mEntrance
            )
        }
    }

    override fun onResume() {
        super.onResume()
        if (activity is IPageLevelProvider) {
            (activity as IPageLevelProvider).getPageLevel().updateTopTabPosition(bottomTabIndex, lastSelectedPosition)
        }
    }

    private fun showNoConnection(show: Boolean) {
        if (show) {
            if (noConnectionBinding == null) {
                noConnectionStub?.setOnInflateListener { _, inflated ->
                    noConnectionBinding = ReuseNoConnectionBinding.bind(inflated)
                    noConnectionBinding?.root?.visibility = View.VISIBLE
                    noConnectionBinding?.connectionReloadTv?.setOnClickListener {
                        provideViewModel().getMultiTabNav()
                        showNoData(false)
                        showNoConnection(false)
                        showLoading(true)
                    }
                }
                noConnectionStub?.inflateOrShow()
            } else {
                noConnectionBinding?.root?.visibility = View.VISIBLE
            }
        } else {
            noConnectionBinding?.root?.visibility = View.GONE
        }
    }

    private fun showNoData(show: Boolean) {
        if (show) {
            if (noDataBinding == null) {
                noDataStub?.setOnInflateListener { _, inflated ->
                    noDataBinding = ReuseNoneDataBinding.bind(inflated)
                    noDataBinding?.root?.visibility = View.VISIBLE
                }
                noDataStub?.inflateOrShow()
            } else {
                noDataBinding?.root?.visibility = View.VISIBLE
            }
        } else {
            noDataBinding?.root?.visibility = View.GONE
        }
    }

    private fun showLoading(show: Boolean) {
        if (show) {
            if (loadingBinding == null) {
                loadingStub?.setOnInflateListener { _, inflated ->
                    loadingBinding = ReuseLoadingBinding.bind(inflated)
                    loadingBinding?.root?.visibility = View.VISIBLE
                }
                loadingStub?.inflateOrShow()
            } else {
                loadingBinding?.root?.visibility = View.VISIBLE
            }
        } else {
            loadingBinding?.root?.visibility = View.GONE
        }
    }

    abstract fun hideTab()

    override fun onBackPressed(): Boolean {
        val currentFragment = currentFragment
        if (currentFragment is ToolbarFragment) {
            return currentFragment.onBackPressed()
        }
        return super.onBackPressed()
    }

    protected open fun initViewPager(tabEntityList: ArrayList<MultiTabNav.LinkMultiTabNav>) {
        viewPager = provideViewPager()
        tabLayout = provideTabLayout()
        indicatorView = provideIndicatorView()

        val fragmentList = generateFragments(tabEntityList).apply { fragmentList = this }
        val tabTitleList = arrayListOf<String>()

        tabEntityList.forEach { tabTitleList.add(it.name) }

        viewPager?.run {
            offscreenPageLimit = if (isOldDevice) 1 else fragmentList.size
            doOnScroll(
                onPageSelected = { position ->
                    onPageSelected(position)
                    tabEntityList.safelyGetInRelease(position)?.let { logTabSelected(it, position) }
                },
                onPageScrolled = { position, positionOffset, _ ->
                    onPageScrolled(position, positionOffset, tabEntityList)
                }
            )
            setRestoredCurItem(this)
            adapter = FragmentStateAdapter(childFragmentManager, fragmentList, tabTitleList)
        }

        tabLayout?.setupWithViewPager(viewPager)
        indicatorView?.setupWithTabLayout(tabLayout)
        indicatorView?.setupWithViewPager(viewPager)
        indicatorView?.setIndicatorWidth(provideIndicatorWidth())

        initTabView(tabEntityList)
        showTabGuideIfExists(tabEntityList)
    }

    private fun showTabGuideIfExists(tabEntityList: ArrayList<MultiTabNav.LinkMultiTabNav>) {
        val guidePosition = tabEntityList.indexOfFirst { it.guide != null }
        if (guidePosition != -1) {
            val tabEntity = tabEntityList[guidePosition]
            val guide = tabEntity.guide
            guide?.bottomTabId = bottomTabId
            guide?.multiTabId = tabEntity.id
            showTabGuide(true, guide, guidePosition)
        } else {
            showTabGuide(false)
        }
    }

    abstract fun showTabGuide(shouldShow: Boolean, guide: BottomTab.Guide? = null, guidePosition: Int = -1)

    protected open fun generateFragments(tabEntityList: ArrayList<MultiTabNav.LinkMultiTabNav>): ArrayList<Fragment> {
        val fragmentList = arrayListOf<Fragment>()
        for ((index, tabEntity) in tabEntityList.withIndex()) {
            val bundle = Bundle()
            bundle.putAll(arguments)
            bundle.putBoolean(EntranceConsts.KEY_IS_FROM_MAIN_WRAPPER, false)
            bundle.putBoolean(EntranceConsts.KEY_IS_FROM_TAB_WRAPPER, true)
            bundle.putBoolean(EntranceConsts.KEY_DEFAULT_TAB, tabEntity.default)
            bundle.putInt(EntranceConsts.KEY_TAB_COUNT, tabEntityList.size)
            bundle.putInt(EntranceConsts.KEY_TAB_INDEX, index)
            bundle.putString(EntranceConsts.KEY_TAB_NAME, tabEntity.name)
            bundle.putInt(EntranceConsts.KEY_POSITION, index)

            val bottomTabExposureSource = arguments?.getParcelableArrayList<ExposureSource>(EntranceConsts.KEY_EXPOSURE_SOURCE_LIST)
            val multiTabNavId = arguments?.getString(EntranceConsts.KEY_MULTI_TAB_NAV_ID, "") ?: ""
            val multiTabNavName = arguments?.getString(EntranceConsts.KEY_MULTI_TAB_NAV_NAME, "") ?: ""
            val multiTabNavExposureSource = ExposureSource("多tab导航页", "${multiTabNavName}+${multiTabNavId}")
            val tabExposureSource = ExposureSource("顶部tab", tabEntity.name)
            val exposureSourceList = if (bottomTabExposureSource != null) {
                bottomTabExposureSource + multiTabNavExposureSource + tabExposureSource
            } else {
                arrayListOf(multiTabNavExposureSource, tabExposureSource)
            }
            bundle.putParcelableArrayList(EntranceConsts.KEY_EXPOSURE_SOURCE_LIST, exposureSourceList.toArrayList())

            val fragment = when (tabEntity.link?.type) {
                ViewPagerFragmentHelper.TYPE_CUSTOM_PAGE -> {
                    val superiorChain = if (this is ISuperiorChain) this else null
                    bundle.putString(EntranceConsts.KEY_CUSTOM_PAGE_ID, tabEntity.link.link)
                    bundle.putString(EntranceConsts.KEY_CUSTOM_PAGE_NAME, tabEntity.link.text)
                    CustomPageFragment().setSuperiorChain(superiorChain).with(bundle)
                }

                else -> tabEntity.link?.let { ViewPagerFragmentHelper.createFragment(this, bundle, it, true) }
                    ?: ReloadFragment()
            }
            fragmentList.add(fragment)
        }
        return fragmentList
    }

    /**
     * 设置 ViewPager 默认的选中项
     */
    protected open fun setRestoredCurItem(viewPager: ViewPager) {
        // 设置默认 position 避免 position 为 0 的 fragment 被先加载显示再跳转至具体页面
        tryCatchInRelease {
            val field = ViewPager::class.java.getDeclaredField("mRestoredCurItem")
            field.isAccessible = true
            field.set(viewPager, defaultSelectedTab)
            lastSelectedPosition = defaultSelectedTab
        }
    }

    /**
     * 初始化每个需要显示的 TabView
     */
    protected open fun initTabView(tabEntityList: ArrayList<MultiTabNav.LinkMultiTabNav>) {
        for (i in 0 until tabEntityList.size) {
            val tabView = tabLayout?.getTabAt(i) ?: continue
            val tabEntity = tabEntityList[i]
            val tabTitle = if (tabView.text != null) tabView.text.toString() else ""
            val tabViewBinding = generateTabView(tabTitle)
            val tabImageStyle = if (tabEntity.img.isEmpty()) {
                TAB_IMAGE_EMPTY
            } else if (tabEntity.showImgOnSelected == true) {
                TAB_IMAGE_ALWAYS_ON
            } else {
                TAB_IMAGE_HIDE_ON_SELECTED
            }

            tabBindingList.add(tabViewBinding)
            tabImageStyleList.add(tabImageStyle)

            if (tabEntity.img.isNotEmpty()) {
                tabViewBinding.titleTv.visibility = View.GONE
                tabViewBinding.invisibleTitleTv.visibility = View.GONE
                tabViewBinding.titleIv.setFixedHeight(16)
                // 部分设备加载图片时会获取到错误的最小宽度，这里为它做个 64DP 的保底尺寸
                tabViewBinding.titleIv.setTag(ImageUtils.TAG_TARGET_WIDTH, 64F.dip2px())
                tabViewBinding.titleIv.display(tabEntity.img)
                tabViewBinding.titleIv.registerLoadingCallback(object : WrapContentDraweeView.LoadingCallback {
                    override fun loaded() {
                        postRunnable {
                            viewPager?.run {
                                // 图片 layout 完成后，更新 tabBar 和 indicatorView 的位置，避免偏移
                                tabLayout?.setScrollPosition(currentItem, 0F, false)
                                indicatorView?.generatePath(currentItem, 0F)
                            }
                        }
                    }
                })
            } else {
                tabViewBinding.titleTv.visibility = View.VISIBLE
                tabViewBinding.invisibleTitleTv.visibility = View.INVISIBLE
            }
            tabView.customView = tabViewBinding.root
            tabView.view.setPadding(0, 0, 0, 0)
            tabView.view.setOnClickListener {
                onTabViewClick()
            }

            // 第一个和最后一个分别设置额外的外边距
            if (i == 0) {
                tabView.view.updateLayoutParams {
                    this as LinearLayout.LayoutParams
                    setMargins(getFirstTabLeftMargin(), 0, 0, 0)
                }
            } else if (i == tabEntityList.size - 1) {
                tabView.view.updateLayoutParams {
                    this as LinearLayout.LayoutParams
                    setMargins(0, 0, getLastTabRightMargin(), 0)
                }
            }
        }
    }

    protected open fun getFirstTabLeftMargin(): Int = 10F.dip2px()

    protected open fun getLastTabRightMargin(): Int = 10F.dip2px()

    protected open fun onTabViewClick() {}

    /**
     * 生成 TabView
     */
    protected open fun generateTabView(title: String): TabItemMainBinding {
        val binding = TabItemMainBinding.inflate(LayoutInflater.from(requireContext()))
        binding.titleTv.run {
            text = title
            textSize = provideTabTextSize()
            setTextColor(tabDefaultColor)
        }
        binding.invisibleTitleTv.run {
            text = title
            textSize = provideTabTextSize()
        }
        return binding
    }

    protected open fun onPageSelected(position: Int) {
        notifyChildFragmentLifecycle(position)
        if (activity is IPageLevelProvider) {
            (activity as IPageLevelProvider).getPageLevel().updateTopTabPosition(bottomTabIndex, position)
        }
    }

    abstract fun onPageScrolled(position: Int, positionOffset: Float, tabEntityList: ArrayList<MultiTabNav.LinkMultiTabNav>)

    protected open fun logTabSelected(tabEntity: MultiTabNav.LinkMultiTabNav, position: Int) {
        SensorsBridge.trackEvent("SeveralTabPageTabSelect", json {
            "position" to position
            "tab_content" to tabEntity.name
            "link_type" to tabEntity.link?.type
            "link_id" to tabEntity.link?.link
            "link_text" to tabEntity.link?.text
            "bottom_tab" to bottomTabName
            "several_tab_page_name" to multiTabNavName
            "several_tab_page_id" to multiTabNavId
        })
    }

    /**
     * 安全地从根据 position 获取 fragment
     */
    protected fun getFragment(position: Int): Fragment? {
        return if (position < fragmentList.size) {
            fragmentList.safelyGetInRelease(position)
        } else {
            null
        }
    }

    protected fun getValidSmartRefreshContent(position: Int? = viewPager?.currentItem): ISmartRefreshContent? {
        if (position == null) return null
        val fragment = getFragment(position)
        return if (fragment?.isAdded == true) fragment as? ISmartRefreshContent else null
    }

    // 滑动切换Tab是否使用缩放效果
    protected open fun isTabScaleEnabled(): Boolean = true

    /**
     * 更新 tab 的样式
     * @param selectedPosition 选中的 tab
     * @param positionOffset 与选中 tab 的位置偏移，为负时在选中的 tab 左边，为正时在选中 tab 的右边
     * @param currentTabDefaultColor tab默认颜色
     * @param currentTabSelectedColor tab选中颜色
     */
    protected open fun updateTabStyle(selectedPosition: Int, positionOffset: Float, currentTabDefaultColor: Int, currentTabSelectedColor: Int) {
        if (tabBindingList.isEmpty()) return

        val prePosition = selectedPosition - 1
        val nextPosition = selectedPosition + 1

        // positionOffset 小于零，表示 indicator 当前位置处于选中的 tab 的左边
        val indicatorOnLeft = positionOffset < 0F

        val selectedTabBinding = tabBindingList.safelyGetInRelease(selectedPosition) ?: return
        val selectedTabImageStyle = tabImageStyleList.safelyGetInRelease(selectedPosition) ?: return

        // 前一个 tab、当前选中的 tab、后一个 tab 的显示比例
        val preScaleRatio = 1 + abs(positionOffset) / 4
        val selectedScaleRatio = 1 + (1 - abs(positionOffset)) / 4
        val nextScaleRatio = 1 + positionOffset / 4

        // 处理前一个 tab
        if (prePosition != -1) {
            tabBindingList[prePosition].run {
                if (indicatorOnLeft) {
                    when (tabImageStyleList[prePosition]) {
                        TAB_IMAGE_ALWAYS_ON -> {
                            if (isTabScaleEnabled()) {
                                titleIv.scaleX = preScaleRatio
                                titleIv.scaleY = preScaleRatio
                            }
                        }

                        TAB_IMAGE_HIDE_ON_SELECTED -> {
                            if (isTabScaleEnabled()) {
                                titleIv.scaleX = preScaleRatio
                                titleIv.scaleY = preScaleRatio
                            }
                            titleIv.visibility = View.VISIBLE
                            titleTv.visibility = View.GONE
                            invisibleTitleTv.visibility = View.GONE
                        }

                        else -> {
                            titleIv.visibility = View.GONE
                            titleTv.visibility = View.VISIBLE
                            invisibleTitleTv.visibility = View.INVISIBLE
                        }
                    }

                    if (isTabScaleEnabled()) {
                        titleTv.scaleX = preScaleRatio
                        titleTv.scaleY = preScaleRatio
                    }
                    titleTv.setTextColor(
                        ColorUtils.blendARGB(
                            currentTabDefaultColor,
                            currentTabSelectedColor,
                            abs(positionOffset)
                        )
                    )
                } else {
                    titleTv.setTextColor(currentTabDefaultColor)
                }
            }
        }

        // 更新当前选中的 tab
        selectedTabBinding.run {
            // 更新当前选中的 tab 的图片显示状态
            when (selectedTabImageStyle) {
                TAB_IMAGE_ALWAYS_ON -> {
                    if (isTabScaleEnabled()) {
                        val scaleRatio = (1 + (1 - abs(positionOffset)) * 0.25).toFloat()
                        titleIv.scaleX = scaleRatio
                        titleIv.scaleY = scaleRatio
                    }
                }

                else -> {
                    titleIv.visibility = View.GONE
                    titleTv.visibility = View.VISIBLE
                    invisibleTitleTv.visibility = View.INVISIBLE

                    indicatorView?.visibility = View.VISIBLE
                }
            }

            // 选中常驻型的图片时隐藏 indicatorView
            indicatorView?.goneIf(selectedTabImageStyle == TAB_IMAGE_ALWAYS_ON)

            if (isTabScaleEnabled()) {
                titleTv.scaleX = selectedScaleRatio
                titleTv.scaleY = selectedScaleRatio
            }
            titleTv.setTextColor(
                ColorUtils.blendARGB(
                    currentTabDefaultColor,
                    currentTabSelectedColor,
                    1 - abs(positionOffset)
                )
            )
        }

        // 处理后一个 tab
        if (nextPosition < tabBindingList.size) {
            tabBindingList[nextPosition].run {
                if (!indicatorOnLeft) {
                    when (tabImageStyleList[nextPosition]) {
                        TAB_IMAGE_ALWAYS_ON -> {
                            if (isTabScaleEnabled()) {
                                titleIv.scaleX = nextScaleRatio
                                titleIv.scaleY = nextScaleRatio
                            }
                        }

                        TAB_IMAGE_HIDE_ON_SELECTED -> {
                            if (isTabScaleEnabled()) {
                                titleIv.scaleX = nextScaleRatio
                                titleIv.scaleY = nextScaleRatio
                            }
                            titleIv.visibility = View.VISIBLE
                            titleTv.visibility = View.GONE
                            invisibleTitleTv.visibility = View.GONE
                        }

                        else -> {
                            titleIv.visibility = View.GONE
                            titleTv.visibility = View.VISIBLE
                            invisibleTitleTv.visibility = View.INVISIBLE
                        }
                    }
                    if (isTabScaleEnabled()) {
                        titleTv.scaleX = nextScaleRatio
                        titleTv.scaleY = nextScaleRatio
                    }
                    titleTv.setTextColor(
                        ColorUtils.blendARGB(
                            currentTabDefaultColor,
                            currentTabSelectedColor,
                            positionOffset
                        )
                    )
                } else {
                    titleTv.setTextColor(currentTabDefaultColor)
                }
            }
        }

        // 多 tab 切换的时候可能会出现某些 tab 的文字没有回归到原始大小的问题的问题 (positionOffset 不保证连续)
        for ((index, binding) in tabBindingList.withIndex()) {
            if (index != prePosition && index != selectedPosition && index != nextPosition) {
                if (binding.titleTv.scaleX != 1F) {
                    binding.titleTv.scaleX = 1F
                    binding.titleTv.scaleY = 1F
                }
                binding.titleTv.setTextColor(currentTabDefaultColor)
                if (binding.titleIv.scaleX != 1F) {
                    binding.titleIv.scaleX = 1F
                    binding.titleIv.scaleY = 1F
                }
            }

            if (index == selectedPosition) {
                if (positionOffset == 0F) {
                    binding.titleTv.setTextColor(currentTabSelectedColor)
                }

                binding.titleTv.setTypeface(binding.titleTv.typeface, Typeface.BOLD)
            } else {
                if (positionOffset == 0F) {
                    binding.titleTv.setTextColor(currentTabDefaultColor)
                }

                binding.titleTv.setTypeface(null, Typeface.NORMAL)
            }
        }
    }

    protected open fun notifyChildFragmentLifecycle(currentSelectedPosition: Int) {
        tryWithDefaultCatch {
            // 补充 Viewpager Fragment 的生命周期， 先调用旧选中 fragment 的 onPause 再当前的 onResume
            // 避免部分被内嵌的 Fragment 不能正常运作
            if (fragmentList.size > lastSelectedPosition) {
                val fragment: Fragment = fragmentList[lastSelectedPosition]
                if (!fragment.isAdded) return

                fragment.onPause()
                val childFragmentManager = fragment.childFragmentManager
                val fragments = childFragmentManager.fragments
                for (childFragment in fragments) {
                    childFragment.onPause()
                }
            }
            if (fragmentList.size > currentSelectedPosition) {
                val fragment: Fragment = fragmentList[currentSelectedPosition]
                if (!fragment.isAdded) return

                fragment.onResume()
                val childFragmentManager = fragment.childFragmentManager
                val fragments = childFragmentManager.fragments
                for (childFragment in fragments) {
                    childFragment.onResume()
                }
            }
            lastSelectedPosition = currentSelectedPosition
        }
    }

    protected fun getCurrentTabEntity(): MultiTabNav.LinkMultiTabNav? =
        provideViewPager()?.currentItem?.let {
            provideViewModel().tabListLiveData.value?.safelyGetInRelease(it)
        }

    // 默认页面是否为自定义页面
    protected fun isDefaultCustomPageFragment(): Boolean = getFragment(provideViewModel().defaultTabPosition) is CustomPageFragment
    abstract fun addTabGuideHandlerIfExists(chain: PriorityChain)

    override fun onDarkModeChanged() {
        super.onDarkModeChanged()
        backgroundColor = com.gh.gamecenter.common.R.color.ui_background.toColor(requireContext())
        backgroundWhiteColor = com.gh.gamecenter.common.R.color.ui_surface.toColor(requireContext())
        amwayPrimaryColor = com.gh.gamecenter.common.R.color.amway_primary_color.toColor(requireContext())
        tabDefaultColor = provideTabDefaultColor().toColor(requireContext())
        tabSelectedColor = provideTabSelectedColor().toColor(requireContext())
        tabDefaultLightColor = TAB_DEFAULT_COLOR_LIGHT.toColor(requireContext())
    }

    companion object {
        const val LAST_SELECTED_POSITION = "last_selected_position"

        var TAB_SELECTED_COLOR: Int = com.gh.gamecenter.common.R.color.text_primary
        var TAB_DEFAULT_COLOR: Int = com.gh.gamecenter.common.R.color.text_secondary

        var TAB_DEFAULT_COLOR_LIGHT: Int = com.gh.gamecenter.common.R.color.search_text_color_light
        var DEFAULT_TAB_TEXT_SIZE = 16F
        var DEFAULT_INDICATOR_WIDTH = 18

        val isOldDevice = Build.VERSION.SDK_INT < Build.VERSION_CODES.O

        const val TAB_IMAGE_EMPTY = 0
        const val TAB_IMAGE_HIDE_ON_SELECTED = 1
        const val TAB_IMAGE_ALWAYS_ON = 2
    }
}