package com.gh.gamecenter.gamecollection.square

import android.app.Activity
import android.content.Intent
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.os.Message
import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup
import android.view.animation.AnimationUtils
import android.widget.ImageView
import android.widget.RelativeLayout
import androidx.core.content.ContextCompat
import androidx.core.view.ViewCompat
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.PagerSnapHelper
import androidx.recyclerview.widget.RecyclerView
import androidx.viewpager2.widget.ViewPager2
import com.ethanhua.skeleton.Skeleton
import com.gh.common.exposure.*
import com.gh.common.util.NewLogUtils
import com.gh.gamecenter.R
import com.gh.gamecenter.common.baselist.LazyListFragment
import com.gh.gamecenter.common.baselist.ListAdapter
import com.gh.gamecenter.common.baselist.LoadStatus
import com.gh.gamecenter.common.baselist.LoadType
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.constant.EntranceConsts
import com.gh.gamecenter.common.entity.ExposureEntity
import com.gh.gamecenter.common.eventbus.EBReuse
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.common.view.ScrollEventListener
import com.gh.gamecenter.common.view.SegmentedFilterView
import com.gh.gamecenter.common.view.VerticalItemDecoration
import com.gh.gamecenter.core.utils.ClickUtils
import com.gh.gamecenter.core.utils.DisplayUtils
import com.gh.gamecenter.databinding.FragmentGameCollectionSquareAlBinding
import com.gh.gamecenter.databinding.FragmentGameCollectionSquareBinding
import com.gh.gamecenter.entity.GamesCollectionEntity
import com.gh.gamecenter.entity.TagInfoEntity
import com.gh.gamecenter.fragment.HomeSearchToolWrapperFragment
import com.gh.gamecenter.gamecollection.publish.GameCollectionEditActivity
import com.gh.gamecenter.gamecollection.tag.GameCollectionTagSelectActivity
import com.gh.gamecenter.gamecollection.tag.GameCollectionTagSelectFragment
import com.google.android.material.appbar.AppBarLayout
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import java.lang.ref.WeakReference
import kotlin.math.abs

class GameCollectionSquareFragment : LazyListFragment<GamesCollectionEntity, GameCollectionSquareViewModel>() {
    private lateinit var mBasicExposureSource: ArrayList<ExposureSource>
    private lateinit var mViewModel: GameCollectionSquareViewModel
    private lateinit var mExposureListener: ExposureListener

    private lateinit var mDefaultBinding: FragmentGameCollectionSquareBinding
    private lateinit var mAlternativeBinding: FragmentGameCollectionSquareAlBinding
    private lateinit var mSnapHelper: PagerSnapHelper
    private lateinit var mBannerLayoutManager: LinearLayoutManager

    private var mAdapter: GameCollectionSquareAdapter? = null
    private var mItemDecoration: RecyclerView.ItemDecoration? = null

    private val mLooperHandle = LooperHandle(this)
    private val mSlideLooperKey = 666
    private val mExposureEventList = arrayListOf<ExposureEvent>()

    private var mUseAlternativeLayout = false
    private var mIsCollapsed = false
    private var mForumName = ""
    private var mGameCollectionTitle = ""
    private var mGameCollectionId = ""

    override fun onCreate(savedInstanceState: Bundle?) {
        mUseAlternativeLayout = arguments?.getBoolean(EntranceConsts.KEY_IS_HOME, false) ?: false
        mForumName = arguments?.getString(EntranceConsts.KEY_FORUM_NAME, "") ?: ""
        mGameCollectionTitle = arguments?.getString(EntranceConsts.KEY_GAME_COLLECTION_TITLE, "") ?: ""
        mGameCollectionId = arguments?.getString(EntranceConsts.KEY_GAME_COLLECTION_ID, "") ?: ""
        super.onCreate(savedInstanceState)
    }

    override fun getStubLayoutId() = R.layout.fragment_stub

