package com.gh.gamecenter.wrapper

import android.graphics.Typeface
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.os.Message
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
import android.view.ViewGroup.MarginLayoutParams
import android.view.ViewTreeObserver
import android.widget.FrameLayout
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.TextView
import androidx.appcompat.widget.ActionMenuView
import androidx.appcompat.widget.Toolbar
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.view.isVisible
import androidx.core.view.updateLayoutParams
import androidx.fragment.app.Fragment
import com.facebook.drawee.view.SimpleDraweeView
import com.gh.common.exposure.ExposureManager
import com.gh.common.iinterface.IMultiTab
import com.gh.common.iinterface.ISmartRefresh
import com.gh.common.iinterface.ISmartRefreshContent
import com.gh.common.prioritychain.PullDownPushHandler
import com.gh.common.util.DirectUtils
import com.gh.common.util.DownloadItemUtils
import com.gh.common.util.ViewPagerFragmentHelper
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.common.base.fragment.LazyFragment
import com.gh.gamecenter.common.base.fragment.ToolbarController
import com.gh.gamecenter.common.base.fragment.ToolbarFragment
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.exposure.ExposureSource
import com.gh.gamecenter.common.json.json
import com.gh.gamecenter.common.observer.MuteCallback
import com.gh.gamecenter.common.observer.VolumeObserver
import com.gh.gamecenter.common.tracker.IBusiness
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.core.utils.DisplayUtils
import com.gh.gamecenter.core.utils.MD5Utils
import com.gh.gamecenter.core.utils.SPUtils
import com.gh.gamecenter.core.utils.TimeElapsedHelper
import com.gh.gamecenter.databinding.FragmentToolbarWrapperBinding
import com.gh.gamecenter.entity.GameUpdateEntity
import com.gh.gamecenter.entity.PullDownPush
import com.gh.gamecenter.eventbus.EBDownloadStatus
import com.gh.gamecenter.feature.exposure.ExposureEvent
import com.gh.gamecenter.feature.exposure.time.TimeUtil
import com.gh.gamecenter.feature.game.GameItemViewHolder
import com.gh.gamecenter.home.video.ScrollCalculatorHelper
import com.gh.gamecenter.packagehelper.PackageViewModel
import com.halo.assistant.HaloApp
import com.lightgame.OnTitleClickListener
import com.lightgame.download.DataWatcher
import com.lightgame.download.DownloadEntity
import com.lightgame.listeners.OnBackPressedListener
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.listener.GSYSampleCallBack
import com.shuyu.gsyvideoplayer.video.base.GSYVideoView
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import org.json.JSONObject

/**
 * 带常规标题栏Toolbar的外层Fragment，支持下拉推送
 */
class ToolbarWrapperFragment : LazyFragment(), ToolbarController, ISmartRefresh, OnBackPressedListener, IBusiness {
    private lateinit var mBinding: FragmentToolbarWrapperBinding
    private var mContentFragment: Fragment? = null
    private var mToolbarContainer: View? = null
    private var mToolbar: Toolbar? = null
    private var mTitleTv: TextView? = null
    private var mAdLabelTv: TextView? = null
    private var mTitleContainer: ConstraintLayout? = null
    private var mIconTitleContainer: LinearLayout? = null
    private var mBackContainer: FrameLayout? = null
    private var mActionMenuView: ActionMenuView? = null
    private var mBackBtn: ImageView? = null
    private var mUserAvatarIv: SimpleDraweeView? = null
    private var mIconTitle: TextView? = null
    private var mDownloadBtn: ImageView? = null
    private var mShowDownloadMenu = false
    private var mDownloadCountHint: TextView? = null
    private var mPackageViewModel: PackageViewModel? = null
    private var mPullDownPushAction = "" // 触发行为（主动展开/自动展开）
    private var mShowTwoLevel = false
    private var mIsDragging = false
    private var mPullDownPushClick = false
    private var mHeaderOffset = 0
    private var mClipChildren = true
    private var mTwoLevelOpenOffset = 0
    private var mTwoLevelOpenCount = 0
    private var mShowTwoLevelStartOffset = 0
    private var mPullDownPush: PullDownPush? = null
    private var mPullDownPushExposureEvent: ExposureEvent? = null
    private var mGameViewHolder: GameViewHolder? = null
    private val mStatusBarHeight by lazy { DisplayUtils.getStatusBarHeight(requireContext().resources) }
    private var mLightToolbar = false
    private var mAutoFinishTwoLevelHandler: Handler? = null
    private var mAutoFinishTwoLevelCallback: (() -> Unit)? = null
    private val mVolumeObserver by lazy {
        VolumeObserver(object : MuteCallback {
            override fun onMute(isMute: Boolean) {
                if (::mBinding.isInitialized) {
                    mBinding.muteIv.setImageResource(if (isMute) R.drawable.ic_basic_offsound else R.drawable.ic_basic_onsound)
                    if (isMute) {
                        mBinding.autoVideoView.mute()
                    } else {
                        mBinding.autoVideoView.unMute()
                    }
                }
            }
        })
    }

