package com.gh.gamecenter.fragment

import android.graphics.Color
import android.graphics.Typeface
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
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.exposure.ExposureManager
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.download.DownloadManager
import com.gh.gamecenter.GameDetailActivity
import com.gh.gamecenter.R
import com.gh.gamecenter.adapter.viewholder.GameViewHolder
import com.gh.gamecenter.amway.AmwayFragment
import com.gh.gamecenter.catalog.CatalogFragment
import com.gh.gamecenter.category.CategoryDirectoryFragment
import com.gh.gamecenter.category2.CategoryV2Fragment
import com.gh.gamecenter.common.base.adapter.FragmentAdapter
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.constant.EntranceConsts
import com.gh.gamecenter.common.eventbus.EBReuse
import com.gh.gamecenter.common.json.json
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.common.view.TabIndicatorView
import com.gh.gamecenter.common.view.WrapContentDraweeView
import com.gh.gamecenter.core.utils.*
import com.gh.gamecenter.databinding.FragmentMainHomeWrapperBinding
import com.gh.gamecenter.databinding.TabItemMainBinding
import com.gh.gamecenter.discovery.DiscoveryFragment
import com.gh.gamecenter.entity.HomePush
import com.gh.gamecenter.entity.SubjectData
import com.gh.gamecenter.entity.SubjectRecommendEntity
import com.gh.gamecenter.eventbus.EBDownloadStatus
import com.gh.gamecenter.eventbus.EBPackage
import com.gh.gamecenter.feature.exposure.ExposureEvent
import com.gh.gamecenter.feature.exposure.ExposureSource
import com.gh.gamecenter.feature.game.GameItemViewHolder
import com.gh.gamecenter.game.GameFragment
import com.gh.gamecenter.game.columncollection.detail.ColumnCollectionDetailFragment
import com.gh.gamecenter.game.commoncollection.detail.CommonCollectionDetailFragment
import com.gh.gamecenter.gamecollection.square.GameCollectionSquareFragment
import com.gh.gamecenter.home.HomeFragment
import com.gh.gamecenter.home.video.ScrollCalculatorHelper
import com.gh.gamecenter.servers.GameServersPublishFragment
import com.gh.gamecenter.servers.GameServersTestFragment
import com.gh.gamecenter.servers.gametest2.GameServerTestV2Fragment
import com.gh.gamecenter.subject.SubjectFragment
import com.google.android.material.appbar.AppBarLayout
import com.halo.assistant.HaloApp
import com.halo.assistant.fragment.WebFragment
import com.lightgame.download.DataWatcher
import com.lightgame.download.DownloadEntity
import com.scwang.smartrefresh.layout.api.RefreshHeader
import com.scwang.smartrefresh.layout.api.RefreshLayout
import com.scwang.smartrefresh.layout.constant.RefreshState
import com.scwang.smartrefresh.layout.listener.SimpleMultiPurposeListener
import com.shuyu.gsyvideoplayer.builder.GSYVideoOptionBuilder
import com.shuyu.gsyvideoplayer.video.base.GSYVideoView
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import kotlin.math.abs
import kotlin.math.roundToInt

class HomeSearchToolWrapperFragment : SearchToolWrapperFragment() {

    private var mBinding: FragmentMainHomeWrapperBinding? = null
    private var mTabBindingList = arrayListOf<TabItemMainBinding>()
    private var mTabImageStyleList = arrayListOf<Int>()

    private var mTabSelectedColor: Int = 0
    private var mTabDefaultColor: Int = 0

    private var mCurrentAppBarColor: Int = 0

    private var mIsDisplayingLightContent = false

    private var mDefaultSelectedTab = -1
    private var mLastSelectedPosition = 0

    private var mViewModel: HomeSearchToolWrapperViewModel? = null

    private var mFragmentList = ArrayList<Fragment>()

    private var mHomeTabPosition = -1
    private var mOffsetCritical = 0.7F

    private var mShowTwoLevel = false
    private var mIsDragging = false
    private var mHomePushClick = false
    private var mHeaderOffset = 0
    private var mClipChildren = true
    private var mTwoLevelOpenOffset = 0
    private var mTwoLevelOpenCount = 0
    private var mShowTwoLevelStartOffset = 0
    private var mHomePush: HomePush? = null
    private var mExposureEvent: ExposureEvent? = null
    private var mGameViewHolder: GameViewHolder? = null

    private lateinit var mElapsedHelper: TimeElapsedHelper

    private val dataWatcher = object : DataWatcher() {
        override fun onDataChanged(downloadEntity: DownloadEntity) {
            if (downloadEntity.gameId == mHomePush?.game?.id) {
                updateHomePushDownloadBtn()
            }
        }

        override fun onDataInit(downloadEntity: DownloadEntity) {
            onDataChanged(downloadEntity)
        }
    }

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