    override fun getRealLayoutId() =
        if (mUseAlternativeLayout) R.layout.fragment_game_collection_square_al else R.layout.fragment_game_collection_square

    override fun onFragmentFirstVisible() {
        super.onFragmentFirstVisible()
        mViewModel.entrance = mEntrance
        mViewModel.isHome = mUseAlternativeLayout
        mListViewModel.load(LoadType.NORMAL)

        NewLogUtils.logEnterGameCollectionSquare(mEntrance, mForumName, mGameCollectionTitle, mGameCollectionId)
    }

    override fun onFragmentPause() {
        super.onFragmentPause()
        if (mUseAlternativeLayout) {
            val rootView = (parentFragment as? HomeSearchToolWrapperFragment)?.view
            rootView?.findViewById<ImageView>(R.id.fab)?.visibility = View.GONE
        } else {
            if (mExposureEventList.isNotEmpty()) ExposureManager.log(mExposureEventList)
        }
        val stayTime = (System.currentTimeMillis() - startPageTime) / 1000
        com.gh.common.util.NewFlatLogUtils.logGameCollectSquareStayTime(stayTime)
    }

    override fun onFragmentResume() {
        super.onFragmentResume()
        if (mUseAlternativeLayout) {
            val rootView = (parentFragment as? HomeSearchToolWrapperFragment)?.view
            rootView?.findViewById<ImageView>(R.id.fab)?.visibility = View.VISIBLE
        }
    }

    override fun isAutomaticLoad() = false

    override fun onRealLayoutInflated(inflatedView: View) {
        super.onRealLayoutInflated(inflatedView)
        if (mUseAlternativeLayout) {
            mAlternativeBinding = FragmentGameCollectionSquareAlBinding.bind(inflatedView)
        } else {
            mDefaultBinding = FragmentGameCollectionSquareBinding.bind(inflatedView)
        }
    }

    override fun initRealView() {
        super.initRealView()

        mExposureListener = ExposureListener(this, mAdapter!!)
        mListRv.addOnScrollListener(mExposureListener)
        initSkeleton()
        if (!mUseAlternativeLayout) {
            initDefaultLayout()
        } else {
            initAlternativeLayout()
        }
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (data == null || resultCode != Activity.RESULT_OK) return
        if (requestCode == REQUEST_SELECT_TAG) {
            val tagInfoEntity = data.getParcelableExtra<TagInfoEntity>(GameCollectionTagSelectFragment.SELECTED_TAG)
            if (tagInfoEntity != mViewModel.selectedTagEntity) {
                mDefaultBinding.tagTv.text = tagInfoEntity?.name ?: "全部标签"
                mViewModel.selectedTagEntity = tagInfoEntity
                mViewModel.selectedTagId = tagInfoEntity?.id ?: ""
                mViewModel.selectedTagName = tagInfoEntity?.name ?: "全部标签"
                mDefaultBinding.tagFilter.background =
                    if (tagInfoEntity != null) R.drawable.bg_game_collection_tag_select.toDrawable() else R.drawable.bg_game_collection_tag_unselect.toDrawable()
                refresh()
            }
        }
    }

    override fun provideListViewModel(): GameCollectionSquareViewModel {
        mViewModel = viewModelProvider()
        return mViewModel
    }

    override fun getItemDecoration() = VerticalItemDecoration(
        context,
        16F,
        false,
        R.color.background_white
    ).apply { mItemDecoration = this }

    override fun provideListAdapter(): ListAdapter<*> {
        if (mAdapter == null) {
            val outerSequence = arguments?.getInt(EntranceConsts.KEY_TAB_INDEX)
            val tabName = arguments?.getString(EntranceConsts.KEY_NAME) ?: ""
            mBasicExposureSource = arrayListOf<ExposureSource>().apply {
                if (mEntrance == "游戏库") {
                    add(ExposureSource("游戏库"))
                    add(ExposureSource("游戏单广场"))
                } else {
                    add(
                        ExposureSource(
                            if (mUseAlternativeLayout) "顶部tab" else "游戏单广场",
                            if (mUseAlternativeLayout) tabName else ""
                        )
                    )
                }
            }
            mAdapter =
                GameCollectionSquareAdapter(
                    requireContext(),
                    mUseAlternativeLayout,
                    mViewModel,
                    mBasicExposureSource,
                    outerSequence ?: (-1)
                )
        }
        return mAdapter!!
    }