    private lateinit var mElapsedHelper: TimeElapsedHelper

    private val mDataWatcher = object : DataWatcher() {
        override fun onDataChanged(downloadEntity: DownloadEntity) {
            if (downloadEntity.gameId == mPullDownPush?.game?.id) {
                updatePullDownPushDownloadBtn()
            }
        }

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

    override fun getRealLayoutId(): Int = R.layout.fragment_toolbar_wrapper

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        mShowDownloadMenu = arguments?.getBoolean(EntranceConsts.KEY_SHOW_DOWNLOAD_MENU, false) ?: false
    }

    override fun onRealLayoutInflated(inflatedView: View) {
        mBinding = FragmentToolbarWrapperBinding.bind(inflatedView)
        mToolbarContainer = mBinding.toolbar.normalToolbarContainer
        mToolbar = mBinding.toolbar.normalToolbar
        mTitleTv = mBinding.toolbar.normalTitle
        mAdLabelTv = mBinding.toolbar.adLabelTv
        mActionMenuView = mBinding.toolbar.actionMenuView
        mTitleContainer = mBinding.toolbar.titleContainer
        mIconTitleContainer = mBinding.toolbar.iconTitleContainer
        mBackContainer = mBinding.toolbar.backContainer
        mBackBtn = mBinding.toolbar.backBtn
        mUserAvatarIv = mBinding.toolbar.userAvatar
        mIconTitle = mBinding.toolbar.iconTitle

        initToolbar()

        tryWithDefaultCatch {
            if (arguments != null) {
                val className = requireArguments().getString(ViewPagerFragmentHelper.WRAPPER_FRAGMENT_NAME, "")
                mContentFragment =
                    childFragmentManager.findFragmentById(R.id.wrapper_main_content) ?: Class.forName(className)
                        .getDeclaredConstructor().newInstance() as Fragment
                mContentFragment!!.arguments = requireArguments().clone() as Bundle
            }
        }
        if (mContentFragment != null) {
            childFragmentManager.beginTransaction()
                .replace(R.id.wrapper_main_content, mContentFragment!!)
                .commitAllowingStateLoss()
        }
    }

    override fun onFragmentFirstVisible() {
        super.onFragmentFirstVisible()
        mElapsedHelper = TimeElapsedHelper()

        if (!SPUtils.getBoolean(Constants.SP_TEENAGER_MODE) && mShowDownloadMenu) {
            mPackageViewModel = viewModelProvider(PackageViewModel.Factory())
            mPackageViewModel?.filterSameUpdateLiveData?.observe(this) { updateList: List<GameUpdateEntity> ->
                updateDownloadCountHint(updateList)
            }
        }

        mBinding.toolbar.normalToolbar.background = null

        initSmartRefresh()
    }

