package com.gh.gamecenter.gamecollection.detail

import android.app.Activity
import android.content.Intent
import android.graphics.Color
import android.os.Bundle
import android.text.SpannableStringBuilder
import android.text.Spanned
import android.view.Gravity
import android.view.View
import android.view.ViewGroup
import android.widget.FrameLayout
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.view.ViewCompat
import androidx.lifecycle.Lifecycle
import androidx.recyclerview.widget.RecyclerView
import com.ethanhua.skeleton.Skeleton
import com.gh.common.exposure.ExposureListener
import com.gh.common.history.HistoryHelper
import com.gh.common.util.DialogUtils
import com.gh.common.util.DirectUtils
import com.gh.common.xapk.XapkInstaller
import com.gh.common.xapk.XapkUnzipStatus
import com.gh.download.DownloadManager
import com.gh.gamecenter.R
import com.gh.gamecenter.common.baselist.ListFragment
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.NormalShareEntity
import com.gh.gamecenter.common.eventbus.EBShare
import com.gh.gamecenter.common.syncpage.SyncDataEntity
import com.gh.gamecenter.common.syncpage.SyncFieldConstants
import com.gh.gamecenter.common.syncpage.SyncPageRepository
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.common.view.SegmentedFilterView
import com.gh.gamecenter.core.iinterface.IScrollable
import com.gh.gamecenter.core.utils.CenterImageSpan
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.databinding.FragmentGameCollectionDetailBinding
import com.gh.gamecenter.databinding.LayoutGameCollectionTagBinding
import com.gh.gamecenter.entity.GamesCollectionDetailEntity
import com.gh.gamecenter.eventbus.EBDownloadStatus
import com.gh.gamecenter.eventbus.EBPackage
import com.gh.gamecenter.eventbus.EBUserFollow
import com.gh.gamecenter.gamedetail.GameDetailFragment
import com.gh.gamecenter.home.video.ScrollCalculatorHelper
import com.gh.gamecenter.login.user.UserManager
import com.gh.gamecenter.login.user.UserViewModel
import com.gh.gamecenter.qa.article.detail.CommentItemData
import com.gh.gamecenter.qa.comment.CommentActivity
import com.gh.gamecenter.qa.comment.base.BaseCommentAdapter
import com.gh.gamecenter.qa.comment.base.BaseCommentViewModel
import com.gh.gamecenter.video.detail.CustomManager
import com.google.android.material.appbar.AppBarLayout
import com.halo.assistant.HaloApp
import com.lightgame.download.DataWatcher
import com.lightgame.download.DownloadEntity
import com.shuyu.gsyvideoplayer.builder.GSYVideoOptionBuilder
import com.shuyu.gsyvideoplayer.listener.GSYSampleCallBack
import com.shuyu.gsyvideoplayer.utils.OrientationUtils
import com.shuyu.gsyvideoplayer.video.base.GSYVideoView
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import kotlin.math.abs