    private fun initDefaultLayout() {
        mDefaultBinding.nightMaskView.goneIf(!mIsDarkModeOn)
        mDefaultBinding.bannerBackground.background =
            if (mIsDarkModeOn) ColorDrawable(R.color.background_white.toColor(requireContext())) else R.drawable.bg_game_collection_square_banner.toDrawable(
                requireContext()
            )

        // toolbar 消费 fitsSystemWindows 避免在 collapsingToolbar 下面出现多出来的 padding
        // [https://stackoverflow.com/questions/48137666/viewgroup-inside-collapsingtoolbarlayout-show-extra-bottom-padding-when-set-fits]
        ViewCompat.setOnApplyWindowInsetsListener(mDefaultBinding.appbar) { _, insets ->
            (mDefaultBinding.toolbar.layoutParams as ViewGroup.MarginLayoutParams).topMargin =
                insets.systemWindowInsetTop
            insets.consumeSystemWindowInsets()
        }

        val collapsingTrigger = 66F.dip2px() + DisplayUtils.getStatusBarHeight(requireContext().resources)

        mDefaultBinding.toolbar.setNavigationOnClickListener { requireActivity().finish() }
        mDefaultBinding.placeholder.run {
            layoutParams = layoutParams.apply {
                height = DisplayUtils.getStatusBarHeight(requireContext().resources) + 48F.dip2px()
            }
        }

        mDefaultBinding.collapsingToolbar.scrimVisibleHeightTrigger = collapsingTrigger
        mDefaultBinding.collapsingToolbar.scrimShownAction = {
            mIsCollapsed = it
            DisplayUtils.setLightStatusBar(requireActivity(), !mIsDarkModeOn && it)
            changeToolbarStyle(it)
        }

        mDefaultBinding.titleTv.setOnClickListener {
            if (ClickUtils.isFastDoubleClick(mDefaultBinding.titleTv.id, 300)) {
                scrollToTop()
            }
        }

        mDefaultBinding.appbar.addOnOffsetChangedListener(AppBarLayout.OnOffsetChangedListener { _, verticalOffset ->
            val absOffset = abs(verticalOffset)
            val invisibleOffset = DisplayUtils.dip2px(30F)

            if (absOffset <= invisibleOffset) {
                mDefaultBinding.titleTv.alpha = 1 - (absOffset.toFloat() / invisibleOffset)
            } else {
                mDefaultBinding.titleTv.alpha = 0F
            }

            mListRefresh?.isEnabled = absOffset <= 2
        })

//        mReuseNoData?.findViewById<TextView>(R.id.reuseNoneDataTv)?.text = "哎呀，没有找到相关内容~"

        mDefaultBinding.orderSfv.post {
            // 防止标签文字过长
            mDefaultBinding.tagTv.maxWidth =
                DisplayUtils.getScreenWidth() - 80F.dip2px() - mDefaultBinding.orderSfv.width
        }
        mDefaultBinding.orderSfv.setItemList(listOf("推荐", "热门", "最新"), 0)
        mDefaultBinding.orderSfv.setOnCheckedCallback(object : SegmentedFilterView.OnCheckedCallback {
            override fun onItemCheck(position: Int) {
                when (position) {
                    0 -> mViewModel.view = "recommend"
                    1 -> mViewModel.view = "hot"
                    2 -> mViewModel.view = "new"
                }
                refresh()
            }
        })

        mDefaultBinding.fab.setOnClickListener {
            // 创建游戏单
            ifLogin(mEntrance) {
                showRegulationTestDialogIfNeeded {
                    startActivity(GameCollectionEditActivity.getIntent(requireContext(), mEntrance, "游戏单广场"))
                }
            }
        }

        mDefaultBinding.listRv.addOnScrollListener(object : RecyclerView.OnScrollListener() {
            override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
                super.onScrolled(recyclerView, dx, dy)
                if (dy > Constants.FOLLOW_HINT_TRIGGER_HEIGHT) {
                    setFabStatus(mDefaultBinding.fab, View.GONE)
                } else if (dy < -Constants.FOLLOW_HINT_TRIGGER_HEIGHT) {
                    setFabStatus(mDefaultBinding.fab, View.VISIBLE)
                }
            }
        })