    override fun setPullDownPush(pullDownPush: PullDownPush?, pullDownPushHandler: PullDownPushHandler?) {
        if (pullDownPush != null) {
            setSmartRefreshEnabled(true)
            if ((mPullDownPush?.id ?: "") == pullDownPush.id) return
            mPullDownPush = pullDownPush
            mPullDownPush?.run {
                if (game != null) {
                    game.sequence = 1
                    mPullDownPushExposureEvent = ExposureEvent.createEventWithSourceConcat(
                        game,
                        basicSource = listOf(ExposureSource("自定义页面", "$customPageName+$customPageId")),
                        source = listOf(ExposureSource("下拉推送", id))
                    )
                }

                mBinding.run {
                    if (game != null) {
                        gameNameTv.text = game.name
                        GameItemViewHolder.initGameSubtitleAndAdLabel(game, gameSubtitleTv)
                        updatePullDownPushDownloadBtn()
                        headerContainer.setOnClickListener {
                            if (mShowTwoLevel) {
                                mPullDownPushClick = true
                                SensorsBridge.trackEvent(
                                    "DropDownPushClick",
                                    json {
                                        "action" to mPullDownPushAction
                                        "button_name" to "游戏详情"
                                        "drop_down_push_id" to id
                                        "game_name" to game.name
                                        "game_id" to game.id
                                        getPageInfo().forEach { (key, value) ->
                                            key to value
                                        }
                                    }
                                )
                                GameDetailActivity.startGameDetailActivity(
                                    requireContext(),
                                    game.id,
                                    "(自定义页面-下拉推送)",
                                    mPullDownPushExposureEvent
                                )
                            }
                        }
                    }
                    descTv.text = description
                    gameImageIv.goneIf(video != null) {
                        ImageUtils.display(gameImageIv, imgUrl)
                    }
                    muteIv.isVisible = video != null
                    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)

                            // 处理部分设备下拉推送自动弹出时封面图高度为1 https://jira.shanqu.cc/browse/GHZS-4986
                            autoVideoView.thumbImage.viewTreeObserver.addOnGlobalLayoutListener(object :
                                ViewTreeObserver.OnGlobalLayoutListener {
                                override fun onGlobalLayout() {
                                    if (autoVideoView.thumbImage.height == 1) {
                                        autoVideoView.thumbImage.requestLayout()
                                    } else {
                                        autoVideoView.thumbImage.viewTreeObserver.removeOnGlobalLayoutListener(this)
                                    }
                                }
                            })

                            autoVideoView.setParamsData(game, null)
                            autoVideoView.setOnVideoClickListener {
                                headerContainer.performClick()
                            }
                        }
                        var videoVoiceStatus = SPUtils.getBoolean(Constants.SP_VIDEO_PLAY_MUTE, true)
                        muteIv.setImageResource(if (videoVoiceStatus) R.drawable.ic_basic_offsound else R.drawable.ic_basic_onsound)
                        muteIv.setDebouncedClickListener {
                            videoVoiceStatus = !videoVoiceStatus
                            muteIv.setImageResource(if (videoVoiceStatus) R.drawable.ic_basic_offsound else R.drawable.ic_basic_onsound)
                            if (videoVoiceStatus) {
                                autoVideoView.mute()
                            } else {
                                autoVideoView.unMute()
                            }
                        }
                    }
                }
            }
        }

        val pullDownPushSet =
            SPUtils.getStringSet(Constants.SP_PULL_DOWN_PUSH_POP_UP_SET)
        val popupPush = mPullDownPush != null
                && "on" == mPullDownPush!!.popSwitch
                && !pullDownPushSet.contains(mPullDownPush!!.id)
        pullDownPushHandler?.doPreProcess(this as? ISmartRefresh, popupPush)
    }

    private fun observeVolume() {
        context?.applicationContext?.contentResolver?.registerContentObserver(
            android.provider.Settings.System.CONTENT_URI,
            true,
            mVolumeObserver
        )
    }

    private fun unObserveVolume() {
        context?.applicationContext?.contentResolver?.unregisterContentObserver(mVolumeObserver)
    }

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

    override fun onFragmentResume() {
        super.onFragmentResume()
        refreshStatusBarStyle()
        setTitleCenter()
        DownloadManager.getInstance().addObserver(mDataWatcher)
    }

    private fun inflateMenu(res: Int) {
        requireActivity().menuInflater.inflate(res, mActionMenuView?.menu)
        if (!SPUtils.getBoolean(Constants.SP_TEENAGER_MODE) && mShowDownloadMenu) {
            createDownloadMenu(res)
        }
    }

    private fun createDownloadMenu(res: Int) {
        if (res != R.menu.menu_download) {
            requireActivity().menuInflater.inflate(R.menu.menu_download, mActionMenuView?.menu)
        }
        if (mPackageViewModel != null) {
            updateDownloadCountHint(mPackageViewModel?.filterSameUpdateLiveData?.value)
        }
        val downloadMenuView = mActionMenuView?.menu?.findItem(R.id.menu_download)?.actionView
        mDownloadCountHint = downloadMenuView?.findViewById(R.id.menu_download_count_hint)
        mDownloadCountHint?.typeface =
            Typeface.createFromAsset(requireActivity().assets, Constants.DIN_FONT_PATH)
        mDownloadBtn = downloadMenuView?.findViewById(R.id.menu_download_iv)
        mDownloadBtn?.setColorFilter(com.gh.gamecenter.common.R.color.text_primary.toColor(requireContext()))
    }

    private fun updateDownloadCountHint(updateList: List<GameUpdateEntity>?) {
        if (mDownloadCountHint == null) return
        val count = DownloadManager.getInstance().getDownloadOrUpdateCount(updateList)
        mDownloadCountHint?.goneIf(count == null) {
            mDownloadCountHint?.text = count!!
            val params = mDownloadCountHint?.layoutParams
            params?.width = if (count.isEmpty()) 6F.dip2px() else ConstraintLayout.LayoutParams.WRAP_CONTENT
            params?.height = if (count.isEmpty()) 6F.dip2px() else 14F.dip2px()
            (params as? MarginLayoutParams)?.setMargins(
                0,
                if (count.isEmpty()) 0 else (-4F).dip2px(),
                if (count.isEmpty()) (-4F).dip2px() else (-8F).dip2px(),
                0
            )
            mDownloadCountHint?.setPadding(
                if (count.isEmpty()) 0 else 4F.dip2px(),
                0,
                if (count.isEmpty()) 0 else 4F.dip2px(),
                0
            )
            mDownloadCountHint?.minWidth = if (count.isEmpty()) 0 else 14F.dip2px()
            mDownloadCountHint?.layoutParams = params
        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onEventMainThread(status: EBDownloadStatus?) {
        if (!SPUtils.getBoolean(Constants.SP_TEENAGER_MODE) && mShowDownloadMenu && mPackageViewModel != null) {
            updateDownloadCountHint(mPackageViewModel?.filterSameUpdateLiveData?.value)
        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onEventMainThread(reuse: EBReuse) {
        if (reuse.type == Constants.FINISH_PULL_DOWN_PUSH) {
            if (!mPullDownPushClick) {
                mBaseHandler.postDelayed({
                    finishTwoLevel("跳转收起")
                }, FINISH_TWO_LEVEL_DELAY)
            }
            mPullDownPushClick = false
        }
    }

    // 设置标题居中
    override fun setTitleCenter() {
        if (mActionMenuView != null && mTitleContainer != null && mBackContainer != null) {
            mActionMenuView!!.post {
                val params =
                    mTitleContainer!!.layoutParams as LinearLayout.LayoutParams
                params.setMargins(mActionMenuView!!.width - mBackContainer!!.width, 0, 0, 0)
                mTitleContainer!!.layoutParams = params
            }
        }
    }

    private fun initToolbar() {
        mBackBtn?.isVisible = !requireArguments().getBoolean(EntranceConsts.KEY_IS_HOME, false)
        mBackBtn?.setOnClickListener { requireActivity().onBackPressed() }
        mTitleTv?.setOnClickListener {
            val fragmentList = childFragmentManager.fragments
            for (fragment in fragmentList) {
                if (fragment is OnTitleClickListener) {
                    (fragment as OnTitleClickListener).onTitleClick()
                }
            }
        }
    }

    private fun getPageInfo(): Map<String, Any?> {
        val customPageName = (mContentFragment as? IMultiTab)?.provideCurrentTabEntity()?.link?.text ?:
            arguments?.getString(EntranceConsts.KEY_CUSTOM_PAGE_NAME) ?: ""
        val customPageId = (mContentFragment as? IMultiTab)?.provideCurrentTabEntity()?.link?.link ?:
            arguments?.getString(EntranceConsts.KEY_CUSTOM_PAGE_ID) ?: ""
        return mapOf(
            "position" to (mContentFragment as? IMultiTab)?.provideLastSelectedPosition(),
            "tab_content" to (mContentFragment as? IMultiTab)?.provideCurrentTabEntity()?.name,
            "custom_page_name" to customPageName,
            "custom_page_id" to customPageId,
            "several_tab_page_name" to (mContentFragment as? IMultiTab)?.provideMultiTabName(),
            "several_tab_page_id" to (mContentFragment as? IMultiTab)?.provideMultiTabId(),
        )
    }

    private fun initSmartRefresh() {
        mBinding.run {
            mGameViewHolder = GameViewHolder(headerContainer).also {
                it.gameDownloadBtn = downloadBtn
                it.multiVersionDownloadTv = multiVersionDownloadTv
                it.gameDownloadTips = downloadTipsLottie
            }
            topMaskView.updateLayoutParams<ViewGroup.LayoutParams> {
                height = mStatusBarHeight + TOOLBAR_HEIGHT.dip2px()
            }
            mTwoLevelOpenOffset = DisplayUtils.getScreenWidth() - TOOLBAR_HEIGHT.dip2px() - mStatusBarHeight
            mShowTwoLevelStartOffset = 139F.dip2px() - mStatusBarHeight
            backgroundContainer.setOnlyTopRoundedColorBackground(com.gh.gamecenter.common.R.color.ui_surface.toColor(requireContext()), 8F)
            classicsHeader.setArrowResource(R.drawable.icon_arrow)
            classicsHeader.setArrowColorFilter(com.gh.gamecenter.common.R.color.text_tertiary.toColor(requireContext()))
            statusBar.post {
                twoLevelHeader.updateLayoutParams<MarginLayoutParams> {
                    topMargin = -(mStatusBarHeight + TOOLBAR_HEIGHT.dip2px())
                }
            }
            refreshLayout.setOnMultiPurposeListener(object : SimpleMultiPurposeListener() {
                override fun onRefresh(refreshLayout: RefreshLayout) {
                    SensorsBridge.trackEvent("CustomPageFlush", JSONObject(getPageInfo()))
                    (mContentFragment as? ISmartRefreshContent)?.onRefresh()
                }

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

                override fun onStateChanged(
                    refreshLayout: RefreshLayout,
                    oldState: RefreshState,
                    newState: RefreshState
                ) {
                    (mContentFragment as? ISmartRefreshContent)?.onStateChanged(refreshLayout, oldState, newState)

                    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

                    mPullDownPush?.run {
                        if (isAutoScrollToTwoLevel) {
                            mPullDownPushAction = "自动展开"
                            mTwoLevelOpenCount++
                            SensorsBridge.trackEvent(
                                "DropDownPushShow",
                                json {
                                    "action" to "自动展开"
                                    "drop_down_push_id" to id
                                    "game_name" to game?.name
                                    "game_id" to game?.id
                                    getPageInfo().forEach { (key, value) ->
                                        key to value
                                    }
                                }
                            )
                            com.gh.common.util.NewFlatLogUtils.logHomePushShow(
                                id,
                                "自动展开",
                                mTwoLevelOpenCount,
                                game?.id ?: "",
                                game?.name ?: ""
                            )
                        }
                        if (isShowTwoLevelByDrag) {
                            mPullDownPushAction = "主动展开"
                            SensorsBridge.trackEvent(
                                "DropDownPushShow",
                                json {
                                    "action" to "主动展开"
                                    "drop_down_push_id" to id
                                    "game_name" to game?.name
                                    "game_id" to game?.id
                                    getPageInfo().forEach { (key, value) ->
                                        key to value
                                    }
                                }
                            )
                            com.gh.common.util.NewFlatLogUtils.logHomePushShow(
                                id,
                                "主动展开",
                                mTwoLevelOpenCount,
                                game?.id ?: "",
                                game?.name ?: ""
                            )
                        }
                        if (isDragToTwoLevel) {
                            mTwoLevelOpenCount++

                            SensorsBridge.trackEvent(
                                "DropDownPushTrigger",
                                json {
                                    "drop_down_push_id" to id
                                    "game_name" to game?.name
                                    "game_id" to game?.id
                                    getPageInfo().forEach { (key, value) ->
                                        key to value
                                    }
                                }
                            )
                            com.gh.common.util.NewFlatLogUtils.logHomePushTrigger(
                                id,
                                mTwoLevelOpenCount,
                                game?.id ?: "",
                                game?.name ?: ""
                            )
                        }
                    }

                    if (isScrollToTwoLevel) {
                        mShowTwoLevel = true
                    }

                    if (isFinishTwoLevel) {
                        pausePullDownPushVideo()
                        mShowTwoLevel = false

                        if (mIsDragging) {
                            mAutoFinishTwoLevelHandler?.removeMessages(KEY_AUTO_FINISH_TWO_LEVEL)
                            mElapsedHelper.pauseCounting()
                            mPullDownPush?.run {
                                SensorsBridge.trackEvent(
                                    "DropDownPushClick",
                                    json {
                                        "action" to mPullDownPushAction
                                        "button_name" to "关闭推送"
                                        "drop_down_push_id" to id
                                        "game_name" to game?.name
                                        "game_id" to game?.id
                                        getPageInfo().forEach { (key, value) ->
                                            key to value
                                        }
                                    }
                                )
                                com.gh.common.util.NewFlatLogUtils.logHomePushClose(
                                    id,
                                    "主动收起",
                                    mTwoLevelOpenCount,
                                    game?.id ?: "",
                                    game?.name ?: "",
                                    mElapsedHelper.elapsedTime
                                )
                            }
                        }
                    }

                    when (newState) {
                        RefreshState.TwoLevel -> {
                            mBinding.refreshLayout.isDisableContent = false
                        }
                        RefreshState.None -> {
                            mShowTwoLevel = false
                            mIsDragging = false
                            twoLevelHeader.setFloorDuration(1000)
                            mBinding.refreshLayout.setFloorDuration(1000)
                            classicsHeader.visibility = View.VISIBLE
                        }
                        RefreshState.PullDownToRefresh -> {
                            mShowTwoLevel = false
                            mBinding.classicsHeader.updateLayoutParams<MarginLayoutParams> {
                                topMargin = mStatusBarHeight - 11F.dip2px()
                            }
                        }
                        RefreshState.PullDownCanceled,
                        RefreshState.ReleaseToRefresh -> mShowTwoLevel = false
                        else -> {
                            // do nothing
                        }
                    }

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

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

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

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

            twoLevelHeader.setOnTwoLevelListener {
                mPullDownPushExposureEvent?.timeInMillisecond = System.currentTimeMillis()
                mPullDownPushExposureEvent?.time = TimeUtil.currentTime()
                mPullDownPushExposureEvent?.payload?.sequence = mTwoLevelOpenCount
                mPullDownPushExposureEvent?.let {
                    ExposureManager.log(it)
                }
                mElapsedHelper.resetCounting()
                mElapsedHelper.resumeCounting()
                playPullDownPushVideo()
                true
            }
        }
    }

    override fun popupPullDownPush(finishCallback: () -> Unit) {
        mBinding.run {
            if ((mPullDownPush == null) || mContentFragment == null) {
                finishCallback.invoke()
                return
            }
            if (!isSupportVisible) {
                setResumeAndPauseListener {
                    if (it) {
                        popupPullDownPush(finishCallback)
                        setResumeAndPauseListener(null)
                    }
                }
                return
            }

            // 自动弹出时禁止一切手势操作，避免动画冲突造成界面混乱
            refreshLayout.isDisableContent = true

            // 自动弹出
            mBaseHandler.post {
                mPullDownPush?.run {
                    val pullDownPushSet = HashSet(SPUtils.getStringSet(Constants.SP_PULL_DOWN_PUSH_POP_UP_SET))
                    mShowTwoLevel = true
                    twoLevelHeader.openTwoLevel(true)
                    wrapperLl.clipChildren = false
                    refreshLayout.clipChildren = false
                    headerBackground.animate().alpha(0F).duration = AUTO_OPEN_TWO_LEVEL_DURATION
                    toolbarBackground.animate().alpha(0F).duration = AUTO_OPEN_TWO_LEVEL_DURATION
                    classicsHeader.visibility = View.INVISIBLE
                    pullDownPushSet.add(id)
                    SPUtils.setStringSet(Constants.SP_PULL_DOWN_PUSH_POP_UP_SET, pullDownPushSet)
                    mAutoFinishTwoLevelHandler = object : Handler(Looper.getMainLooper()) {
                        override fun handleMessage(msg: Message) {
                            super.handleMessage(msg)
                            finishTwoLevel("自动收起")
                            finishCallback.invoke()
                        }
                    }
                    when {
                        putAwaySwitch == "video_finished" && video != null -> {
                            autoVideoView.setVideoAllCallBack(object : GSYSampleCallBack() {
                                override fun onAutoComplete(url: String?, vararg objects: Any?) {
                                    super.onAutoComplete(url, *objects)
                                    mAutoFinishTwoLevelHandler?.sendEmptyMessage(SearchToolbarTabWrapperFragment.KEY_AUTO_FINISH_TWO_LEVEL)
                                    autoVideoView.setVideoAllCallBack(null)
                                }
                            })
                        }
                        putAwaySwitch.toIntOrNull() != null -> {
                            val autoFinishDelayTime = putAwaySwitch.toInt() * 1000L
                            mAutoFinishTwoLevelHandler?.sendEmptyMessageDelayed(SearchToolbarTabWrapperFragment.KEY_AUTO_FINISH_TWO_LEVEL, autoFinishDelayTime)
                        }
                        else -> {
                            mAutoFinishTwoLevelCallback = finishCallback
                        }
                    }
                }
            }
        }
    }

    // 下拉进入/退出下拉推送时更新背景和颜色
    private fun updateStyleOnHeaderMoving(offset: Int) {
        if (context == null) return
        mBinding.run {
            val lightToolbar = offset >= mShowTwoLevelStartOffset
            if (mLightToolbar != lightToolbar) {
                mLightToolbar = lightToolbar
                refreshStatusBarStyle()
                val color = if (lightToolbar) com.gh.gamecenter.common.R.color.text_aw_primary.toColor(requireContext()) else com.gh.gamecenter.common.R.color.text_primary.toColor(requireContext())
                toolbar.normalTitle.setTextColor(color)
                mBackBtn?.setColorFilter(color)
                if (mShowDownloadMenu) {
                    mDownloadBtn?.setColorFilter(color)
                }
            }

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

    // 播放下拉推送视频
    private fun playPullDownPushVideo() {
        mBinding.run {
            if (!mPullDownPush?.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
                            }
                        }
                    }, PULL_DOWN_PUSH_VIDEO_PLAY_DELAY)
                } else {
                    resumePullDownPushVideo()
                }
                observeVolume()
            }
        }
    }

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

    private fun resumePullDownPushVideo() {
        mBinding.run {
            if (mShowTwoLevel && !mPullDownPush?.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)
                            if (autoVideoView.isMute) {
                                autoVideoView.mute()
                            } else {
                                autoVideoView.unMute()
                            }
                        } else {
                            autoVideoView.release()
                        }
                    }, PULL_DOWN_PUSH_VIDEO_PLAY_DELAY)
                }
            }
        }
    }

    private fun updatePullDownPushDownloadBtn() {
        mBinding.run {
            mPullDownPush?.game?.run {
                mGameViewHolder?.let {
                    DownloadItemUtils.updateItem(requireContext(), this, it)
                }
                DownloadItemUtils.setOnClickListener(
                    requireContext(),
                    downloadBtn,
                    this,
                    0,
                    null,
                    "自定义页面-下拉推送",
                    location = "",
                    traceEvent = mPullDownPushExposureEvent,
                    clickCallback = {
                        updatePullDownPushDownloadBtn()
                        SensorsBridge.trackEvent(
                            "DropDownPushClick",
                            json {
                                "action" to mPullDownPushAction
                                "button_name" to "下载按钮"
                                "drop_down_push_id" to id
                                "game_name" to name
                                "game_id" to id
                                getPageInfo().forEach { (key, value) ->
                                    key to value
                                }
                            }
                        )
                    },
                    refreshCallback = { updatePullDownPushDownloadBtn() },
                    allStateClickCallback = null
                )
            }
        }
    }

    override fun finishTwoLevel(action: String) {
        if (mShowTwoLevel) {
            mAutoFinishTwoLevelHandler?.removeMessages(KEY_AUTO_FINISH_TWO_LEVEL)
            mBinding.twoLevelHeader.finishTwoLevel()
            mAutoFinishTwoLevelCallback?.invoke()
            mAutoFinishTwoLevelCallback = null
            mElapsedHelper.pauseCounting()
            mPullDownPush?.run {
                SensorsBridge.trackEvent(
                    "DropDownPushClick",
                    json {
                        "action" to mPullDownPushAction
                        "button_name" to "关闭推送"
                        "drop_down_push_id" to id
                        "game_name" to game?.name
                        "game_id" to game?.id
                        getPageInfo().forEach { (key, value) ->
                            key to value
                        }
                    }
                )
                com.gh.common.util.NewFlatLogUtils.logHomePushClose(
                    id,
                    action,
                    mTwoLevelOpenCount,
                    game?.id ?: "",
                    game?.name ?: "",
                    mElapsedHelper.elapsedTime
                )
            }
        }
    }

    override fun setToolbarMenu(res: Int) {
        // 青少年模式下要隐藏下载按钮
        if (SPUtils.getBoolean(Constants.SP_TEENAGER_MODE) && res == R.menu.menu_download) return
        if (mActionMenuView == null) return
        inflateMenu(res)

        mActionMenuView?.setOnMenuItemClickListener {
            onMenuItemClick(it)
            false
        }
        mActionMenuView?.menu?.let { menu ->
            for (i in 0 until menu.size()) {
                val menuItem = menu.getItem(i)
                // menu设置actionLayout后，无法捕捉点击事件，以icon为tag，如果icon is null 手动设置menuItem点击事件
                if (menuItem != null && menuItem.icon == null) {
                    if (menuItem.actionView != null) {
                        menuItem.actionView!!.setOnClickListener {
                            onMenuItemClick(menuItem)
                        }
                    }
                }
            }
        }
        setTitleCenter()
    }

    override fun onMenuItemClick(menuItem: MenuItem?) {
        if (menuItem?.itemId == R.id.menu_download) {
            DirectUtils.directToDownloadManager(
                requireContext(),
                mEntrance,
                customPageName = arguments?.getString(EntranceConsts.KEY_CUSTOM_PAGE_NAME, "") ?: "",
                customPageId = arguments?.getString(EntranceConsts.KEY_CUSTOM_PAGE_ID, "") ?: "",
                multiTabId = arguments?.getString(EntranceConsts.KEY_MULTI_TAB_NAV_ID, "") ?: "",
                multiTabName = arguments?.getString(EntranceConsts.KEY_MULTI_TAB_NAV_NAME, "") ?: "",
            )
        } else if (mContentFragment is ToolbarFragment) {
            (mContentFragment as ToolbarFragment).onMenuItemClick(menuItem)
        }
    }

    override fun getMenuItem(res: Int): MenuItem? {
        return if (mToolbar == null) null else mActionMenuView?.menu?.findItem(res) //后续页面做好判断
    }

    override fun hideToolbar(isHide: Boolean) {
        mToolbarContainer?.isVisible = !isHide
    }

    override fun showAdLabel(isAd: Boolean) {
        mAdLabelTv?.isVisible = isAd
    }

    override fun setNavigationTitle(title: Int) {
        mTitleTv?.text = getString(title)
        mIconTitle?.text = getString(title)
    }

    override fun setNavigationTitle(title: String?) {
        mTitleTv?.text = title
        mIconTitle?.text = title
    }

    override fun onHandleBackPressed(): Boolean = onBackPressed()

    override fun onBackPressed(): Boolean {
        if (mShowTwoLevel) {
            finishTwoLevel("主动收起")
            return true
        }
        return super.onBackPressed()
    }

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

    override fun setSmartRefreshEnabled(isEnable: Boolean) {
        mBinding.refreshLayout.setEnableRefresh(isEnable)
        (mContentFragment as? ISmartRefreshContent)?.setSwipeRefreshEnabled(!isEnable)
    }

    private fun refreshStatusBarStyle() {
        DisplayUtils.transparentStatusBar(requireActivity())
        DisplayUtils.setLightStatusBar(requireActivity(), !mIsDarkModeOn && !mShowTwoLevel)
    }

    override fun onDarkModeChanged() {
        super.onDarkModeChanged()
        if (!::mBinding.isInitialized) return

        refreshStatusBarStyle()
        mBinding.toolbarBackground.setBackgroundColor(com.gh.gamecenter.common.R.color.ui_surface.toColor(requireContext()))
        mBinding.backgroundContainer.setOnlyTopRoundedColorBackground(com.gh.gamecenter.common.R.color.ui_surface.toColor(requireContext()), 8F)

        val color = if (mShowTwoLevel) com.gh.gamecenter.common.R.color.text_aw_primary.toColor(requireContext()) else com.gh.gamecenter.common.R.color.text_primary.toColor(requireContext())
        mTitleTv?.setTextColor(color)
        mBackBtn?.setColorFilter(color)
        if (mShowDownloadMenu) {
            mDownloadBtn?.setColorFilter(color)
        }
        mBinding.classicsHeader.run {
            setArrowColorFilter(com.gh.gamecenter.common.R.color.text_tertiary.toColor(requireContext()))
            setPrimaryColor(com.gh.gamecenter.common.R.color.ui_surface.toColor(requireContext()))
            setAccentColor(com.gh.gamecenter.common.R.color.text_tertiary.toColor(requireContext()))
        }
    }

    override fun onDestroyView() {
        super.onDestroyView()
        mAutoFinishTwoLevelHandler?.removeCallbacksAndMessages(null)
        if (::mBinding.isInitialized) {
            mBinding.autoVideoView.release()
        }
    }

    override fun getBusinessId(): Pair<String, String> = (mContentFragment as? IBusiness)?.getBusinessId() ?: Pair("", "")

    companion object {
        const val TOOLBAR_HEIGHT = 48F

        const val PULL_DOWN_PUSH_VIDEO_PLAY_DELAY = 100L
        const val FINISH_TWO_LEVEL_DELAY = 1000L
        const val AUTO_OPEN_TWO_LEVEL_DURATION = 1000L
        const val KEY_AUTO_FINISH_TWO_LEVEL = 456
    }
}