package com.gh.gamecenter.gamecollection.square

import android.app.Activity
import android.content.Intent
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.os.Message
import android.view.Gravity
import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup
import android.view.ViewGroup.MarginLayoutParams
import android.view.animation.AnimationUtils
import android.widget.FrameLayout
import android.widget.LinearLayout
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.coordinatorlayout.widget.CoordinatorLayout
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.core.view.isVisible
import androidx.core.view.updateLayoutParams
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.PagerSnapHelper
import androidx.recyclerview.widget.RecyclerView
import androidx.viewpager2.widget.ViewPager2
import com.airbnb.lottie.LottieAnimationView
import com.airbnb.lottie.LottieDrawable
import com.ethanhua.skeleton.Skeleton
import com.gh.common.exposure.ExposureListener
import com.gh.common.exposure.ExposureManager
import com.gh.common.util.DirectUtils
import com.gh.common.util.NewFlatLogUtils
import com.gh.common.util.NewLogUtils
import com.gh.gamecenter.R
import com.gh.gamecenter.common.base.GlobalActivityManager
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.exposure.ExposureSource
import com.gh.gamecenter.common.json.json
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.common.view.ScrollEventListener
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.core.utils.SPUtils
import com.gh.gamecenter.core.utils.TimeElapsedHelper
import com.gh.gamecenter.databinding.FragmentGameCollectionSquareAlBinding
import com.gh.gamecenter.databinding.FragmentGameCollectionSquareBinding
import com.gh.gamecenter.databinding.LayoutGameCollectionFilterGuideBinding
import com.gh.gamecenter.databinding.LayoutPostFabBinding
import com.gh.gamecenter.entity.GamesCollectionEntity
import com.gh.gamecenter.entity.TagInfoEntity
import com.gh.gamecenter.feature.exposure.ExposureEvent
import com.gh.gamecenter.feature.exposure.ExposureType
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 org.json.JSONException
import org.json.JSONObject
import java.lang.ref.WeakReference
import kotlin.math.abs

class GameCollectionSquareFragment : LazyListFragment<GamesCollectionEntity, GameCollectionSquareViewModel>() {
    private lateinit var mBasicExposureSourceList: 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 mGuideContainer: LinearLayout? = null
    private var mPostFabView: ConstraintLayout? = null
    private var mRefreshFabView: FrameLayout? = null
    private val mElapsedHelper by lazy { TimeElapsedHelper() }

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

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

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