        val bannerAdapter = GameCollectionBannerAdapter(
            requireContext(),
            false,
            mEntrance = "游戏单广场",
            mBasicExposureSource = mBasicExposureSource
        )
        mSnapHelper = PagerSnapHelper()
        mBannerLayoutManager = LinearLayoutManager(requireContext(), RecyclerView.HORIZONTAL, false)
        mDefaultBinding.bannerRv.run {
            adapter = bannerAdapter
            layoutManager = mBannerLayoutManager
            mSnapHelper.attachToRecyclerView(this)
            addOnItemTouchListener(object : RecyclerView.SimpleOnItemTouchListener() {
                override fun onInterceptTouchEvent(rv: RecyclerView, e: MotionEvent): Boolean {
                    when (e.action) {
                        MotionEvent.ACTION_DOWN -> {
                            mDefaultBinding.listRefresh.isEnabled = false
                        }
                        MotionEvent.ACTION_UP -> {
                            mDefaultBinding.listRefresh.isEnabled = true
                        }
                    }

                    val isStop = e.action == MotionEvent.ACTION_DOWN || e.action == MotionEvent.ACTION_MOVE
                    if (isStop) stopAutoPlay() else startAutoPlay()
                    return false
                }
            })
            addOnScrollListener(ScrollEventListener(this).apply {
                setOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
                    override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {
                        super.onPageScrolled(position, positionOffset, positionOffsetPixels)
                        mDefaultBinding.bannerIndicator.onPageScrolled(
                            bannerAdapter.getActualPosition(position),
                            positionOffset
                        )
                    }
                })
            })
        }

        mDefaultBinding.tagFilter.setOnClickListener {
            startActivityForResult(
                GameCollectionTagSelectActivity.getIntent(requireContext(), true, mViewModel.selectedTagEntity),
                REQUEST_SELECT_TAG
            )
        }

        mViewModel.mBannerList.observeNonNull(this) {
            mDefaultBinding.tagFilterContainer.layoutParams =
                (mDefaultBinding.tagFilterContainer.layoutParams as AppBarLayout.LayoutParams).apply {
                    setMargins(
                        0,
                        if (it.isEmpty()) (-16F).dip2px() else 0,
                        0,
                        0
                    )
                }
            mDefaultBinding.headIv.goneIf(it.isNotEmpty())
            mDefaultBinding.bannerContainer.goneIf(it.isEmpty())
            mDefaultBinding.titleIv.goneIf(it.isEmpty())
            mDefaultBinding.sloganTv.goneIf(it.isEmpty())
            mDefaultBinding.statusBar.setBackgroundColor(
                if (it.isEmpty()) Color.TRANSPARENT
                else if (mIsDarkModeOn) R.color.background_white.toColor(requireContext())
                else R.color.game_collection_square.toColor(requireContext())
            )
            mDefaultBinding.toolbar.setBackgroundColor(
                if (it.isEmpty()) Color.TRANSPARENT
                else if (mIsDarkModeOn) R.color.background_white.toColor(requireContext())
                else R.color.game_collection_square.toColor(requireContext())
            )
            if (it.isNotEmpty()) {
                bannerAdapter.submitList(it)
                mExposureEventList.clear()
                it.forEachIndexed { index, entity ->
                    val exposureEvent = ExposureEvent(
                        payload = ExposureEntity(
                            carouselId = entity.id,
                            sequence = index
                        ),
                        source = ArrayList(mBasicExposureSource).apply {
                            add(ExposureSource(k = "轮播图"))
                        },
                        event = ExposureType.EXPOSURE
                    )
                    mExposureEventList.add(exposureEvent)
                }
                if (bannerAdapter.getActualSize() > 1) {
                    mDefaultBinding.bannerRv.scrollToPosition(bannerAdapter.getActualFirstPositionInCenter())
                }
                mDefaultBinding.bannerIndicator.run {
                    mPageSize = bannerAdapter.getActualSize()
                    notifyDataChanged()
                }
                startAutoPlay()
            }
        }

        mListRefresh?.setProgressViewOffset(
            false,
            0,
            118F.dip2px() + DisplayUtils.getStatusBarHeight(requireContext().resources)
        )
    }

    private fun changeToolbarStyle(isCollapsed: Boolean) {
        if (isCollapsed) {
            mDefaultBinding.titleTv.alpha = 1F
            mDefaultBinding.titleTv.visibility = View.VISIBLE
            mDefaultBinding.titleTv.setTextColor(R.color.text_black.toColor(requireContext()))
            mDefaultBinding.toolbar.navigationIcon = R.drawable.ic_bar_back.toDrawable(requireContext())
            mDefaultBinding.tagFilterContainer.background = null
            mDefaultBinding.titleIv.visibility = View.GONE
            mDefaultBinding.sloganTv.visibility = View.GONE
            mDefaultBinding.statusBar.setBackgroundColor(Color.TRANSPARENT)
            mDefaultBinding.toolbar.setBackgroundColor(Color.TRANSPARENT)
        } else {
            mDefaultBinding.titleTv.visibility = View.GONE
            mDefaultBinding.toolbar.navigationIcon = R.drawable.ic_bar_back_light.toDrawable(requireContext())
            mDefaultBinding.tagFilterContainer.background =
                R.drawable.bg_game_collection_square.toDrawable(requireContext())
            mDefaultBinding.titleIv.goneIf(mViewModel.mBannerList.value.isNullOrEmpty())
            mDefaultBinding.sloganTv.goneIf(mViewModel.mBannerList.value.isNullOrEmpty())
            mDefaultBinding.statusBar.setBackgroundColor(
                if (mViewModel.mBannerList.value.isNullOrEmpty()) Color.TRANSPARENT
                else if (mIsDarkModeOn) R.color.background_white.toColor(requireContext())
                else R.color.game_collection_square.toColor(requireContext())
            )
            mDefaultBinding.toolbar.setBackgroundColor(
                if (mViewModel.mBannerList.value.isNullOrEmpty()) Color.TRANSPARENT
                else if (mIsDarkModeOn) R.color.background_white.toColor(requireContext())
                else R.color.game_collection_square.toColor(requireContext())
            )
        }
    }

    private fun scrollToNextPage() {
        val snapView = mSnapHelper.findSnapView(mBannerLayoutManager)
        if (snapView != null) {
            mBannerLayoutManager.smoothScrollToPosition(
                mDefaultBinding.bannerRv,
                null,
                mBannerLayoutManager.getPosition(snapView) + 1
            )
        }
    }

    private fun startAutoPlay() {
        if ((mDefaultBinding.bannerRv.adapter as GameCollectionBannerAdapter).getActualSize() <= 1) return
        stopAutoPlay()
        mLooperHandle.sendEmptyMessageDelayed(mSlideLooperKey, BANNER_LOOP_TIME)
    }

    private fun stopAutoPlay() {
        mLooperHandle.removeMessages(mSlideLooperKey)
    }

    private fun initAlternativeLayout() {
        if (parentFragment is HomeSearchToolWrapperFragment) {
            val rootView = (parentFragment as HomeSearchToolWrapperFragment).view
            if (rootView is RelativeLayout) {
                val fabView = ImageView(context).apply {
                    id = R.id.fab
                    layoutParams = RelativeLayout.LayoutParams(60F.dip2px(), 60F.dip2px()).apply {
                        addRule(RelativeLayout.ALIGN_PARENT_BOTTOM)
                        addRule(RelativeLayout.ALIGN_PARENT_RIGHT)
                        setMargins(0, 0, 14F.dip2px(), 14F.dip2px())
                    }
                    background = R.drawable.community_edit_icon.toDrawable()
                    setOnClickListener {
                        ifLogin(mEntrance) {
                            showRegulationTestDialogIfNeeded {
                                startActivity(
                                    GameCollectionEditActivity.getIntent(
                                        requireContext(),
                                        mEntrance,
                                        "游戏单广场"
                                    )
                                )
                            }
                        }
                    }
                }
                rootView.addView(fabView)
                mAlternativeBinding.listRv.addOnScrollListener(object : RecyclerView.OnScrollListener() {
                    override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
                        super.onScrolled(recyclerView, dx, dy)
                        if (dy > Constants.FOLLOW_HINT_TRIGGER_HEIGHT) {
                            setFabStatus(fabView, View.GONE)
                        } else if (dy < -Constants.FOLLOW_HINT_TRIGGER_HEIGHT) {
                            setFabStatus(fabView, View.VISIBLE)
                        }
                    }
                })
            }
        }