        savedInstanceState?.let { mDefaultSelectedTab = it.getInt(LAST_SELECTED_POSITION) }
    }

    override fun onFragmentFirstVisible() {
        mViewModel = viewModelProviderFromParent()
        mElapsedHelper = TimeElapsedHelper()
        mSearchToolbarFragment =
            childFragmentManager.findFragmentById(R.id.wrapper_toolbar) as SearchToolbarFragment?
                ?: SearchToolbarFragment()
        mSearchToolbarFragment.with(Bundle().apply { putString(EntranceConsts.KEY_LOCATION, "首页") })

        setSearchHints()

        // 记录 appBarOffset 供其它子页面使用
        mBinding?.appbar?.addOnOffsetChangedListener { _, verticalOffset ->
            mViewModel?.appBarOffset = abs(verticalOffset)
        }

        childFragmentManager.beginTransaction()
            .replace(R.id.wrapper_toolbar, mSearchToolbarFragment)
            .commitAllowingStateLoss()

        initSmartRefresh()

        mViewModel?.tabs?.observe(viewLifecycleOwner) {
            if (mDefaultSelectedTab == -1) {
                mDefaultSelectedTab = mViewModel?.defaultTabPosition ?: 0
            }
            mHomeTabPosition = mViewModel?.getHomeTabPosition() ?: 0
            initViewPager(it)

            // 当 tab 只有一个的时候隐藏顶部 tab 栏，停用 nestedScroll
            if (it.size == 1) {
                mBinding?.tabContainer?.visibility = View.GONE
                mBinding?.tabBackground?.visibility = View.GONE
                (mBinding?.collapsingToolbar?.layoutParams as? AppBarLayout.LayoutParams)?.let { lp ->
                    lp.scrollFlags = AppBarLayout.LayoutParams.SCROLL_FLAG_NO_SCROLL
                }
            }

            mBinding?.noConnectionContainer?.reuseNoConnection?.visibility = View.GONE
            mBinding?.loadingContainer?.reuseLlLoading?.visibility = View.GONE
        }

        mViewModel?.error?.observe(viewLifecycleOwner) {
            mBinding?.noConnectionContainer?.reuseNoConnection?.visibility = View.VISIBLE
            mBinding?.loadingContainer?.reuseLlLoading?.visibility = View.GONE
            mBinding?.noConnectionContainer?.reuseNoConnection?.setOnClickListener {
                mViewModel?.getHomeContentUnion()
                mBinding?.noConnectionContainer?.reuseNoConnection?.visibility = View.GONE
                mBinding?.loadingContainer?.reuseLlLoading?.visibility = View.VISIBLE
            }
        }

        mViewModel?.homeDataLiveData?.observeNonNull(viewLifecycleOwner) {
            if (it.homePush != null) {
                mBinding?.run {
                    refreshLayout.setEnableRefresh(getFragment(viewPager.currentItem) is HomeFragment)
                }
                mHomePush = it.homePush
                setHomePush()
            }
        }
    }

    private fun initSmartRefresh() {
        mBinding?.run {
            mGameViewHolder = GameViewHolder(headerContainer).also {
                it.gameDownloadBtn = downloadBtn
                it.multiVersionDownloadTv = multiVersionDownloadTv
                it.gameDownloadTips = downloadTipsLottie
            }
            topMaskView.layoutParams = topMaskView.layoutParams.apply {
                height = DisplayUtils.getStatusBarHeight(requireContext().resources) + 48F.dip2px()
            }
            mTwoLevelOpenOffset =
                DisplayUtils.getScreenWidth() - 48F.dip2px() - DisplayUtils.getStatusBarHeight(requireContext().resources)
            mShowTwoLevelStartOffset = 139F.dip2px() - DisplayUtils.getStatusBarHeight(requireContext().resources)
            tabBackground.setOnlyTopRoundedColorBackground(R.color.background_white.toColor(requireContext()), 8F)
            classicsHeader.setArrowResource(R.drawable.icon_arrow)
            classicsHeader.layoutParams = (classicsHeader.layoutParams as ViewGroup.MarginLayoutParams).apply {
                topMargin = 48F.dip2px() + DisplayUtils.getStatusBarHeight(requireContext().resources)
            }
            statusBar.post {
                twoLevelHeader.layoutParams = (twoLevelHeader.layoutParams as ViewGroup.MarginLayoutParams).apply {
                    topMargin = -(statusBar.height + 48F.dip2px())
                }
            }
            refreshLayout.setOnMultiPurposeListener(object : SimpleMultiPurposeListener() {
                override fun onRefresh(refreshLayout: RefreshLayout) {
                    if (mBinding?.viewPager?.currentItem == mHomeTabPosition) {
                        getValidHomeFragment()?.onRefresh()
                    }
                }

                override fun onHeaderMoving(
                    header: RefreshHeader?,
                    isDragging: Boolean,
                    percent: Float,
                    offset: Int,
                    headerHeight: Int,
                    maxDragHeight: Int
                ) {
                    mIsDragging = isDragging
                    mHeaderOffset = offset
                    updateBackgroundAlpha(offset)
                    headerContainer.translationY = -(mTwoLevelOpenOffset - offset).toFloat()
                }

                override fun onStateChanged(
                    refreshLayout: RefreshLayout,
                    oldState: RefreshState,
                    newState: RefreshState
                ) {
                    val isAutoScrollToTwoLevel = oldState == RefreshState.None && newState == RefreshState.TwoLevel
                    val isDragToTwoLevel =
                        oldState == RefreshState.ReleaseToRefresh && newState == RefreshState.ReleaseToTwoLevel
                    val isScrollToTwoLevel = isDragToTwoLevel || isAutoScrollToTwoLevel
                    val isShowTwoLevelByDrag =
                        oldState == RefreshState.TwoLevelReleased && newState == RefreshState.TwoLevel
                    val isFinishTwoLevel = oldState == RefreshState.TwoLevel && newState == RefreshState.TwoLevelFinish

                    mHomePush?.run {
                        if (isAutoScrollToTwoLevel) {
                            mTwoLevelOpenCount++
                            com.gh.common.util.NewFlatLogUtils.logHomePushShow(
                                id,
                                "自动展开",
                                mTwoLevelOpenCount,
                                game?.id ?: "",
                                game?.name ?: ""
                            )
                        }
                        if (isShowTwoLevelByDrag) {
                            com.gh.common.util.NewFlatLogUtils.logHomePushShow(
                                id,
                                "主动展开",
                                mTwoLevelOpenCount,
                                game?.id ?: "",
                                game?.name ?: ""
                            )
                        }
                        if (isDragToTwoLevel) {
                            mTwoLevelOpenCount++
                            com.gh.common.util.NewFlatLogUtils.logHomePushTrigger(
                                id,
                                mTwoLevelOpenCount,
                                game?.id ?: "",
                                game?.name ?: ""
                            )
                        }
                    }

                    if (isScrollToTwoLevel) {
                        mShowTwoLevel = true
                    }

                    if (isFinishTwoLevel) {
                        pauseHomePushVideo()
                        mShowTwoLevel = false

                        if (mIsDragging) {
                            mElapsedHelper.pauseCounting()
                            mHomePush?.run {
                                com.gh.common.util.NewFlatLogUtils.logHomePushClose(
                                    id,
                                    "主动收起",
                                    mTwoLevelOpenCount,
                                    game?.id ?: "",
                                    game?.name ?: "",
                                    mElapsedHelper.elapsedTime
                                )
                            }
                        }
                    }

                    if (viewPager.currentItem == mHomeTabPosition) {
                        when (newState) {
                            RefreshState.TwoLevel -> getValidHomeFragment()?.setScrollEnabled(false)
                            RefreshState.None -> getValidHomeFragment()?.setScrollEnabled(true)
                            else -> {
                                // do nothing
                            }
                        }
                    }

                    val clipChildren: Boolean
                    when (newState) {
                        RefreshState.TwoLevel,
                        RefreshState.TwoLevelFinish -> {
                            clipChildren = false
                            toolbarBackground.alpha = 0F
                            statusBarBackground.alpha = 0F
                        }

                        RefreshState.ReleaseToTwoLevel,
                        RefreshState.TwoLevelReleased -> {
                            clipChildren = false
                            toolbarBackground.alpha = 0F
                            statusBarBackground.alpha = 0F
                            headerBackground.alpha = 0F
                        }

                        else -> {
                            clipChildren = true
                            toolbarBackground.alpha = 1F
                            statusBarBackground.alpha = 1F
                            headerBackground.alpha = 1F
                        }
                    }

                    if (mClipChildren != clipChildren) {
                        mClipChildren = clipChildren
                        wrapperLl.clipChildren = mClipChildren
                        mBinding?.refreshLayout?.clipChildren = mClipChildren
                    }

                    if (newState == RefreshState.None) {
                        mIsDragging = false
                        twoLevelHeader.setFloorDuration(1000)
                        mBinding?.refreshLayout?.setFloorDuration(1000)
                        classicsHeader.visibility = View.VISIBLE
                    }
                }
            })

            twoLevelHeader.setOnTwoLevelListener {
                mHomePush?.run {
                    if (game != null) {
                        game.sequence = mTwoLevelOpenCount
                        mExposureEvent = ExposureEvent.createEventWithSourceConcat(
                            game,
                            basicSource = listOf(ExposureSource("新首页", "")),
                            source = listOf(ExposureSource("下拉推送", id))
                        )
                        ExposureManager.log(mExposureEvent!!)
                    }
                }

                mElapsedHelper.resetCounting()
                mElapsedHelper.resumeCounting()
                playHomePushVideo()
                true
            }
        }
    }

    private fun updateHomePushDownloadBtn() {
        mBinding?.run {
            mHomePush?.game?.run {
                mGameViewHolder?.let {
                    DownloadItemUtils.updateItem(requireContext(), this, it, true)
                }
                DownloadItemUtils.setOnClickListener(
                    requireContext(),
                    downloadBtn,
                    this,
                    0,
                    null,
                    "新首页-下拉推送",
                    "",
                    mExposureEvent,
                    { updateHomePushDownloadBtn() },
                    { updateHomePushDownloadBtn() },
                    null
                )
            }
        }
    }

    private fun getValidHomeFragment(): HomeFragment? {
        return if (getFragment(mHomeTabPosition) is HomeFragment
            && (getFragment(mHomeTabPosition) as HomeFragment).isAdded
        ) {
            getFragment(mHomeTabPosition) as HomeFragment
        } else null
    }

    // 下拉进入/退出首页推送时更新背景透明度
    private fun updateBackgroundAlpha(offset: Int) {
        mBinding?.run {
            if (offset >= mShowTwoLevelStartOffset) {
                val oneLevelAlpha =
                    1 - (offset - mShowTwoLevelStartOffset) / (mTwoLevelOpenOffset - mShowTwoLevelStartOffset).toFloat()
                tabBgView.alpha = oneLevelAlpha
                getValidHomeFragment()?.getHomeSlideBackgroundView()?.alpha = oneLevelAlpha
                if (mLastSelectedPosition == mHomeTabPosition) {
                    val tabSelectedColor =
                        if (oneLevelAlpha >= PULL_TAB_TEXT_STYLE_UPDATE_PERCENT) TAB_DEFAULT_COLOR_LIGHT.toColor(
                            requireContext()
                        ) else TAB_SELECTED_COLOR.toColor(
                            requireContext()
                        )
                    val tabDefaultColor =
                        if (oneLevelAlpha >= PULL_TAB_TEXT_STYLE_UPDATE_PERCENT) TAB_DEFAULT_COLOR_LIGHT.toColor(
                            requireContext()
                        ) else TAB_DEFAULT_COLOR.toColor(
                            requireContext()
                        )
                    val indicatorDrawable =
                        if (oneLevelAlpha >= PULL_TAB_TEXT_STYLE_UPDATE_PERCENT) R.drawable.ic_home_tab_indicator_white.toDrawable(
                            requireContext()
                        ) else R.drawable.ic_commodity_selected.toDrawable(
                            requireContext()
                        )
                    if (mTabSelectedColor != tabSelectedColor || mTabDefaultColor != tabDefaultColor) {
                        mTabSelectedColor = tabSelectedColor
                        mTabDefaultColor = tabDefaultColor
                        updateTabStyle(mLastSelectedPosition, 0F)
                        indicatorView.updateIndicatorDrawable(indicatorDrawable)
                    }
                }
            } else {
                tabBgView.alpha = 1F
                getValidHomeFragment()?.getHomeSlideBackgroundView()?.alpha = 1F
            }

            if (refreshLayout.state == RefreshState.TwoLevelFinish || refreshLayout.state == RefreshState.TwoLevel) {
                headerBackground.alpha = 1 - offset / mTwoLevelOpenOffset.toFloat()
            }
        }
    }

    // 播放首页推送视频
    private fun playHomePushVideo() {
        mBinding?.run {
            if (!mHomePush?.video?.url.isNullOrEmpty()) {
                if (autoVideoView.currentState != GSYVideoView.CURRENT_STATE_PAUSE) {
                    mBaseHandler.postDelayed({
                        val videoOption =
                            SPUtils.getString(Constants.SP_HOME_OR_DETAIL_VIDEO_OPTION, Constants.VIDEO_OPTION_WIFI)
                                ?: Constants.VIDEO_OPTION_WIFI

                        when (videoOption) {
                            Constants.VIDEO_OPTION_ALL -> {
                                autoVideoView.onVideoReset()
                                autoVideoView.startPlayLogic(false)
                            }

                            Constants.VIDEO_OPTION_WIFI -> {
                                if (NetworkUtils.isWifiConnected(HaloApp.getInstance().application)) {
                                    autoVideoView.onVideoReset()
                                    autoVideoView.startPlayLogic(false)
                                }
                            }

                            else -> {
                                //do nothing
                            }
                        }
                    }, HOME_PUSH_VIDEO_PLAY_DELAY)
                } else {
                    resumeHomePushVideo()
                }
            }
        }
    }

    private fun setHomePush() {
        mHomePush?.run {
            mBinding?.run {
                if (game != null) {
                    gameNameTv.text = game.name
                    GameItemViewHolder.initGameSubtitleAndAdLabel(game, gameSubtitleTv)
                    updateHomePushDownloadBtn()
                    headerContainer.setOnClickListener {
                        if (mShowTwoLevel) {
                            mHomePushClick = true
                            GameDetailActivity.startGameDetailActivity(
                                requireContext(),
                                game.id,
                                "(新首页-下拉推送)",
                                mExposureEvent
                            )
                        }
                    }
                }
                descTv.text = description
                gameImageIv.goneIf(video != null) {
                    ImageUtils.display(gameImageIv, imgUrl)
                }
                autoVideoView.goneIf(video == null) {
                    if (!autoVideoView.isInPlayingState) {
                        GSYVideoOptionBuilder()
                            .setIsTouchWiget(false)
                            .setUrl(video?.url ?: "")
                            .setRotateViewAuto(false)
                            .setCacheWithPlay(true)
                            .setRotateWithSystem(false)
                            .setReleaseWhenLossAudio(true)
                            .setLooping(false)
                            .setShowFullAnimation(false)
                            .build(autoVideoView)
                        autoVideoView.updateThumb(imgUrl)
                        autoVideoView.setParamsData(game, null)
                        autoVideoView.setOnVideoClickListener {
                            headerContainer.performClick()
                        }
                    }
                }
            }
        }
    }

    fun popUpHomePushIfNeeded() {
        mBinding?.run {
            if (mFragmentList.safelyGetInRelease(viewPager.currentItem) !is HomeFragment) return
            mHomePush?.run {
                val homePushSet = HashSet(SPUtils.getStringSet(Constants.SP_HOME_PUSH_POP_UP_SET))
                if (popSwitch == "on" && !homePushSet.contains(id)) {
                    // 自动弹出，5s后自动收起
                    twoLevelHeader.openTwoLevel(true)
                    wrapperLl.clipChildren = false
                    mBinding?.refreshLayout?.clipChildren = false
                    headerBackground.animate().alpha(0F).duration = AUTO_OPEN_TWO_LEVEL_DURATION
                    statusBarBackground.animate().alpha(0F).duration = AUTO_OPEN_TWO_LEVEL_DURATION
                    toolbarBackground.animate().alpha(0F).duration = AUTO_OPEN_TWO_LEVEL_DURATION
                    classicsHeader.visibility = View.INVISIBLE
                    homePushSet.add(id)
                    SPUtils.setStringSet(Constants.SP_HOME_PUSH_POP_UP_SET, homePushSet)
                    mBaseHandler.postDelayed({
                        finishTwoLevel("自动收起")
                    }, AUTO_FINISH_TWO_LEVEL_DELAY)
                }
            }
        }
    }

    private fun pauseHomePushVideo() {
        mBinding?.run {
            if (mShowTwoLevel && !mHomePush?.video?.url.isNullOrEmpty()) {
                autoVideoView.onVideoPause()
                val currentPosition = autoVideoView.getCurrentPosition()
                val videoUrl = autoVideoView.getUrl()
                if (videoUrl.isNotEmpty()) {
                    ScrollCalculatorHelper.savePlaySchedule(MD5Utils.getContentMD5(videoUrl), currentPosition)
                }
            }
        }
    }

    private fun resumeHomePushVideo() {
        mBinding?.run {
            if (mShowTwoLevel && !mHomePush?.video?.url.isNullOrEmpty()) {
                val videoUrl = autoVideoView.getUrl()
                if (videoUrl.isNotEmpty()) {
                    val position = ScrollCalculatorHelper.getPlaySchedule(MD5Utils.getContentMD5(videoUrl))
                    //这里必须要延迟操作，否则会白屏
                    mBaseHandler.postDelayed({
                        if (position != 0L) {
                            autoVideoView.seekTo(position)
                            autoVideoView.onVideoResume(false)
                            val topVideoVoiceStatus = SPUtils.getBoolean(Constants.SP_VIDEO_PLAY_MUTE, true)
                            if (topVideoVoiceStatus) {
                                autoVideoView.mute()
                            } else {
                                autoVideoView.unMute()
                            }
                        } else {
                            autoVideoView.release()
                        }
                    }, HOME_PUSH_VIDEO_PLAY_DELAY)
                }
            }
        }
    }

    override fun onFragmentPause() {
        super.onFragmentPause()
        pauseHomePushVideo()
        DownloadManager.getInstance().removeObserver(dataWatcher)
    }

    // 下载被删除事件
    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onEventMainThread(status: EBDownloadStatus) {
        if ("delete" == status.status) {
            if (status.gameId == mHomePush?.game?.id) {
                updateHomePushDownloadBtn()
            }
        }
    }

    // 安装/卸载 事件
    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onEventMainThread(busFour: EBPackage) {
        if (busFour.isInstalledOrUninstalled()) {
            updateHomePushDownloadBtn()
        }
    }

    fun finishRefresh() {
        mBinding?.refreshLayout?.finishRefresh(true)
    }

    fun finishTwoLevel(action: String) {
        if (mShowTwoLevel) {
            mBinding?.twoLevelHeader?.finishTwoLevel()
            mElapsedHelper.pauseCounting()
            mHomePush?.run {
                com.gh.common.util.NewFlatLogUtils.logHomePushClose(
                    id,
                    action,
                    mTwoLevelOpenCount,
                    game?.id ?: "",
                    game?.name ?: "",
                    mElapsedHelper.elapsedTime
                )
            }
        }
    }

    override fun onFragmentResume() {
        super.onFragmentResume()
        refreshStatusBarStyle()
        resumeHomePushVideo()
        DownloadManager.getInstance().addObserver(dataWatcher)
        updateHomePushDownloadBtn()
    }

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

    override fun getInflatedLayout() =
        FragmentMainHomeWrapperBinding.inflate(layoutInflater).apply { mBinding = this }.root

    private fun initViewPager(tabEntityList: ArrayList<SubjectRecommendEntity>) {
        val fragmentList = generateFragments(tabEntityList).apply { mFragmentList = this }
        val tabTitleList = arrayListOf<String>()

        tabEntityList.forEach { tabTitleList.add(it.name ?: "") }

        mBinding?.run {
            viewPager.offscreenPageLimit = fragmentList.size
            viewPager.doOnScroll(
                onPageSelected = { position ->
                    refreshLayout.setEnableRefresh(getFragment(position) is HomeFragment && mHomePush != null)
                    if (mShowTwoLevel) finishTwoLevel("跳转收起")
                    notifyChildFragmentLifecycle(position)
                    mViewModel?.forumTabPairs?.forEach { pair ->
                        if (pair.first == position) {
                            DirectUtils.directForumDetail(requireContext(), pair.second, "首页")
                            viewPager.post { viewPager.currentItem = position - 1 }
                        }
                    }
                    tabEntityList.safelyGetInRelease(position)?.let { logTabSelected(it, position) }
                },
                onPageScrolled = { position, positionOffset, _ ->
                    onPageScrolled(position, positionOffset, tabEntityList)
                }
            )

            setRestoredCurItem(viewPager)
            viewPager.adapter = FragmentAdapter(childFragmentManager, fragmentList, tabTitleList)
            tabLayout.setupWithViewPager(mBinding?.viewPager)
            indicatorView.setupWithTabLayout(mBinding?.tabLayout)
            indicatorView.setupWithViewPager(mBinding?.viewPager)
            indicatorView.setIndicatorWidth(18)

            initTabView(tabEntityList)
        }
    }

    private fun updateIndicatorDrawable(indicatorView: TabIndicatorView?) {
        if (mIsDisplayingLightContent) {
            indicatorView?.updateIndicatorDrawable(R.drawable.ic_home_tab_indicator_white.toDrawable(requireContext()))
        } else {
            indicatorView?.updateIndicatorDrawable(R.drawable.ic_commodity_selected.toDrawable(requireContext()))
        }
    }

    private fun onPageScrolled(position: Int, positionOffset: Float, tabEntityList: ArrayList<SubjectRecommendEntity>) {
        val nextPosition = position + 1

        // TODO 避免高频调用 toColor 方法
        val backgroundColor = R.color.background.toColor(requireContext())
        val backgroundWhiteColor = R.color.background_white.toColor(requireContext())
        val amwayPrimaryColor = R.color.amway_primary_color.toColor(requireContext())
        val tabDefaultColor = TAB_DEFAULT_COLOR.toColor(requireContext())
        val tabSelectedColor = TAB_SELECTED_COLOR.toColor(requireContext())
        val tabDefaultLightColor = TAB_DEFAULT_COLOR_LIGHT.toColor(requireContext())

        val tabEntity = tabEntityList.safelyGetInRelease(position)

        // 处理当前 tab 和下一个 tab
        if (nextPosition != mTabBindingList.size) {
            val nextTabEntity = tabEntityList.safelyGetInRelease(nextPosition)
            var currentAppBarColor = tabEntity?.primaryColor ?: backgroundWhiteColor
            var nextAppBarColor = nextTabEntity?.primaryColor ?: backgroundWhiteColor

            if (currentAppBarColor == Color.WHITE) currentAppBarColor = backgroundWhiteColor
            if (nextAppBarColor == Color.WHITE) nextAppBarColor = backgroundWhiteColor

            if (getFragment(position) is AmwayFragment) {
                currentAppBarColor = if (mIsDarkModeOn) backgroundColor else amwayPrimaryColor
                tabEntity?.currentSelectColor = currentAppBarColor
            }
            if (getFragment(nextPosition) is AmwayFragment) {
                nextAppBarColor = if (mIsDarkModeOn) backgroundColor else amwayPrimaryColor
            }

            val proximatelySelectedTabEntity = if (positionOffset < 0.5) tabEntity else nextTabEntity

            val appBarColorInBetween = if (currentAppBarColor == nextAppBarColor) {
                currentAppBarColor
            } else {
                ColorUtils.blendARGB(currentAppBarColor, nextAppBarColor, positionOffset)
            }

            // 颜色显示是否变更
            val isContentStyleChanged =
                proximatelySelectedTabEntity?.useLightStyle != mIsDisplayingLightContent
            mIsDisplayingLightContent = proximatelySelectedTabEntity?.useLightStyle ?: false

            if (!mShowTwoLevel) {
                mTabSelectedColor =
                    if (mIsDisplayingLightContent) tabDefaultLightColor else tabSelectedColor
                mTabDefaultColor = if (mIsDisplayingLightContent) tabDefaultLightColor else tabDefaultColor
            }

            if (isContentStyleChanged) {
                if (!mShowTwoLevel) updateIndicatorDrawable(mBinding?.indicatorView)
                refreshStatusBarStyle()
            }

            mCurrentAppBarColor = appBarColorInBetween
            updateAppBarStyle(appBarColorInBetween, mIsDisplayingLightContent)
        } else {
            var currentAppBarColor = tabEntity?.primaryColor ?: backgroundWhiteColor
            if (mIsDarkModeOn && currentAppBarColor == Color.WHITE) {
                currentAppBarColor = backgroundWhiteColor
            }
            if (getFragment(position) is AmwayFragment) {
                currentAppBarColor = if (mIsDarkModeOn) backgroundColor else amwayPrimaryColor
                tabEntity?.currentSelectColor = currentAppBarColor
            }
            mIsDisplayingLightContent = tabEntity?.useLightStyle == true
            if (!mShowTwoLevel) {
                mTabSelectedColor =
                    if (mIsDisplayingLightContent) tabDefaultLightColor else tabSelectedColor
                mTabDefaultColor = if (mIsDisplayingLightContent) tabDefaultLightColor else tabDefaultColor
            }

            updateAppBarStyle(currentAppBarColor, mIsDisplayingLightContent)
            if (!mShowTwoLevel) updateIndicatorDrawable(mBinding?.indicatorView)
            refreshStatusBarStyle()
        }

        // 这里的 selectedPosition 指的是应该被高亮显示的 position
        val selectedPosition = (position + positionOffset).roundToInt()
        val positionOffsetOnRealSelectedPosition = if (positionOffset >= 0.5) {
            positionOffset - 1
        } else {
            positionOffset
        }

        updateTabStyle(selectedPosition, positionOffsetOnRealSelectedPosition)
    }

    /**
     * 更新 tab 的样式
     * @param selectedPosition 选中的 tab
     * @param positionOffset 与选中 tab 的位置偏移，为负时在选中的 tab 左边，为正时在选中 tab 的右边
     */
    private fun updateTabStyle(selectedPosition: Int, positionOffset: Float) {
        if (mTabBindingList.isEmpty()) return

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

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

        val selectedTabBinding = mTabBindingList[selectedPosition]
        val selectedTabImageStyle = mTabImageStyleList[selectedPosition]

        // 前一个 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) {
            mTabBindingList[prePosition].run {
                if (indicatorOnLeft) {
                    when (mTabImageStyleList[prePosition]) {
                        TAB_IMAGE_ALWAYS_ON -> {
                            titleIv.scaleX = preScaleRatio
                            titleIv.scaleY = preScaleRatio
                        }

                        TAB_IMAGE_HIDE_ON_SELECTED -> {
                            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
                        }
                    }

                    titleTv.textSize = (DEFAULT_TAB_TEXT_SIZE * preScaleRatio).roundTo(1)
                    titleTv.setTextColor(ColorUtils.blendARGB(mTabDefaultColor, mTabSelectedColor, abs(positionOffset)))
                } else {
                    titleTv.setTextColor(mTabDefaultColor)
                }
            }
        }

        // 更新当前选中的 tab
        selectedTabBinding.run {
            // 更新当前选中的 tab 的图片显示状态
            when (selectedTabImageStyle) {
                TAB_IMAGE_ALWAYS_ON -> {
                    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

                    mBinding?.indicatorView?.visibility = View.VISIBLE
                }
            }

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

            titleTv.textSize = (DEFAULT_TAB_TEXT_SIZE * selectedScaleRatio).roundTo(1)
            titleTv.setTextColor(ColorUtils.blendARGB(mTabDefaultColor, mTabSelectedColor, 1 - abs(positionOffset)))
        }

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

                        TAB_IMAGE_HIDE_ON_SELECTED -> {
                            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
                        }
                    }
                    titleTv.textSize = (DEFAULT_TAB_TEXT_SIZE * nextScaleRatio).roundTo(1)
                    titleTv.setTextColor(ColorUtils.blendARGB(mTabDefaultColor, mTabSelectedColor, positionOffset))
                } else {
                    titleTv.setTextColor(mTabDefaultColor)
                }
            }
        }

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

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

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

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

    fun onScrollChanged(totalHeight: Int, offset: Int) {
        val currentTab = getCurrentTabEntity()
        val backgroundWhiteColor = R.color.background_white.toColor(requireContext())
        val backgroundColor = R.color.background.toColor(requireContext())
        val amwayPrimaryColor = R.color.amway_primary_color.toColor(requireContext())
        val tabDefaultLightColor = TAB_DEFAULT_COLOR_LIGHT.toColor(requireContext())
        val tabSelectedColor = TAB_SELECTED_COLOR.toColor(requireContext())
        val tabDefaultColor = TAB_DEFAULT_COLOR.toColor(requireContext())

        currentTab?.offsetRatio = offset / totalHeight.toFloat()
        if ((currentTab?.isTopViewShow == true && offset >= totalHeight)
            || currentTab?.isSlideEmpty == true
        ) {
            currentTab.isTopViewShow = false
            currentTab.primaryColor = backgroundWhiteColor
            currentTab.useLightStyle = false
            mIsDisplayingLightContent = false
            updateAppBarColorWhenScrollChanged(backgroundWhiteColor)
            refreshStatusBarStyle()
            if (!mShowTwoLevel) {
                mTabSelectedColor = TAB_SELECTED_COLOR.toColor(requireContext())
                mTabDefaultColor = TAB_DEFAULT_COLOR.toColor(requireContext())
                mBinding?.indicatorView?.updateIndicatorDrawable(R.drawable.ic_commodity_selected.toDrawable())
                updateTabStyle(mLastSelectedPosition, 0F)
            }
        } else if (offset < totalHeight) {
            var currentSelectColor = currentTab?.currentSelectColor ?: 0
            val offsetMeetsCriticalPoint = (currentTab?.offsetRatio ?: 0F) < mOffsetCritical
            currentTab?.isTopViewShow = true
            if (getFragment(mBinding?.viewPager?.currentItem ?: 0) is AmwayFragment) {
                currentSelectColor = if (mIsDarkModeOn) backgroundColor else amwayPrimaryColor
            }
            val colorInBetween =
                ColorUtils.blendARGB(currentSelectColor, backgroundWhiteColor, currentTab?.offsetRatio ?: 0F)
            updateAppBarColorWhenScrollChanged(colorInBetween)
            currentTab?.primaryColor = colorInBetween
            currentTab?.useLightStyle = offsetMeetsCriticalPoint
            currentTab?.primaryColor = colorInBetween
            currentTab?.useLightStyle = offsetMeetsCriticalPoint
            if (mIsDisplayingLightContent != currentTab?.useLightStyle) {
                mIsDisplayingLightContent = offsetMeetsCriticalPoint
            }
            refreshStatusBarStyle()
            if (!mShowTwoLevel) {
                mTabSelectedColor = if (offsetMeetsCriticalPoint) tabDefaultLightColor else tabSelectedColor
                mTabDefaultColor = if (offsetMeetsCriticalPoint) tabDefaultLightColor else tabDefaultColor
                mBinding?.indicatorView?.updateIndicatorDrawable(
                    if (offsetMeetsCriticalPoint) {
                        R.drawable.ic_home_tab_indicator_white.toDrawable()
                    } else {
                        R.drawable.ic_commodity_selected.toDrawable()
                    }
                )
                updateTabStyle(mLastSelectedPosition, 0F)
            }
        }
    }

    private fun updateAppBarColorWhenScrollChanged(color: Int) {
        val currentTab = getCurrentTabEntity()
        if ((currentTab?.offsetRatio ?: 0F) >= 1F && color != R.color.background_white.toColor(requireContext())) {
            currentTab?.currentSelectColor = color
            currentTab?.primaryColor = color
        }
        updateAppBarStyle(color, color != R.color.background_white.toColor(requireContext()))
    }

    fun changeAppBarColor(color: Int) {
        val currentTab = getCurrentTabEntity()
        //此处的判断是防止banner在滑动过程中切换tab会导致背景设置错误
        if (currentTab?.type != "home") {
            val homeTab = mViewModel?.getHomeTabEntity()
            homeTab?.currentSelectColor = color
            if (homeTab?.isTopViewShow == true) {
                val colorInBetween =
                    ColorUtils.blendARGB(color, R.color.background_white.toColor(requireContext()), homeTab.offsetRatio)
                homeTab.primaryColor = colorInBetween
            }
        } else {
            currentTab.currentSelectColor = color
            if (currentTab.isTopViewShow) {
                val colorInBetween =
                    ColorUtils.blendARGB(
                        color,
                        R.color.background_white.toColor(requireContext()),
                        currentTab.offsetRatio
                    )
                currentTab.primaryColor = colorInBetween
                updateAppBarStyle(colorInBetween, colorInBetween != R.color.background_white.toColor(requireContext()))
            }
        }
    }

    fun getCurrentTabEntity(): SubjectRecommendEntity? {
        return if (mBinding?.viewPager != null) {
            val currentItem = mBinding?.viewPager?.currentItem ?: -1
            mViewModel?.tabs?.value?.safelyGetInRelease(currentItem)
        } else null
    }

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

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

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

    private fun generateFragments(tabEntityList: ArrayList<SubjectRecommendEntity>): ArrayList<Fragment> {
        val fragmentList = arrayListOf<Fragment>()
        for ((index, tabEntity) in tabEntityList.withIndex()) {
            val fragment = when (tabEntity.type) {
                "home" -> HomeFragment().with(Bundle())
                "top_game_comment" -> AmwayFragment().with(Bundle())
                "block" -> GameFragment().with(Bundle().apply {
                    putParcelable(EntranceConsts.KEY_BLOCK_DATA, tabEntity)
                })

                "server" -> GameServersPublishFragment().with(Bundle())
                "game_list" -> GameCollectionSquareFragment().with(Bundle().apply {
                    putString(EntranceConsts.KEY_ENTRANCE, "顶部tab")
                    putInt(EntranceConsts.KEY_TAB_INDEX, index)
                    putString(EntranceConsts.KEY_NAME, tabEntity.name)
                })

                "column_test" -> GameServersTestFragment().with(Bundle().apply {
                    putString(GameServersTestFragment.TEST_COLUMN_ID, tabEntity.link)
                })

                "category" -> CategoryDirectoryFragment().with(Bundle().apply {
                    putString(EntranceConsts.KEY_CATEGORY_ID, tabEntity.link)
                    putString(EntranceConsts.KEY_CATEGORY_TITLE, tabEntity.text)
                })

                "catalog" -> CatalogFragment().with(Bundle().apply {
                    putString(EntranceConsts.KEY_CATALOG_ID, tabEntity.link)
                    putString(EntranceConsts.KEY_CATALOG_TITLE, tabEntity.text)
                })

                "category_v2" -> CategoryV2Fragment().with(Bundle().apply {
                    putString(EntranceConsts.KEY_CATEGORY_ID, tabEntity.link)
                    putString(EntranceConsts.KEY_CATEGORY_TITLE, tabEntity.text)
                })

                "ranking", "column_collection" -> ColumnCollectionDetailFragment().with(Bundle().apply {
                    putString(EntranceConsts.KEY_ENTRANCE, "首页")
                    putString(EntranceConsts.KEY_COLLECTION_ID, tabEntity.link)
                    putInt(EntranceConsts.KEY_POSITION, 0)
                    putString(EntranceConsts.KEY_COLUMNNAME, tabEntity.text)
                    putBoolean(EntranceConsts.KEY_IS_COLUMN_COLLECTION, true)
                })

                "column" -> SubjectFragment().with(Bundle().apply {
                    putString(EntranceConsts.KEY_ENTRANCE, "首页")
                    putParcelable(
                        EntranceConsts.KEY_SUBJECT_DATA,
                        SubjectData(tabEntity.link, tabEntity.text, false)
                    )
                })

                "web" -> WebFragment().with(Bundle().apply {
                    putString(EntranceConsts.KEY_URL, tabEntity.link)
                    putString(EntranceConsts.KEY_ENTRANCE, "首页tab")
                    putBoolean(WebFragment.KEY_OPEN_NATIVE_PAGE, false)
                    putBoolean(WebFragment.KEY_ENABLE_HORIZONTAL_SCROLL_DISPATCH, true)
                    if (tabEntity.link?.contains("leave_web_page_handle_back_pressed=true") == true) {
                        putBoolean(WebFragment.KEY_LEAVE_WEB_PAGE_TO_HANDLE_BACK_PRESSED, true)
                    }
                })

                "common_collection" -> CommonCollectionDetailFragment().with(Bundle().apply {
                    putString(EntranceConsts.KEY_ENTRANCE, "首页顶部Tab栏")
                    putString(EntranceConsts.KEY_COLLECTION_ID, tabEntity.link)
                    putString(EntranceConsts.KEY_COLUMNNAME, tabEntity.text)
                })

                "explore_column" -> DiscoveryFragment().with(Bundle().apply {
                    putString(EntranceConsts.KEY_ENTRANCE, "首页")
                    putInt(EntranceConsts.KEY_POSITION, index)
                })

                "column_test_v2" -> GameServerTestV2Fragment().with(Bundle().apply {
                    putString(EntranceConsts.KEY_ENTRANCE, "首页")
                    putInt(EntranceConsts.KEY_POSITION, index)
                    putParcelable(
                        EntranceConsts.KEY_EXPOSURE_SOURCE,
                        ExposureSource("顶部tab", tabEntity.name ?: "")
                    )
                })

                "bbs" -> Fragment()
                else -> Fragment()
            }
            fragment.arguments?.putInt(EntranceConsts.KEY_TAB_COUNT, tabEntityList.size)
            fragment.arguments?.putBoolean(EntranceConsts.KEY_IS_HOME, true)
            if (fragment.arguments?.getParcelable<ExposureSource>(EntranceConsts.KEY_EXPOSURE_SOURCE) == null) {
                fragment.arguments?.putParcelable(
                    EntranceConsts.KEY_EXPOSURE_SOURCE,
                    ExposureSource("首页顶部Tab栏", tabEntity.name ?: "")
                )
            }
            fragmentList.add(fragment)
        }
        return fragmentList
    }

    /**
     * 更新 AppBar 的控件 style
     */
    private fun updateAppBarStyle(color: Int, useLightStyle: Boolean) {
        mBinding?.toolbarBgView?.setBackgroundColor(color)
        mBinding?.statusBar?.setBackgroundColor(color)
        mBinding?.headerBgView?.setBackgroundColor(color)
        mBinding?.tabBgView?.setOnlyTopRoundedColorBackground(color, 8F)

        mSearchToolbarFragment.updateStyle(mIsDarkModeOn || useLightStyle)
    }

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

    override fun onBackPressed(): Boolean {
        if (mShowTwoLevel) {
            finishTwoLevel("主动收起")
            return true
        }
        mBinding?.viewPager?.run {
            val currentFragment = mFragmentList.safelyGetInRelease(currentItem)
            if (currentFragment is WebFragment) {
                return currentFragment.onBackPressed()
            }
        }
        return super.onBackPressed()
    }

    private fun updateTabAndToolbarStyle() {
        mViewModel?.tabs?.value?.forEach {
            if (it.type != "top_game_comment") {
                it.primaryColor = R.color.background_white.toColor(requireContext())
            }
        }
        mBinding?.viewPager?.currentItem?.let {
            if (it < mFragmentList.size) {
                when (mFragmentList[it]) {
                    is HomeFragment -> (mFragmentList[it] as HomeFragment).onScrollChanged()
                    is AmwayFragment -> (mFragmentList[it] as AmwayFragment).onScrollChanged()
                    else -> onScrollChanged(0, 0)
                }
            }
        }
        mBinding?.run {
            tabBackground.setOnlyTopRoundedColorBackground(R.color.background_white.toColor(requireContext()), 8F)
            toolbarBackground.setBackgroundColor(R.color.background_white.toColor(requireContext()))
            if (mShowTwoLevel) {
                updateBackgroundAlpha(mHeaderOffset)
            }
        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    override fun onEventMainThread(reuse: EBReuse) {
        super.onEventMainThread(reuse)
        if (reuse.type == EntranceConsts.HOST_HOME_GAME_COLLECTION_SQUARE) {
            mFragmentList.forEachIndexed { index, fragment ->
                if (fragment is GameCollectionSquareFragment) {
                    mBinding?.viewPager?.currentItem = index
                }
            }
        }
        if (reuse.type == Constants.FINISH_HOME_PUSH) {
            if (!mHomePushClick) {
                mBaseHandler.postDelayed({
                    finishTwoLevel("跳转收起")
                }, FINISH_TWO_LEVEL_DELAY)
            }
            mHomePushClick = false
        }
    }

    /**
     * 初始化每个需要显示的 TabView
     */
    private fun initTabView(tabEntityList: ArrayList<SubjectRecommendEntity>) {
        for (i in 0 until tabEntityList.size) {
            val tabView = mBinding?.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.isNullOrEmpty()) {
                TAB_IMAGE_EMPTY
            } else if (tabEntity.showImgOnSelected == true) {
                TAB_IMAGE_ALWAYS_ON
            } else {
                TAB_IMAGE_HIDE_ON_SELECTED
            }

            mTabBindingList.add(tabViewBinding)
            mTabImageStyleList.add(tabImageStyle)

            if (!tabEntity.img.isNullOrEmpty()) {
                tabViewBinding.titleTv.visibility = View.GONE
                tabViewBinding.invisibleTitleTv.visibility = View.GONE
                tabViewBinding.titleIv.setFixedHeight(16)
                tabViewBinding.titleIv.display(tabEntity.img)
                tabViewBinding.titleIv.registerLoadingCallback(object : WrapContentDraweeView.LoadingCallback {
                    override fun loaded() {
                        postRunnable {
                            mBinding?.run {
                                // 图片 layout 完成后，更新 tabBar 和 indicatorView 的位置，避免偏移
                                tabLayout.setScrollPosition(viewPager.currentItem, 0F, false)
                                indicatorView.generatePath(viewPager.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 {
                if (mShowTwoLevel) {
                    mBinding?.twoLevelHeader?.setFloorDuration(100)
                    mBinding?.refreshLayout?.setFloorDuration(100)
                    finishTwoLevel("跳转收起")
                }
            }

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

    /**
     * 刷新状态栏风格 （亮色或暗色）
     * 因为调用此方法损耗较大，所以需要在状态变更时才调用
     */
    private fun refreshStatusBarStyle() {
        DisplayUtils.setLightStatusBar(requireActivity(), !mIsDisplayingLightContent && !mIsDarkModeOn)
    }

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

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

    /**
     * 记录 tab 被选中的日志
     */
    private fun logTabSelected(tabEntity: SubjectRecommendEntity, position: Int) {
        LogUtils.logHomeTopTabClick(tabEntity.name, tabEntity.type, tabEntity.text, tabEntity.link, position)

        SensorsBridge.trackEvent("HomeTopTabSelect",
            json {
                "position" to position
                "tab_content" to tabEntity.name
            }
        )

        if (tabEntity.type == "common_collection") {
            NewLogUtils.logAccessToCommonCollectionDetail(
                tabEntity.link ?: "",
                tabEntity.text ?: "",
                "首页顶部Tab栏"
            )
        }
    }

    override fun onDarkModeChanged() {
        super.onDarkModeChanged()
        getCurrentTabEntity()?.isTopViewShow = true
        updateTabAndToolbarStyle()
    }

    companion object {
        const val LAST_SELECTED_POSITION = "last_selected_position"

        var TAB_SELECTED_COLOR: Int = R.color.text_title
        var TAB_DEFAULT_COLOR: Int = R.color.text_subtitle

        var TAB_DEFAULT_COLOR_LIGHT: Int = R.color.search_text_color_light

        var DEFAULT_TAB_TEXT_SIZE = 16F

        const val HOME_PUSH_VIDEO_PLAY_DELAY = 100L
        const val AUTO_FINISH_TWO_LEVEL_DELAY = 5000L
        const val FINISH_TWO_LEVEL_DELAY = 1000L
        const val AUTO_OPEN_TWO_LEVEL_DURATION = 1000L
        const val PULL_TAB_TEXT_STYLE_UPDATE_PERCENT = 0.5F

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

}