    override fun getStubLayoutId() = com.gh.gamecenter.common.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)

        val collectionId = arguments?.getString(EntranceConsts.KEY_COLLECTION_ID, "") ?: ""
        val collectionName = arguments?.getString(EntranceConsts.KEY_COLLECTION_NAME, "") ?: ""
        NewLogUtils.logEnterGameCollectionSquare(
            mEntrance,
            mForumName,
            mGameCollectionTitle,
            mGameCollectionId,
            collectionName,
            collectionId
        )
    }

    override fun onFragmentPause() {
        super.onFragmentPause()
        if (mUseAlternativeLayout) {
            mPostFabView?.visibility = View.GONE
            mRefreshFabView?.visibility = View.GONE
            mGuideContainer?.visibility = View.GONE
        } else {
            if (mExposureEventList.isNotEmpty()) ExposureManager.log(mExposureEventList)
            stopAutoPlay()
        }
        val stayTime = (System.currentTimeMillis() - startPageTime) / 1000
        NewFlatLogUtils.logGameCollectSquareStayTime(stayTime, if (mUseAlternativeLayout) "首页tab栏" else "游戏单广场")

        mElapsedHelper.pauseCounting()
        if (mElapsedHelper.elapsedTime >= 3) {
            val trackEvent = JSONObject()
            try {
                trackEvent.put("game_collect_title", mGameCollectionTitle)
                trackEvent.put("game_collect_id", mGameCollectionId)
                trackEvent.put("page_name", GlobalActivityManager.getCurrentPageEntity().pageName)
                trackEvent.put("page_id", GlobalActivityManager.getCurrentPageEntity().pageId)
                trackEvent.put("page_business_id", GlobalActivityManager.getCurrentPageEntity().pageBusinessId)
                trackEvent.put("last_page_name", GlobalActivityManager.getLastPageEntity().pageName)
                trackEvent.put("last_page_id", GlobalActivityManager.getLastPageEntity().pageId)
                trackEvent.put("last_page_business_id", GlobalActivityManager.getLastPageEntity().pageBusinessId)
                trackEvent.put("stay_length", mElapsedHelper.elapsedTime)
            } catch (e: JSONException) {
                e.printStackTrace()
            }
            SensorsBridge.trackEvent("ViewGameCollectSquare", trackEvent)
        }
    }

    override fun onFragmentResume() {
        super.onFragmentResume()
        if (mUseAlternativeLayout) {
            mPostFabView?.visibility = View.VISIBLE
            mRefreshFabView?.visibility = View.VISIBLE
            if (mIsLoadDone) {
                mGuideContainer?.goneIf(
                    !SPUtils.getBoolean(
                        Constants.SP_SHOW_GAME_COLLECTION_SQUARE_FILTER_GUIDE,
                        true
                    )
                )
            }
        } else {
            startAutoPlay()
        }
        mElapsedHelper.resetCounting()
        mElapsedHelper.resumeCounting()
    }

    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 || !::mViewModel.isInitialized) return
        if (requestCode == REQUEST_SELECT_TAG) {
            val tagInfoEntity = data.getParcelableExtra<TagInfoEntity>(GameCollectionTagSelectFragment.SELECTED_TAG)
            val tagCategory = data.getStringExtra(GameCollectionTagSelectFragment.SELECTED_TAG_CATEGORY)
            if (tagInfoEntity != null) {
                NewLogUtils.logFilterGameCollectionTag(
                    tagCategory ?: "",
                    tagInfoEntity.name,
                    if (mUseAlternativeLayout) "首页tab栏" else "游戏单广场"
                )
                SensorsBridge.trackEvent(
                    "GameCollectSquareTagClick",
                    "label_category",
                    tagCategory ?: "",
                    "label_name",
                    tagInfoEntity.name,
                    "label_id",
                    tagInfoEntity.id,
                    "text",
                    "游戏单标签"
                )
            }
            if (tagInfoEntity != mViewModel.selectedTagEntity) {
                mViewModel.selectedTagEntity = tagInfoEntity
                mViewModel.selectedTagCategory = tagCategory ?: ""
                mViewModel.selectedTagId = tagInfoEntity?.id ?: ""
                mViewModel.selectedTagName = tagInfoEntity?.name ?: "全部标签"
                if (mUseAlternativeLayout) {
                    mAdapter?.notifyItemChanged(HOME_FILTER_ITEM_POSITION)
                } else {
                    mDefaultBinding.tagFilterContainer.tagTv.text = tagInfoEntity?.name ?: "全部标签"
                    mDefaultBinding.tagFilterContainer.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,
        com.gh.gamecenter.common.R.color.ui_surface
    ).apply { mItemDecoration = this }

    override fun provideListAdapter(): ListAdapter<*> {
        if (mAdapter == null) {
            val outerSequence = arguments?.getInt(EntranceConsts.KEY_TAB_INDEX)
            mBasicExposureSourceList = arrayListOf<ExposureSource>().apply {
                val exposureSourceList = requireArguments().getParcelableArrayList<ExposureSource>(EntranceConsts.KEY_EXPOSURE_SOURCE_LIST)
                if (exposureSourceList != null) {
                    addAll(exposureSourceList)
                }
                add(ExposureSource("游戏单广场"))
            }
            mAdapter =
                GameCollectionSquareAdapter(
                    requireContext(),
                    viewLifecycleOwner,
                    mUseAlternativeLayout,
                    this,
                    mViewModel,
                    mBasicExposureSourceList,
                    outerSequence ?: (-1)
                ) {
                    refresh()
                }
        }
        return mAdapter!!
    }


    private fun initDefaultLayout() {
        // toolbar 消费 fitsSystemWindows 避免在 collapsingToolbar 下面出现多出来的 padding
        // [https://stackoverflow.com/questions/48137666/viewgroup-inside-collapsingtoolbarlayout-show-extra-bottom-padding-when-set-fits]
        DisplayUtils.setLightStatusBar(requireActivity(), !mIsDarkModeOn)
        ViewCompat.setOnApplyWindowInsetsListener(mDefaultBinding.appbar) { _, insets ->
            (mDefaultBinding.toolbar.layoutParams as ViewGroup.MarginLayoutParams).topMargin =
                insets.getInsets(WindowInsetsCompat.Type.systemBars()).top
            WindowInsetsCompat.CONSUMED
        }

        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
            changeToolbarStyle(it)
        }

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

        mDefaultBinding.appbar.addOnOffsetChangedListener { _, 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.tagFilterContainer.orderSfv.post {
            // 防止标签文字过长
            mDefaultBinding.tagFilterContainer.tagTv.maxWidth =
                DisplayUtils.getScreenWidth() - 80F.dip2px() - mDefaultBinding.tagFilterContainer.orderSfv.width
        }
        mDefaultBinding.tagFilterContainer.orderSfv.setItemList(listOf("推荐", "热门", "最新"), 0)
        mDefaultBinding.tagFilterContainer.orderSfv.setOnCheckedCallback { position ->
            mViewModel.view = GameCollectionSquareViewModel.getOrderNameByPosition(position)
            SensorsBridge.trackEvent(
                "GameCollectSquareSortClick",
                "text",
                GameCollectionSquareViewModel.getOrderChineseByName(mViewModel.view)
            )
            refresh()
        }

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

        mDefaultBinding.refreshFab.setOnClickListener {
            if (!mDefaultBinding.refreshLottie.isAnimating) {
                mViewModel.refreshCount++
                NewFlatLogUtils.logGameCollectionSquareFlush("点击刷新按钮", mViewModel.refreshCount)
                SensorsBridge.trackEvent("GameCollectSquareFlush", json {
                    "action" to "点击刷新按钮"
                    "count_num" to mViewModel.refreshCount
                })
                mDefaultBinding.refreshLottie.playAnimation()
                refresh()
            }
        }

        mDefaultBinding.listRv.addOnScrollListener(object : RecyclerView.OnScrollListener() {
            override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
                super.onScrollStateChanged(recyclerView, newState)
                if (newState == RecyclerView.SCROLL_STATE_DRAGGING) {
                    setFabStatus(mDefaultBinding.postFab.root, View.GONE)
                    setFabStatus(mDefaultBinding.refreshFab, View.GONE)
                } else if (newState == RecyclerView.SCROLL_STATE_IDLE) {
                    setFabStatus(mDefaultBinding.postFab.root, View.VISIBLE)
                    setFabStatus(mDefaultBinding.refreshFab, View.VISIBLE)
                }
            }
        })

        val bannerAdapter = GameCollectionBannerAdapter(
            requireContext(),
            viewLifecycleOwner,
            mViewModel,
            mEntrance = "游戏单广场",
            mBasicExposureSource = mBasicExposureSourceList
        )
        mSnapHelper = PagerSnapHelper()
        mBannerLayoutManager = LinearLayoutManager(requireContext(), RecyclerView.HORIZONTAL, false)
        mDefaultBinding.headerContainer.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 {
                registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
                    override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {
                        super.onPageScrolled(position, positionOffset, positionOffsetPixels)
                        mDefaultBinding.headerContainer.bannerIndicator.onPageScrolled(
                            bannerAdapter.getActualPosition(position),
                            positionOffset
                        )
                    }
                })
            })
        }

        mDefaultBinding.headerContainer.hotListCv.setOnClickListener {
            DirectUtils.directToGameCollectionHotList(requireContext(), "游戏单广场")
        }

        mDefaultBinding.tagFilterContainer.tagFilter.setOnClickListener {
            NewLogUtils.logEnterGameCollectionTag("游戏单广场")
            SensorsBridge.trackEvent(
                "GameCollectTagEnter",
                "label_category",
                mViewModel.selectedTagCategory,
                "label_name",
                mViewModel.selectedTagEntity?.name ?: "",
                "label_id",
                mViewModel.selectedTagEntity?.id ?: ""
            )
            startActivityForResult(
                GameCollectionTagSelectActivity.getIntent(requireContext(), true, mViewModel.selectedTagEntity),
                REQUEST_SELECT_TAG
            )
        }

        val headerHeight = (DisplayUtils.getScreenWidth() - 40F.dip2px()) / 4 + 64F.dip2px()
        mDefaultBinding.guideView.updateLayoutParams<MarginLayoutParams> { topMargin = headerHeight }

        mViewModel.bannerList.observeNonNull(this) {
            if (it.isNotEmpty()) {
                bannerAdapter.submitList(it)
                mExposureEventList.clear()
                it.forEachIndexed { index, entity ->
                    val exposureEvent = ExposureEvent(
                        payload = ExposureEntity(
                            carouselId = entity.id,
                            sequence = index
                        ),
                        source = ArrayList(mBasicExposureSourceList).apply {
                            add(ExposureSource(k = "轮播图"))
                        },
                        event = ExposureType.EXPOSURE
                    )
                    mExposureEventList.add(exposureEvent)
                }
                if (bannerAdapter.getActualSize() > 1) {
                    mDefaultBinding.headerContainer.bannerRv.scrollToPosition(bannerAdapter.getActualFirstPositionInCenter())
                }
                mDefaultBinding.headerContainer.bannerIndicator.run {
                    pageSize = bannerAdapter.getActualSize()
                    notifyDataChanged()
                }
                startAutoPlay()
            }
        }

        mViewModel.amwayCommentList.observeNonNull(this) {
            bannerAdapter.submitList(amwayList = it)
        }

        mViewModel.hotListFirstTab.observeNonNull(this) {
            mDefaultBinding.headerContainer.tabNameTv.text = it
        }

        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(com.gh.gamecenter.common.R.color.text_black.toColor(requireContext()))
            mDefaultBinding.titleIv.visibility = View.GONE
            mDefaultBinding.sloganTv.visibility = View.GONE
        } else {
            mDefaultBinding.titleTv.visibility = View.GONE
            mDefaultBinding.titleIv.visibility = View.VISIBLE
            mDefaultBinding.sloganTv.visibility = View.VISIBLE
        }
    }

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

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

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

    private fun initAlternativeLayout() {
        mPostFabView = LayoutPostFabBinding.inflate(layoutInflater).root.apply {
            setOnClickListener {
                ifLogin(mEntrance) {
                    showRegulationTestDialogIfNeeded {
                        startActivity(
                            GameCollectionEditActivity.getCreateIntent(
                                requireContext(),
                                mEntrance,
                                "游戏单广场"
                            )
                        )
                    }
                }
            }
        }
        val refreshLottieView = LottieAnimationView(requireContext()).apply {
            id = R.id.refreshLottie
            layoutParams = FrameLayout.LayoutParams(45F.dip2px(), 45F.dip2px()).apply {
                gravity = Gravity.CENTER
            }
            setAnimation("lottie/icon_fab_change.json")
            repeatMode = LottieDrawable.RESTART
        }
        mRefreshFabView = FrameLayout(requireContext()).apply {
            id = R.id.refreshFab
            background = R.drawable.bg_fab_container.toDrawable()
            addView(refreshLottieView)
            setOnClickListener {
                if (!refreshLottieView.isAnimating) {
                    mViewModel.refreshCount++
                    NewFlatLogUtils.logGameCollectionSquareFlush("点击刷新按钮", mViewModel.refreshCount)
                    SensorsBridge.trackEvent("GameCollectSquareFlush", json {
                        "action" to "点击刷新按钮"
                        "count_num" to mViewModel.refreshCount
                    })
                    refreshLottieView.playAnimation()
                    refresh()
                }
            }
        }

        mGuideContainer = LayoutGameCollectionFilterGuideBinding.inflate(layoutInflater).root
        val headerHeight = (DisplayUtils.getScreenWidth() - 40F.dip2px()) / 4 + 16F.dip2px()
        mGuideContainer?.setPadding(0, headerHeight, 0, 0)
        if (mIsFromMainWrapper || (!mIsHome && mIsFromTabWrapper)) {
            if (mIsFromMainWrapper) setNavigationTitle("游戏单广场")
            val rootView: FrameLayout? = parentFragment?.view?.findViewById(R.id.wrapper_main_content)
                ?: parentFragment?.parentFragment?.view?.findViewById(R.id.wrapper_main_content)
            if (rootView != null) {
                rootView.addView(mPostFabView, FrameLayout.LayoutParams(60F.dip2px(), 60F.dip2px()).also {
                    it.gravity = Gravity.BOTTOM.xor(Gravity.END)
                    it.setMargins(0, 0, 8F.dip2px(), 32F.dip2px())
                })
                rootView.addView(mRefreshFabView, FrameLayout.LayoutParams(60F.dip2px(), 60F.dip2px()).also {
                    it.gravity = Gravity.BOTTOM.xor(Gravity.END)
                    it.setMargins(0, 0, 8F.dip2px(), 92F.dip2px())
                })
                rootView.addView(mGuideContainer, FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT).also {
                    if (!mIsHome && mIsFromTabWrapper) {
                        it.setMargins(0, com.gh.gamecenter.common.R.dimen.tab_layout_height.toPx(), 0, 0)
                    }
                })
            }
        } else {
            val rootView = parentFragment?.view?.findViewById<CoordinatorLayout>(R.id.coordinator)
            if (rootView != null) {
                rootView.addView(mPostFabView, CoordinatorLayout.LayoutParams(60F.dip2px(), 60F.dip2px()).also {
                    it.gravity = Gravity.BOTTOM.xor(Gravity.END)
                    it.setMargins(0, 0, 8F.dip2px(), 32F.dip2px())
                })
                rootView.addView(mRefreshFabView, CoordinatorLayout.LayoutParams(60F.dip2px(), 60F.dip2px()).also {
                    it.gravity = Gravity.BOTTOM.xor(Gravity.END)
                    it.setMargins(0, 0, 8F.dip2px(), 92F.dip2px())
                })
                rootView.addView(mGuideContainer, CoordinatorLayout.LayoutParams(CoordinatorLayout.LayoutParams.MATCH_PARENT, CoordinatorLayout.LayoutParams.MATCH_PARENT).apply {
                    behavior = AppBarLayout.ScrollingViewBehavior()
                    if (parentFragment?.view?.findViewById<View>(R.id.tabContainer)?.isVisible == true) {
                        setMargins(0, 48F.dip2px(), 0, 0)
                    }
                })
            }
        }

        mAlternativeBinding.listRv.addOnScrollListener(object : RecyclerView.OnScrollListener() {
            override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
                super.onScrollStateChanged(recyclerView, newState)
                if (!isSupportVisible) return
                if (newState == RecyclerView.SCROLL_STATE_DRAGGING) {
                    setFabStatus(mPostFabView, View.GONE)
                    setFabStatus(mRefreshFabView, View.GONE)
                } else if (newState == RecyclerView.SCROLL_STATE_IDLE) {
                    setFabStatus(mPostFabView, View.VISIBLE)
                    setFabStatus(mRefreshFabView, View.VISIBLE)
                }
            }
        })

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

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

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

        mViewModel.hotListFirstTab.observeNonNull(this) {
            mAdapter?.setHotListTabName(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() {
        showSkeleton(false)
        if (mReuseNoConn != null) mReuseNoConn!!.visibility = View.GONE
        if (mReuseNoData != null) mReuseNoData!!.visibility = View.VISIBLE
        if (mListLoading != null) mListLoading!!.visibility = View.GONE
        if (mDataExceptionView != null) mDataExceptionView!!.visibility = View.GONE
        mListRv?.isVisible = mUseAlternativeLayout
        hideRefreshingLayout()
        if (!mUseAlternativeLayout) mDefaultBinding.tagFilterContainer.root.visibility = View.VISIBLE
    }

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

        val guideContainer =
            if (mUseAlternativeLayout) mGuideContainer else mDefaultBinding.guideContainer
        guideContainer?.goneIf(
            !SPUtils.getBoolean(
                Constants.SP_SHOW_GAME_COLLECTION_SQUARE_FILTER_GUIDE,
                true
            )
        ) {
            guideContainer.setOnClickListener {
                SPUtils.setBoolean(Constants.SP_SHOW_GAME_COLLECTION_SQUARE_FILTER_GUIDE, false)
                guideContainer.visibility = View.GONE
            }
        }
    }

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

    override fun onLoadRefresh() {
        refresh(true)
    }

    private fun initSkeleton() {
        mSkeletonScreen =
            Skeleton.bind(if (mUseAlternativeLayout) mAlternativeBinding.skeletonPlaceholder else mDefaultBinding.skeletonPlaceholder)
                .shimmer(true)
                .angle(Constants.SHIMMER_ANGLE)
                .color(com.gh.gamecenter.common.R.color.ui_skeleton_highlight)
                .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(showSkeleton: Boolean = false) {
        showSkeleton(showSkeleton)
        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 && (!mUseAlternativeLayout || showSkeleton)) mListRv?.visibility = View.GONE
        if (!mUseAlternativeLayout) mDefaultBinding.tagFilterContainer.root.visibility = View.VISIBLE
        if (mUseAlternativeLayout) {
            mAdapter?.run {
                entityList?.removeAll { it.isGameCollectionItem }
                notifyItemRangeRemoved(2, itemCount)
            }
        }
        mBaseHandler.postDelayed({ mListViewModel.load(LoadType.REFRESH) }, 500)
    }

    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 onRefresh() {
        mViewModel.refreshCount++
        NewFlatLogUtils.logGameCollectionSquareFlush("下拉刷新", mViewModel.refreshCount)
        SensorsBridge.trackEvent("GameCollectSquareFlush", json {
            "action" to "下拉刷新"
            "count_num" to mViewModel.refreshCount
        })
        super.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(com.gh.gamecenter.common.R.color.ui_surface.toColor(requireContext()))
        } else if (::mDefaultBinding.isInitialized) {
            initSkeleton()
            showSkeleton(mListViewModel.loadStatusLiveData.value == LoadStatus.INIT_LOADING)
            mDefaultBinding.listRefresh.setBackgroundColor(com.gh.gamecenter.common.R.color.ui_surface.toColor(requireContext()))
            mDefaultBinding.appbar.setBackgroundColor(com.gh.gamecenter.common.R.color.ui_surface.toColor(requireContext()))
            mDefaultBinding.toolbar.navigationIcon = com.gh.gamecenter.common.R.drawable.ic_bar_back.toDrawable(requireContext())
            mDefaultBinding.collapsingToolbar.setContentScrimColor(com.gh.gamecenter.common.R.color.ui_surface.toColor(requireContext()))
            mDefaultBinding.tagFilterContainer.orderSfv.run {
                setContainerBackground(com.gh.gamecenter.common.R.drawable.button_round_f5f5f5.toDrawable(requireContext()))
                setIndicatorBackground(R.drawable.bg_game_collection_sfv_indicator.toDrawable(requireContext()))
                setTextColor(
                    com.gh.gamecenter.common.R.color.text_secondary.toColor(requireContext()),
                    com.gh.gamecenter.common.R.color.text_tertiary.toColor(requireContext())
                )
            }
            DisplayUtils.setLightStatusBar(requireActivity(), !mIsDarkModeOn)
            changeToolbarStyle(mIsCollapsed)
        }
    }

    companion object {
        const val REQUEST_SELECT_TAG = 100
        const val BANNER_LOOP_TIME = 3500L
        const val HOME_FILTER_ITEM_POSITION = 1
    }

    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()
            }
        }
    }

}