//        mReuseNoData?.findViewById<TextView>(R.id.reuseNoneDataTv)?.text = "哎呀，没有找到相关内容~"

        mViewModel.mAmwayCommentList.observeNonNull(this) {
            mAdapter?.setAmwayList(it)
        }

        mViewModel.mBannerList.observeNonNull(this) {
            mAdapter?.setBannerList(it)
        }
    }

    private fun setFabStatus(fab: View, visibility: Int) {
        if (fab.visibility == visibility) return
        if (visibility == View.GONE) {
            val animation = AnimationUtils.loadAnimation(context, R.anim.button_anim_exit)
            fab.startAnimation(animation)
        } else {
            val animation = AnimationUtils.loadAnimation(context, R.anim.button_anim_enter)
            fab.startAnimation(animation)
        }
        fab.visibility = visibility
    }

    override fun onLoadEmpty() {
        super.onLoadEmpty()
        if (!mUseAlternativeLayout) mDefaultBinding.tagFilterContainer.visibility = View.VISIBLE
    }

    override fun onLoadDone() {
        super.onLoadDone()
        if (!mUseAlternativeLayout) mDefaultBinding.tagFilterContainer.visibility = View.VISIBLE
    }

    override fun onLoadError() {
        super.onLoadError()
        if (!mUseAlternativeLayout) mDefaultBinding.tagFilterContainer.visibility = View.GONE
    }

    override fun onLoadRefresh() {
        super.onLoadRefresh()
        if (!mUseAlternativeLayout) mDefaultBinding.tagFilterContainer.visibility = View.VISIBLE
    }

    private fun initSkeleton() {
        mSkeletonScreen =
            Skeleton.bind(if (mUseAlternativeLayout) mAlternativeBinding.skeletonPlaceholder else mDefaultBinding.skeletonPlaceholder)
                .shimmer(true)
                .angle(Constants.SHIMMER_ANGLE)
                .color(R.color.skeleton_shimmer_color)
                .duration(Constants.SHIMMER_DURATION)
                .maskWidth(Constants.MASK_WIDTH)
                .gradientCenterColorWidth(Constants.GRADIENT_CENTER_COLOR_WIDTH)
                .load(if (mUseAlternativeLayout) R.layout.fragment_game_collection_square_al_skeleton else R.layout.fragment_game_collection_square_skeleton)
                .show()
        requireView().findViewById<View>(R.id.skeletonPlaceholder)?.fitsSystemWindows = true
    }

    override fun showSkeleton(showSkeleton: Boolean) {
        super.showSkeleton(showSkeleton)
        if (mSkeletonScreen != null && showSkeleton) {
            requireView().findViewById<View>(R.id.skeletonPlaceholder)?.fitsSystemWindows = true
        }
    }

    private fun refresh() {
        if (mReuseNoConn != null) mReuseNoConn!!.visibility = View.GONE
        if (mListLoading != null) mListLoading!!.visibility =
            if (mListRefresh == null || !mListRefresh!!.isRefreshing) View.VISIBLE else View.GONE
        if (mReuseNoData != null) mReuseNoData!!.visibility = View.GONE
        if (mListRv != null) mListRv.visibility = View.GONE
        mBaseHandler.postDelayed({ mListViewModel.load(LoadType.REFRESH) }, 500)
        if (!mUseAlternativeLayout) mDefaultBinding.tagFilterContainer.visibility = View.VISIBLE
    }

    private fun scrollToTop() {
        val firstItemPosition = mLayoutManager.findFirstVisibleItemPosition()
        if (firstItemPosition >= 10) {
            mListRv.scrollToPosition(6)
        }
        mListRv.smoothScrollToPosition(0)
        mDefaultBinding.appbar.setExpanded(true)
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onEventMainThread(reuse: EBReuse) {
        if ("Refresh" == reuse.type) {
            mAdapter?.notifyDataSetChanged()
        } else if (reuse.type == Constants.LOGIN_TAG) { // 登入
            scrollToTop()
            onRefresh()
        }
    }

    override fun onDarkModeChanged() {
        super.onDarkModeChanged()
        mItemDecoration?.let { mListRv?.removeItemDecoration(it) }
        mListRv?.addItemDecoration(itemDecoration)
        if (mUseAlternativeLayout && ::mAlternativeBinding.isInitialized) {
            initSkeleton()
            showSkeleton(mListViewModel.loadStatusLiveData.value == LoadStatus.INIT_LOADING)
            mAlternativeBinding.listRefresh.setBackgroundColor(R.color.background_white.toColor(requireContext()))
        } else if (::mDefaultBinding.isInitialized) {
            initSkeleton()
            showSkeleton(mListViewModel.loadStatusLiveData.value == LoadStatus.INIT_LOADING)
            mDefaultBinding.nightMaskView.goneIf(!mIsDarkModeOn)
            mDefaultBinding.bannerBackground.background =
                if (mIsDarkModeOn) ColorDrawable(R.color.background_white.toColor(requireContext())) else R.drawable.bg_game_collection_square_banner.toDrawable(
                    requireContext()
                )
            mDefaultBinding.listRefresh.setBackgroundColor(R.color.background_white.toColor(requireContext()))
            mDefaultBinding.appbar.setBackgroundColor(R.color.background_white.toColor(requireContext()))
            mDefaultBinding.collapsingToolbar.setContentScrimColor(R.color.background_white.toColor(requireContext()))
            mDefaultBinding.orderSfv.run {
                setContainerBackground(R.drawable.button_round_f5f5f5.toDrawable(requireContext()))
                setIndicatorBackground(R.drawable.bg_game_collection_sfv_indicator.toDrawable(requireContext()))
                setTextColor(ContextCompat.getColorStateList(context, R.color.game_collection_rg_button_selector))
            }
            DisplayUtils.setLightStatusBar(requireActivity(), !mIsDarkModeOn && mIsCollapsed)
            changeToolbarStyle(mIsCollapsed)
        }
    }

    companion object {
        const val REQUEST_SELECT_TAG = 100
        const val BANNER_LOOP_TIME = 5000L
    }

    class LooperHandle(fragment: GameCollectionSquareFragment) : Handler(Looper.getMainLooper()) {
        private val mWeakReference: WeakReference<GameCollectionSquareFragment> = WeakReference(fragment)

        override fun handleMessage(msg: Message) {
            super.handleMessage(msg)
            val fragment = mWeakReference.get()
            if (fragment != null && msg.what == fragment.mSlideLooperKey) {
                fragment.scrollToNextPage()
                fragment.startAutoPlay()
            }
        }
    }

}