class GameCollectionDetailFragment :
    ListFragment<CommentItemData, GameCollectionDetailViewModel>(), IScrollable {

    private var mBinding: FragmentGameCollectionDetailBinding? = null
    private var mAdapter: GameCollectionDetailAdapter? = null
    private var mEntity: GamesCollectionDetailEntity? = null
    private var mUserViewModel: UserViewModel? = null
    private var mGameCollectionId = ""
    private var mGameCollectionTitle = ""
    private var mScrollToCommentArea = false
    private var mFromSquare = false
    private var mIsLight = false
    private var mIsPauseTopVideo = false
    private var mOrientationUtils: OrientationUtils? = null
    private var mStopUpdateToolbar = false
    private var mIsViewGameCollectionFinished = false // 是否已经完成"浏览游戏单"（浏览至少2s）
    private val mDataWatcher = object : DataWatcher() {
        override fun onDataChanged(downloadEntity: DownloadEntity) {
            mAdapter?.notifyItemByDownload(downloadEntity)

            if (downloadEntity.meta[XapkInstaller.XAPK_UNZIP_STATUS] == XapkUnzipStatus.FAILURE.name) {
                showUnzipFailureDialog(downloadEntity)
            }
        }

        override fun onDataInit(downloadEntity: DownloadEntity) {
            mAdapter?.notifyItemByDownload(downloadEntity)
        }
    }

    override fun getLayoutId() = 0

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

    override fun provideListViewModel() =
        viewModelProvider<GameCollectionDetailViewModel>(
            GameCollectionDetailViewModel.Factory(
                mGameCollectionId,
                arguments?.getString(EntranceConsts.KEY_TOP_COMMENT_ID) ?: ""
            )
        )

    override fun provideListAdapter() =
        mAdapter ?: GameCollectionDetailAdapter(
            requireContext(),
            BaseCommentAdapter.AdapterType.COMMENT,
            mEntrance,
            mListViewModel
        ).apply { mAdapter = this }

    override fun getItemDecoration() = null

    override fun addSyncPageObserver() = true

    override fun provideSyncAdapter() = mAdapter

    override fun onCreate(savedInstanceState: Bundle?) {
        mGameCollectionId = arguments?.getString(EntranceConsts.KEY_GAME_COLLECTION_ID) ?: ""
        mFromSquare = arguments?.getBoolean(EntranceConsts.KEY_IS_FROM_SQUARE, false) ?: false
        mScrollToCommentArea = arguments?.getBoolean(EntranceConsts.KEY_SCROLL_TO_COMMENT_AREA, false) ?: false
        mUserViewModel = viewModelProvider(UserViewModel.Factory(HaloApp.getInstance().application))
        super.onCreate(savedInstanceState)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        initView()
        initObserver()
        mListViewModel.getGameCollectionDetail()

        mListRv.addOnScrollListener(ExposureListener(this, provideListAdapter()))
    }

    private fun initView() {
        mBinding?.run {
            ViewCompat.setOnApplyWindowInsetsListener(appbar) { _, insets ->
                (toolbar.layoutParams as ViewGroup.MarginLayoutParams).topMargin =
                    insets.systemWindowInsetTop
                insets.consumeSystemWindowInsets()
            }

            root.setBackgroundColor(R.color.background_white.toColor(requireContext()))
            mSkeletonScreen = Skeleton.bind(listSkeleton)
                .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(R.layout.fragment_game_collection_detail_skeleton)
                .show()

            inputContainer.run {
                bottomShareGroup.visibility = View.VISIBLE
                replyTv.setBackgroundResource(R.drawable.bg_shape_space2_radius_999)
                replyTv.text = "说点什么吧"
                (bottomLikeIv.layoutParams as ConstraintLayout.LayoutParams).apply {
                    rightMargin = 28f.dip2px()
                    mBinding?.inputContainer?.bottomLikeIv?.layoutParams = this
                }
            }
            fixedTopFilterView.run {
                (root.layoutParams as ViewGroup.MarginLayoutParams).apply {
                    topMargin = DisplayUtils.getStatusBarHeight(resources) + 48F.dip2px()
                    root.layoutParams = this
                }
                orderSfv.setItemList(listOf("正序", "倒序"), 0)
                orderSfv.setOnCheckedCallback(object : SegmentedFilterView.OnCheckedCallback {
                    override fun onItemCheck(position: Int) {
                        getFilterVH()?.binding?.orderSfv?.performClick(position)
                        updateFilterView()
                    }
                })
                commentHintTv.text = "玩家评论"
            }
        }
    }

    private fun initObserver() {
        mListViewModel.loadResultLiveData.observeNonNull(this) {
            when (it) {
                BaseCommentViewModel.LoadResult.SUCCESS -> initSuccessResult()

                else -> initFailResult(it)
            }
        }

        mListViewModel.followLiveData.observeNonNull(this) {
            updateFollowView()
        }

        mListViewModel.favoriteLiveData.observeNonNull(this) {
            updateStarView()
        }

        mListViewModel.likeLiveData.observeNonNull(this) {
            updateLikeView()
        }

        mListViewModel.shareLiveData.observeNonNull(this) {
            updateShareView()
        }

        mUserViewModel?.loginObsUserinfo?.observeNonNull(viewLifecycleOwner) {
            if (it.data != null && mEntity != null) {
                mListViewModel.getGameCollectionDetail()
                mListViewModel.load(LoadType.REFRESH)
            }
        }

        mListViewModel.firstItemInitOverLiveData.observeNonNull(this) {
            if (mScrollToCommentArea) mBinding?.inputContainer?.bottomCommentIv?.performClick()
        }
    }

    private fun initSuccessResult() {
        showSkeleton(false)
        mBinding?.root?.setBackgroundColor(Color.TRANSPARENT)
        mEntity = mListViewModel.gameCollectionDetail
        mGameCollectionTitle = mListViewModel.gameCollectionDetail?.title ?: ""

        if (mEntity?.display == "self_only") {
            HistoryHelper.deleteGamesCollectionEntity(mGameCollectionId)
        }

        if (!mIsViewGameCollectionFinished) {
            postDelayedRunnable({
                tryCatchInRelease {
                    if (!isEverPause && !mIsViewGameCollectionFinished) {
                        mIsViewGameCollectionFinished = true
                        logEvent("view_game_collect_detail")
                        mListViewModel.postGameCollectionTask("browse_game_list", mGameCollectionId)
                    }
                }
            }, 2000)
        }

        updateView()
        initViewListener()
    }

    private fun initFailResult(result: BaseCommentViewModel.LoadResult) {
        if (result == BaseCommentViewModel.LoadResult.DELETED) {
            HistoryHelper.deleteGamesCollectionEntity(mGameCollectionId)
            mReuseNoConn?.visibility = View.GONE
            mReuseNoData?.visibility = View.VISIBLE
            toast(R.string.content_delete_toast)
        } else {
            mReuseNoConn?.visibility = View.VISIBLE
            mReuseNoData?.visibility = View.GONE
            mReuseNoConn?.setOnClickListener {
                mListViewModel.getGameCollectionDetail()
                mReuseNoConn?.visibility = View.GONE
                showSkeleton(true)
                mBinding?.root?.setBackgroundColor(R.color.background_white.toColor(requireContext()))
            }
        }

        DisplayUtils.setStatusBarColor(requireActivity(), R.color.background_white, !mIsDarkModeOn)
        mBinding?.toolbarContainer?.setBackgroundColor(R.color.background_white.toColor(requireContext()))
        mBinding?.backIv?.setImageResource(R.drawable.ic_bar_back)

        mListLoading?.visibility = View.GONE
        mBinding?.inputContainer?.bottomContainer?.visibility = View.GONE
        mBinding?.bottomShadowView?.visibility = View.GONE
        showSkeleton(false)
        mBinding?.root?.setBackgroundColor(Color.TRANSPARENT)
    }

    private fun initViewListener() {
        mBinding?.appbar?.addOnOffsetChangedListener(AppBarLayout.OnOffsetChangedListener { appBarLayout, verticalOffset ->
            if (!isAdded) return@OnOffsetChangedListener

            val absVerticalOffset = abs(verticalOffset)
            val total = appBarLayout.totalScrollRange

            mBinding?.run {
                val bgOffset = if (mListViewModel.displayTopVideo) {
                    videoItem.player.bottom - DisplayUtils.getStatusBarHeight(resources) - 48F.dip2px()
                } else {
                    total - 44F.dip2px()
                }
                val curIsLight = absVerticalOffset < bgOffset
                if (mIsLight != curIsLight) {
                    mIsLight = curIsLight
                    if (!mStopUpdateToolbar) {
                        updateFollowView()
                        updateToolbar()
                    }
                }

                if (mListViewModel.displayTopVideo) {
                    if (absVerticalOffset == total
                        && videoItem.player.currentState == GSYVideoView.CURRENT_STATE_PLAYING
                    ) {
                        pauseVideo()
                        mIsPauseTopVideo = true
                    } else if (mIsPauseTopVideo
                        && absVerticalOffset == 0
                        && videoItem.player.currentState == GSYVideoView.CURRENT_STATE_PAUSE
                    ) {
                        resumeVideo()
                        mIsPauseTopVideo = false
                    }
                }
            }
        })

        mListRv?.addOnScrollListener(object : RecyclerView.OnScrollListener() {
            override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
                super.onScrolled(recyclerView, dx, dy)
                val firstCompletelyVisiblePosition = mLayoutManager.findFirstCompletelyVisibleItemPosition()
                if (RecyclerView.NO_POSITION == firstCompletelyVisiblePosition) return

                val filterView = mLayoutManager.findViewByPosition(mListViewModel.filterPos)

                if (firstCompletelyVisiblePosition >= mListViewModel.filterPos + 1 && filterView == null) {
                    mBinding?.fixedTopFilterView?.root?.visibility = View.VISIBLE
                    updateFilterView()
                } else {
                    filterView?.let {
                        if (it.top <= 0 && mBinding?.fixedTopFilterView?.root?.visibility == View.GONE) {
                            mBinding?.fixedTopFilterView?.root?.visibility = View.VISIBLE
                            updateFilterView()
                        } else if (it.top > 0 && mBinding?.fixedTopFilterView?.root?.visibility == View.VISIBLE) {
                            mBinding?.fixedTopFilterView?.root?.visibility = View.GONE
                        }
                    }
                }
            }
        })
    }

    private fun updateToolbar(isLight: Boolean? = null) {
        mBinding?.run {
            if (isLight ?: mIsLight) {
                DisplayUtils.setStatusBarColor(requireActivity(), R.color.transparent, false)
                toolbarContainer.setBackgroundColor(Color.TRANSPARENT)
                backIv.setImageResource(R.drawable.ic_bar_back_light)
                squareIv.setImageResource(R.drawable.ic_game_collection_square_light)
                toolbarUserContainer.visibility = View.GONE
            } else {
                DisplayUtils.setStatusBarColor(requireActivity(), R.color.background_white, !mIsDarkModeOn)
                toolbarContainer.setBackgroundColor(R.color.background_white.toColor(requireContext()))
                backIv.setImageResource(R.drawable.ic_bar_back)
                squareIv.setImageResource(if (mIsDarkModeOn) R.drawable.ic_game_collection_square_light else R.drawable.ic_game_collection_square)
                toolbarUserContainer.visibility = View.VISIBLE
            }
        }
    }

    private fun updateView() {
        mReuseNoConn?.visibility = View.GONE
        mListLoading?.visibility = View.GONE

        initTopView()
        setViewClickListener()
        updateFollowView()
        updateCommentView()
        updateStarView()
        updateLikeView()
        updateShareView()

        mReuseNoConn?.setOnClickListener {
            mReuseNoConn?.visibility = View.GONE
            mListLoading?.visibility = View.VISIBLE
            mListViewModel.getGameCollectionDetail()
        }
    }

    private fun setViewClickListener() {
        mBinding?.run {
            arrayListOf(
                toolbar,
                backIv,
                squareIv,
                imageItem.imageItemDesTv,
                videoItem.videoItemDesTv,
                toolbarUserContainer,
                imageItem.userIcon,
                imageItem.userInfo,
                videoItem.userIcon,
                videoItem.userInfo,
                toolbarFollowTv,
                imageItem.imageItemFollowTv,
                imageItem.imageItemFollowedTv,
                videoItem.videoItemFollowTv,
                videoItem.videoItemFollowedTv,
                inputContainer.replyTv,
                inputContainer.bottomCommentIv,
                inputContainer.bottomCommentTv,
                inputContainer.bottomStarIv,
                inputContainer.bottomStarTv,
                inputContainer.bottomLikeIv,
                inputContainer.bottomLikeTv,
                inputContainer.bottomShareIv,
                inputContainer.bottomShareTv,
            ).forEach {
                it.setOnClickListener(this@GameCollectionDetailFragment)
            }
        }
    }

    private fun initTopView() {
        mBinding?.run {
            val isLogin = UserManager.getInstance().isLoggedIn
            tagContainer.goneIf(isLogin)
            playedContainer.goneIf(!isLogin)
            playedPro.max = mEntity?.count?.game ?: 0
            playedPro.progress = mEntity?.count?.playedGame ?: 0
            playedTv.text = "玩过 ${mEntity?.count?.playedGame} / ${mEntity?.count?.game} 款"
            toolbarUserIcon.display("", mEntity?.user?.icon, mEntity?.user?.auth?.icon)
            toolbarUserName.text = mEntity?.user?.name
            squareIv.goneIf(mFromSquare)
            divider.visibility = View.VISIBLE

            if (!mListViewModel.displayTopVideo) {
                imageItem.root.visibility = View.VISIBLE
                videoItem.root.visibility = View.GONE
                initImageTypeView()
            } else {
                imageItem.root.visibility = View.GONE
                videoItem.root.visibility = View.VISIBLE
                initVideoTypeView()
            }

            if (!UserManager.getInstance().isLoggedIn) {
                mEntity?.tags?.forEachIndexed { index, tag ->
                    tagList.addView(
                        getTagView(
                            tag.name,
                            index == mEntity!!.tags!!.size - 1,
                        )
                    )
                }
            }
        }
    }

    private fun initImageTypeView() {
        mBinding?.imageItem?.run {
            mEntity?.run {
                initGameCollectionTitle(this, nameTv)
                userNameTv.text = user?.name
                ImageUtils.display(poster, cover)
                tagIv.goneIf(stamp.isEmpty())
                imageItemDesTv.text = intro
                imageActivityLabelTv.goneIf(activityTags.isNullOrEmpty())
                ipRegionTv.goneIf(!(source != null && source.region.isNotEmpty()))
                ipRegionTv.text = "IP属地：${source?.region}"
                if (!activityTags.isNullOrEmpty()) {
                    imageActivityLabelTv.text = activityTags!![0].name
                    nameTv.layoutParams =
                        (nameTv.layoutParams as ConstraintLayout.LayoutParams).apply {
                            setMargins(
                                16F.dip2px(),
                                0,
                                30F.dip2px(),
                                6F.dip2px()
                            )
                        }
                }

                when (stamp) {
                    "special_choice" -> {
                        tagIv.setBackgroundResource(R.drawable.ic_chosen_big)
                    }
                    "official" -> {
                        tagIv.setBackgroundResource(R.drawable.ic_official_big)
                    }
                }

                userIcon.display("", user?.icon, user?.auth?.icon)
            }
        }
    }

    private fun initVideoTypeView() {
        mBinding?.videoItem?.run {
            mEntity?.run {
                tagIv.goneIf(stamp.isEmpty())
                initGameCollectionTitle(this, nameTv)
                userNameTv.text = user?.name
                videoItemDesTv.text = intro
                videoActivityLabelTv.goneIf(activityTags.isNullOrEmpty())
                ipRegionTv.goneIf(!(source != null && source.region.isNotEmpty()))
                ipRegionTv.text = "IP属地：${source?.region}"
                if (!activityTags.isNullOrEmpty()) {
                    videoActivityLabelTv.text = activityTags!![0].name
                    videoItemDesContainer.layoutParams =
                        (videoItemDesContainer.layoutParams as ConstraintLayout.LayoutParams).apply {
                            setMargins(
                                0,
                                6F.dip2px(),
                                0,
                                0
                            )
                        }
                }

                when (stamp) {
                    "special_choice" -> {
                        tagIv.setBackgroundResource(R.drawable.ic_chosen_big)
                    }
                    "official" -> {
                        tagIv.setBackgroundResource(R.drawable.ic_official_big)
                    }
                }

                userIcon.display("", user?.icon, user?.auth?.icon)

                setUpTopVideo(video!!)
            }
        }
    }

    private fun initGameCollectionTitle(entity: GamesCollectionDetailEntity, nameTv: TextView) {
        entity.run {
            if (adIconActive) {
                val adLabelView = TextView(context).apply {
                    layoutParams =
                        FrameLayout.LayoutParams(21F.dip2px(), 14F.dip2px()).apply { leftMargin = 4F.dip2px() }
                    background = R.drawable.bg_ad_label.toDrawable(context)
                    text = "AD"
                    textSize = 10F
                    setTextColor(Color.WHITE)
                    gravity = Gravity.CENTER
                }
                adLabelView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED)
                val adLabelBitmap = FrameLayout(requireContext()).apply { addView(adLabelView) }.convertViewToBitmap()
                nameTv.text = SpannableStringBuilder("$title ").apply {
                    setSpan(
                        CenterImageSpan(context, adLabelBitmap),
                        title.length,
                        title.length + 1,
                        Spanned.SPAN_EXCLUSIVE_INCLUSIVE
                    )
                }
            } else {
                nameTv.text = title
            }
        }
    }

    private fun getTagView(
        content: String,
        isLast: Boolean,
    ): View {
        return LayoutGameCollectionTagBinding.inflate(layoutInflater).apply {
            divider.goneIf(isLast)
            divider.setBackgroundColor(R.color.theme_alpha_20.toColor(requireContext()))
            contentTv.text = content
            contentTv.setTextColor(R.color.theme_font.toColor(requireContext()))
        }.root
    }

    private fun updateFollowView(isLight: Boolean? = null) {
        if (mEntity?.user?.id == UserManager.getInstance().userId) {
            mBinding?.run {
                toolbarFollowTv.visibility = View.GONE
                imageItem.imageItemFollowTv.visibility = View.GONE
                videoItem.videoItemFollowTv.visibility = View.GONE
            }
            return
        }

        mBinding?.toolbarFollowTv?.run {
            val isFollow = mEntity?.me?.isFollower ?: false
            if (isLight ?: mIsLight) {
                visibility = View.GONE
            } else {
                visibility = View.VISIBLE
                text = if (isFollow) "已关注" else "关注"
                setBackgroundResource(if (isFollow) R.drawable.button_round_f5f5f5 else R.drawable.button_round_2496ff_alpha_10)
                setTextColor(
                    if (isFollow) R.color.text_subtitleDesc.toColor(requireContext()) else R.color.theme.toColor(
                        requireContext()
                    )
                )
            }
        }

        if (!mListViewModel.displayTopVideo) {
            updateImageItemFollowView()
        } else {
            updateVideoItemFollowView()
        }
    }

    private fun updateImageItemFollowView() {
        mBinding?.imageItem?.run {
            if (mEntity?.me?.isFollower == true) {
                imageItemFollowTv.visibility = View.GONE
                imageItemFollowedTv.visibility = View.VISIBLE
            } else {
                imageItemFollowTv.visibility = View.VISIBLE
                imageItemFollowedTv.visibility = View.GONE
            }
        }
    }

    private fun updateVideoItemFollowView() {
        mBinding?.videoItem?.run {
            if (mEntity?.me?.isFollower == true) {
                videoItemFollowTv.visibility = View.GONE
                videoItemFollowedTv.visibility = View.VISIBLE
            } else {
                videoItemFollowTv.visibility = View.VISIBLE
                videoItemFollowedTv.visibility = View.GONE
            }
        }
    }

    private fun updateCommentView() {
        mBinding?.inputContainer?.run {
            bottomCommentTv.text = mListViewModel.getCommentText()
        }
    }

    private fun updateStarView() {
        mBinding?.inputContainer?.run {
            bottomStarTv.text = mListViewModel.getStarText()
            if (mEntity?.me?.isFavorite == true) {
                bottomStarIv.setImageResource(R.drawable.ic_article_detail_stared_bottom_bar)
                bottomStarTv.setTextColor(R.color.theme_font.toColor(requireContext()))
            } else {
                bottomStarIv.setImageResource(R.drawable.ic_article_detail_star_bottom_bar)
                bottomStarTv.setTextColor(R.color.text_subtitle.toColor(requireContext()))
            }
        }
    }

    private fun updateLikeView() {
        mBinding?.inputContainer?.run {
            bottomLikeTv.text = mListViewModel.getLikeText()
            if (mEntity?.me?.isVoted == true) {
                bottomLikeIv.setImageResource(R.drawable.ic_article_detail_liked_bottom_bar)
                bottomLikeTv.setTextColor(R.color.theme_font.toColor(requireContext()))
            } else {
                bottomLikeIv.setImageResource(R.drawable.ic_article_detail_like_bottom_bar)
                bottomLikeTv.setTextColor(R.color.text_subtitle.toColor(requireContext()))
            }
        }
    }

    private fun updateShareView() {
        mBinding?.inputContainer?.run {
            bottomShareTv.text = mListViewModel.getShareText()
        }
    }

    private fun setUpTopVideo(video: GamesCollectionDetailEntity.Video) {
        mBinding?.videoItem?.player?.run {
            mOrientationUtils = OrientationUtils(requireActivity(), this)
            mOrientationUtils?.isEnable = false

            GSYVideoOptionBuilder()
                .setIsTouchWigetFull(false)
                .setIsTouchWiget(false)
                .setRotateViewAuto(false)
                .setShowFullAnimation(false)
                .setSeekRatio(1f)
                .setUrl(video.url)
                .setCacheWithPlay(true)
                .setVideoAllCallBack(object : GSYSampleCallBack() {
                    override fun onQuitFullscreen(url: String?, vararg objects: Any) {
                        mOrientationUtils?.backToProtVideo()
                        logVideoEvent("video_game_collect_detail_full_cancel")
                    }
                })
                .build(this)

            gameCollectionId = mGameCollectionId
            gameCollectionTitle = mGameCollectionTitle
            viewModel = mListViewModel
            this.video = video
            updateThumb(video.poster)

            //val trafficVideo = PreferenceManager.getDefaultSharedPreferences(context).getBoolean(SettingsFragment.TRAFFIC_VIDEO_SP_KEY, false)
            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 -> {
                    startPlayLogic(isAutoPlay = true)
                }

                Constants.VIDEO_OPTION_WIFI -> {
                    if (NetworkUtils.isWifiConnected(requireContext()) /*|| !trafficVideo*/) {
                        if (mListViewModel.isTopVideoPartlyCached(video.url)) {
                            startPlayLogic(isAutoPlay = true)
                        } else {
                            // 未有缓存时，为避免影响页面加载，延迟自动播放视频
                            postDelayedRunnable({
                                if (activity != null && activity?.isFinishing != true) {
                                    startPlayLogic(isAutoPlay = true)
                                }
                            }, GameDetailFragment.INITIAL_DELAY)
                        }
                    }
                }

                else -> {
                }
            }

            fullscreenButton.setOnClickListener {
                val horizontalVideoView =
                    startWindowFullscreen(requireContext(), true, true) as? GameCollectionVideoView
                if (horizontalVideoView == null) {
                    toastInInternalRelease("全屏失败，请向技术人员提供具体的操作步骤")
                    return@setOnClickListener
                }
                mOrientationUtils?.resolveByClick()
                horizontalVideoView.uuid = uuid
                horizontalVideoView.viewModel = mListViewModel
                horizontalVideoView.video = video
                horizontalVideoView.updateThumb(video.poster)
                horizontalVideoView.violenceUpdateMuteStatus()
                logVideoEvent("video_game_collect_detail_full")
            }

            observeVolume(this@GameCollectionDetailFragment)
        }
    }

    override fun onLoadDone() {
        mReuseNoConn?.visibility = View.GONE
        mReuseNoData?.visibility = View.GONE
        mListLoading?.visibility = View.GONE

        mListRv.visibility = View.VISIBLE
        hideRefreshingLayout()

        mListRv.postDelayed({
            if (provideListAdapter().itemCount < theNumberNeededToFillAScreen()) {
                autoLoadMore()
            }
        }, autoLoadMoreDelay.toLong())
        mBinding?.root?.setBackgroundColor(Color.TRANSPARENT)
    }

    override fun onLoadEmpty() {
        mListRv.visibility = View.VISIBLE
        mBinding?.root?.setBackgroundColor(Color.TRANSPARENT)
    }

    override fun onLoadError() {
        super.onLoadError()
        mListRv.visibility = View.VISIBLE
        mBinding?.root?.setBackgroundColor(Color.TRANSPARENT)
    }

    override fun onResume() {
        if (isEverPause && mAdapter != null) mAdapter?.notifyDataSetChanged()
        super.onResume()
        DownloadManager.getInstance().addObserver(mDataWatcher)

        if (!mIsPauseTopVideo) {
            resumeVideo()
        }

        if (!mIsViewGameCollectionFinished && mEntity != null) {
            postDelayedRunnable({
                tryCatchInRelease {
                    if (!isEverPause && !mIsViewGameCollectionFinished) {
                        mIsViewGameCollectionFinished = true
                        logEvent("view_game_collect_detail")
                        mListViewModel.postGameCollectionTask("browse_game_list", mGameCollectionId)
                    }
                }
            }, 2000)
        }
    }

    override fun onPause() {
        super.onPause()
        DownloadManager.getInstance().removeObserver(mDataWatcher)

        pauseVideo()
        if (mListViewModel.displayTopVideo) {
            mBinding?.videoItem?.player?.run {
                val currentPosition = getCurrentPosition()
                val topVideo = mEntity?.video
                if (topVideo != null) {
                    ScrollCalculatorHelper.savePlaySchedule(
                        MD5Utils.getContentMD5(topVideo.url),
                        currentPosition
                    )
                }
            }
        }
        mListViewModel.gameCollectionDetail?.let {
            val stayTime = (System.currentTimeMillis() - startPageTime) / 1000
            com.gh.common.util.NewFlatLogUtils.logGameCollectStayTime(stayTime, it.id, it.title)
        }
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (requestCode == CommentActivity.REQUEST_CODE && resultCode == Activity.RESULT_OK) {
            val commentCount = data?.getIntExtra(CommentActivity.COMMENT_COUNT, 0)
            if (commentCount != 0 && commentCount != null) {
                mEntity?.count?.comment = commentCount
                mListViewModel.commentCount = commentCount
                updateCommentView()
                updateFilterView()
                mListViewModel.load(LoadType.REFRESH)
                SyncPageRepository.postSyncData(
                    SyncDataEntity(
                        mGameCollectionId,
                        SyncFieldConstants.ARTICLE_COMMENT_COUNT,
                        mEntity?.count?.comment,
                        checkFieldEntity = true
                    )
                )
            }
        }
    }

    override fun onDestroyView() {
        super.onDestroyView()
        mEntity?.run {
            if (status == "pass" && display != "self_only") {
                HistoryHelper.insertGamesCollectionEntity(this)
            }
        }
    }

    override fun onBackPressed(): Boolean {
        mOrientationUtils?.backToProtVideo()

        if (CustomManager.backFromWindowFull(requireActivity(), mBinding?.videoItem?.player?.getKey())) {
            return true
        }

        return super.onBackPressed()
    }

    override fun onDestroy() {
        super.onDestroy()
        releaseVideo()
        mAdapter?.recommendPrefBitmap?.recycle()
    }

    private fun pauseVideo() {
        if (mListViewModel.displayTopVideo) {
            mBinding?.videoItem?.player?.onVideoPause()
        }
    }

    private fun resumeVideo() {
        if (mListViewModel.displayTopVideo) {
            mBinding?.videoItem?.player?.onVideoResume()
        }
    }

    private fun releaseVideo() {
        if (mListViewModel.displayTopVideo) {
            mBinding?.videoItem?.player?.release()
            mBinding?.videoItem?.player?.disposableTimer()
        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onUserFollow(change: EBUserFollow) {
        mEntity?.me?.isFollower = change.isFollow
        updateFollowView()
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onEventMainThread(share: EBShare?) {
        postDelayedRunnable({
            tryCatchInRelease {
                if (share != null && share.shareEntrance == ShareUtils.ShareEntrance.gameCollection && isAdded) {
                    mListViewModel.postShareGameCollection()
                }
            }
        }, 200)
    }

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

    // 安装/卸载 事件
    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onEventMainThread(busFour: EBPackage) {
        if (busFour.isInstalledOrUninstalled()) {
            if (EBPackage.TYPE_INSTALLED == busFour.type
                && UserManager.getInstance().isLoggedIn
                && (mEntity?.count?.playedGame ?: 0) < (mEntity?.count?.game ?: 0)
            ) {
                mListViewModel?.getGameCollectionDetail()
            }
            mAdapter?.notifyDataSetChanged()
        }
    }

    override fun onClick(v: View) {
        super.onClick(v)
        when (v.id) {
            R.id.toolbar -> scrollToTop()

            R.id.backIv -> requireActivity().finish()

            R.id.imageItemDesTv,
            R.id.videoItemDesTv -> {
                logEvent("click_game_collect_detail_product")
                startActivity(
                    GameCollectionPosterActivity.getIntent(
                        requireContext(),
                        mEntity ?: GamesCollectionDetailEntity()
                    )
                )
            }

            R.id.toolbarUserContainer,
            R.id.userIcon,
            R.id.userInfo -> {
                DirectUtils.directToHomeActivity(requireContext(), mEntity?.user?.id, "", "游戏单详情-导航栏")
            }

            R.id.toolbarFollowTv,
            R.id.imageItemFollowTv,
            R.id.imageItemFollowedTv,
            R.id.videoItemFollowTv,
            R.id.videoItemFollowedTv -> {
                ifLogin("游戏单详情") {
                    if (mEntity?.me?.isFollower == false) {
                        logEvent("click_game_collect_detail_follow")
                        mListViewModel?.followingCommand(mEntity?.user?.id ?: "", true)
                    } else {
                        DialogHelper.showDialog(
                            requireContext(),
                            "取消关注",
                            "确定要取消关注 ${mEntity?.user?.name} 吗？",
                            "确定取消",
                            "暂不取消",
                            {
                                logEvent("click_game_collect_detail_follow_cancel")
                                mListViewModel?.followingCommand(mEntity?.user?.id ?: "", false)
                            },
                            extraConfig = DialogHelper.Config(centerTitle = true, centerContent = true)
                        )
                    }
                }
            }

            R.id.squareIv -> {
                DirectUtils.directToGameCollectionSquare(
                    requireContext(),
                    "游戏单详情",
                    "",
                    mGameCollectionTitle,
                    mGameCollectionId
                )
            }

            R.id.replyTv -> {
                if (isSelfOnly()) return
                debounceActionWithInterval(v.id) {
                    startCommentActivity()
                }
            }

            R.id.bottomCommentIv,
            R.id.bottomCommentTv -> {
                mStopUpdateToolbar = true
                updateToolbar(false)
                updateFollowView(false)
                mListRv.post {
                    mBinding?.appbar?.setExpanded(false)
                    mLayoutManager.scrollToPositionWithOffset(mListViewModel?.filterPos ?: 0, 0)
                    mListRv.postDelayed({
                        tryCatchInRelease {
                            mStopUpdateToolbar = false
                        }
                    }, 500)
                }
            }

            R.id.bottomStarIv,
            R.id.bottomStarTv -> {
                if (isSelfOnly()) return
                debounceActionWithInterval(v.id) {
                    ifLogin("游戏单详情") {
                        if (mEntity?.me?.isFavorite == true) {
                            logEvent("click_game_collect_detail_favorite_cancel")
                        } else {
                            logEvent("click_game_collect_detail_favorite")
                        }
                        mListViewModel?.postFavoriteGameCollection()
                    }
                }
            }

            R.id.bottomLikeIv,
            R.id.bottomLikeTv -> {
                if (isSelfOnly()) return
                debounceActionWithInterval(v.id) {
                    ifLogin("游戏单详情") {
                        mListViewModel?.postVoteGameCollection()
                    }
                }
            }

            R.id.bottomShareIv,
            R.id.bottomShareTv -> {
                if (isSelfOnly()) return
                showMoreItemDialog()
            }
        }
    }

    private fun updateFilterView() {
        mBinding?.fixedTopFilterView?.run {
            getFilterVH()?.run {
                binding.commentHintCountTv.text = provideListViewModel().commentCount.toNewSimpleCount()

                orderSfv.setChecked(getFilterVH()?.binding?.orderSfv?.getCurrentPosition() ?: 0)
                commentHintTv.text = binding.commentHintTv.text
                commentHintCountTv.text = binding.commentHintCountTv.text
            }
        }
    }

    private fun getFilterVH(): BaseCommentAdapter.CommentFilterViewHolder? {
        return (provideListAdapter() as BaseCommentAdapter).filterVH
    }

    private fun isSelfOnly(): Boolean {
        val isSelfOnly = mEntity?.display == "self_only"
        if (isSelfOnly) toast("游戏单为仅自己可见状态")
        return isSelfOnly
    }

    private fun showMoreItemDialog() {
        if (!lifecycle.currentState.isAtLeast(Lifecycle.State.STARTED)) return
        mEntity?.run {
            GameCollectionShareDialog.showMoreDialog(
                requireActivity() as AppCompatActivity,
                getShareEntity(this)
            )
        }
    }

    private fun startCommentActivity() {
        mEntity?.run {
            val intent = CommentActivity.getGameCollectionCommentIntent(
                requireContext(),
                id,
                count?.comment ?: 0
            )
            startActivityForResult(intent, CommentActivity.REQUEST_CODE)
        }
    }

    private fun getShareEntity(entity: GamesCollectionDetailEntity): NormalShareEntity {
        val shareUrl = if (isPublishEnv()) {
            Constants.GAME_COLLECTION_SHARE_ADDRESS
        } else {
            Constants.GAME_COLLECTION_SHARE_ADDRESS_DEV
        } + "&id=${entity.id}"
        return NormalShareEntity(
            id = entity.id,
            shareUrl = shareUrl,
            shareIcon = entity.cover,
            shareTitle = entity.title,
            shareSummary = entity.intro,
            shareEntrance = ShareUtils.ShareEntrance.gameCollection
        )
    }

    fun showUnzipFailureDialog(downloadEntity: DownloadEntity) {
        val data = mAdapter?.positionAndPackageMap ?: return
        for (gameAndPosition in data) {
            if (gameAndPosition.key.contains(downloadEntity.packageName)) {
                val targetView = mLayoutManager.findViewByPosition(gameAndPosition.value)
                if (targetView != null) {
                    DialogUtils.showUnzipFailureDialog(requireContext(), downloadEntity)
                    return
                }
            }
        }
    }

    private fun logEvent(event: String, shareType: String = "") {
        NewLogUtils.logViewOrClickGameCollectionDetail(
            event,
            mGameCollectionTitle,
            mGameCollectionId,
            shareType
        )
    }

    override fun onDarkModeChanged() {
        super.onDarkModeChanged()
        updateToolbar()
        mAdapter?.let { it.notifyItemRangeChanged(0, it.itemCount) }
        updateStarView()
        updateLikeView()
    }

    override fun scrollToTop() {
        mBinding?.run {
            fixedTopFilterView.root.visibility = View.GONE
            mListRv.scrollToPosition(0)
            appbar.setExpanded(true)
        }
    }
}