package com.gh.gamecenter.forum.detail

import android.graphics.Color
import android.os.Bundle
import android.view.View
import androidx.recyclerview.widget.RecyclerView
import com.ethanhua.skeleton.Skeleton
import com.gh.common.util.NewLogUtils
import com.gh.gamecenter.R
import com.gh.gamecenter.common.baselist.LazyListFragment
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.constant.EntranceConsts
import com.gh.gamecenter.common.utils.safelyGetInRelease
import com.gh.gamecenter.common.utils.toColor
import com.gh.gamecenter.common.utils.tryCatchInRelease
import com.gh.gamecenter.common.utils.viewModelProvider
import com.gh.gamecenter.core.AppExecutor
import com.gh.gamecenter.core.iinterface.IScrollable
import com.gh.gamecenter.core.utils.MD5Utils
import com.gh.gamecenter.databinding.FragmentListBaseSkeletonBinding
import com.gh.gamecenter.entity.ForumDetailEntity
import com.gh.gamecenter.eventbus.EBDeleteDetail
import com.gh.gamecenter.eventbus.EBTypeChange
import com.gh.gamecenter.eventbus.EBUserFollow
import com.gh.gamecenter.forum.home.ForumScrollCalculatorHelper
import com.gh.gamecenter.feature.entity.AnswerEntity
import com.gh.gamecenter.video.detail.CustomManager
import com.shuyu.gsyvideoplayer.video.base.GSYVideoView
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode

class ForumArticleAskListFragment : LazyListFragment<AnswerEntity, ForumArticleAskListViewModel>(), IScrollable {

    private var mAdapter: ForumArticleAskListAdapter? = null
    private var mViewModel: ForumArticleAskListViewModel? = null
    private var mScrollCalculatorHelper: ForumScrollCalculatorHelper? = null
    private lateinit var mBinding: FragmentListBaseSkeletonBinding
    private var mPath = ""
    private var bbsId: String = ""
    private var mListReachTop = true

    var filter = "回复"
    var videoFilter = "推荐"

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

    override fun onRealLayoutInflated(inflatedView: View) {
        super.onRealLayoutInflated(inflatedView)
        mBinding = FragmentListBaseSkeletonBinding.bind(inflatedView)
    }

    override fun provideListViewModel(): ForumArticleAskListViewModel {
        if (mViewModel == null) {
            val factory = ForumArticleAskListViewModel.Factory(bbsId, mPath)
            mViewModel = viewModelProvider(factory)
        }
        return mViewModel!!
    }

    override fun provideListAdapter() = mAdapter ?: ForumArticleAskListAdapter(
        requireContext(),
        bbsId,
        mEntrance,
        mPath,
        mViewModel!!
    ) {
        onRefresh(it)
    }.apply { mAdapter = this }

    override fun getItemDecoration() = null

    override fun onCreate(savedInstanceState: Bundle?) {
        bbsId = arguments?.getString(EntranceConsts.KEY_BBS_ID, "") ?: ""
        mPath = arguments?.getString(EntranceConsts.KEY_PATH) ?: ""
        super.onCreate(savedInstanceState)
    }

    override fun onFragmentFirstVisible() {
        super.onFragmentFirstVisible()
        mListRv.overScrollMode = View.OVER_SCROLL_NEVER
        mListRefresh?.isEnabled = false
        mListRv.setBackgroundColor(R.color.background_white.toColor(requireContext()))
        mScrollCalculatorHelper = ForumScrollCalculatorHelper(R.id.horizontalVideoView, R.id.verticalVideoView, 0)

        requireView().setBackgroundColor(R.color.background_white.toColor(requireContext()))

        mSkeletonScreen = Skeleton.bind(mBinding.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.forum_article_ask_list_skeleton)
            .show()

        onLoadRefresh()

        mListRv.addOnScrollListener(object : RecyclerView.OnScrollListener() {

            override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
                super.onScrollStateChanged(recyclerView, newState)
                mListReachTop = !recyclerView.canScrollVertically(-1)
                setRefreshingLayoutEnable(mListReachTop)

                mScrollCalculatorHelper?.onScrollStateChanged(mListRv, newState)

                if (newState == RecyclerView.SCROLL_STATE_IDLE) {
                    var position = mLayoutManager.findLastCompletelyVisibleItemPosition()
                    if (position == -1) position = mLayoutManager.findLastVisibleItemPosition() - 1
                    NewLogUtils.logForumDetailFeedSlide(position + 1)
                }
            }

            override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
                super.onScrolled(recyclerView, dx, dy)
                if (dy > Constants.FOLLOW_HINT_TRIGGER_HEIGHT) {
                    EventBus.getDefault().post(EBTypeChange(ForumDetailFragment.EB_HIDE_QUESTION_BUTTON, 0))
                } else if (dy < -Constants.FOLLOW_HINT_TRIGGER_HEIGHT) {
                    EventBus.getDefault().post(EBTypeChange(ForumDetailFragment.EB_SHOW_QUESTION_BUTTON, 0))
                }
                if (dy != 0) scroll()
            }
        })
    }

    override fun onFragmentResume() {
        resumeVideo()
        super.onFragmentResume()
    }

    override fun onFragmentPause() {
        super.onFragmentPause()
        pauseVideo()
    }

    override fun onDestroy() {
        super.onDestroy()
        mScrollCalculatorHelper?.currentPlayer?.release()
    }

    override fun onLoadRefresh() {
        super.onLoadRefresh()
        requireView().setBackgroundColor(R.color.background_white.toColor(requireContext()))
    }

    override fun onLoadDone() {
        super.onLoadDone()
        requireView().setBackgroundColor(Color.TRANSPARENT)
        AppExecutor.uiExecutor.executeWithDelay(Runnable {
            tryCatchInRelease {
                scroll()
                mScrollCalculatorHelper?.onScrollStateChanged(mListRv, RecyclerView.SCROLL_STATE_IDLE)
            }
        }, 100)
    }

    override fun onLoadError() {
        super.onLoadError()
        requireView().setBackgroundColor(Color.TRANSPARENT)
    }

    override fun onLoadEmpty() {
        super.onLoadEmpty()
        requireView().setBackgroundColor(Color.TRANSPARENT)
    }

    override fun hideRefreshingLayout() {
        (parentFragment as? ForumDetailFragment)?.hideRefreshingLayout()
    }

    fun refresh() {
        onRefresh()
    }

    fun onRefresh(filter: String) {
        if (mPath == "全部" || mPath == "问答") {
            this.filter = filter
            mViewModel?.sort = if (filter == "发布") "time.create" else "time.reply"
        }
        if (mPath == "视频") {
            videoFilter = filter
            mViewModel?.videoSort = if (filter == "推荐") "recommend" else "time.upload"
        }
        onRefresh()
    }

    override fun onRefresh() {
        mScrollCalculatorHelper?.currentPlayer?.release()
        mScrollCalculatorHelper?.reset()
        super.onRefresh()
    }

    // 插入一条数据到首位
    fun insertDataToFirstIndex(entity: AnswerEntity) {
        mAdapter?.run {
            if (entityList == null) return

            // 在选择对应子版块或选择全部时才插入数据
            if (entity.sectionIdList.contains(mViewModel?.selectedSection?.id) || mViewModel?.selectedSection?.id.isNullOrEmpty()) {
                if (entityList.size == 0) {
                    mListRv?.visibility = View.VISIBLE
                    mReuseNoData?.visibility = View.GONE
                    mReuseNoConn?.visibility = View.GONE
                    entityList.add(AnswerEntity())
                }

                entityList.add(1, entity)
                notifyDataSetChanged()
                mViewModel?.videoList?.add(0, entity.transformForumVideoEntity())
                mListRv?.scrollToPosition(1)
                mBaseHandler.postDelayed({
                    tryCatchInRelease {
                        scroll()
                        mScrollCalculatorHelper?.onScrollStateChanged(mListRv, RecyclerView.SCROLL_STATE_IDLE)
                    }
                }, 100)
            }
        }
    }

    private fun scroll() {
        val firstVisibleItem = mLayoutManager?.findFirstVisibleItemPosition() ?: -1
        val lastVisibleItem = mLayoutManager?.findLastVisibleItemPosition() ?: -1
        mScrollCalculatorHelper?.onScroll(mViewModel?.videoList, firstVisibleItem, lastVisibleItem)
    }

    private fun resumeVideo() {
        mScrollCalculatorHelper?.run {
            if (currentPlayer != null
                && currentPosition >= 0
                && currentPosition < mViewModel?.videoList?.size ?: 0
            ) {
                val video = mViewModel?.videoList?.safelyGetInRelease(currentPosition)
                if (video != null) {
                    val position = ForumScrollCalculatorHelper.getPlaySchedule(MD5Utils.getContentMD5(video.url))
                    //这里必须要延迟操作，否则会白屏
                    mBaseHandler.postDelayed({
                        tryCatchInRelease {
                            if (position != 0L) {
                                if (currentPlayer?.currentState == GSYVideoView.CURRENT_STATE_PAUSE) {
                                    currentPlayer?.startPlayLogic(true)
                                }
                            } else {
                                currentPlayer?.release()
                            }
                        }
                    }, 50)
                }
            }
        }
    }

    private fun pauseVideo() {
        mScrollCalculatorHelper?.run {
            if (currentPlayer != null
                && currentPosition >= 0
                && currentPosition < mViewModel?.videoList?.size ?: 0
            ) {
                currentPlayer?.onVideoPause()
                val position = currentPlayer?.getCurrentPosition() ?: 0L
                val video = mViewModel?.videoList?.safelyGetInRelease(currentPosition)
                if (video != null) {
                    ForumScrollCalculatorHelper.savePlaySchedule(MD5Utils.getContentMD5(video.url), position)
                }
            }
        }
    }

    fun refreshScrollHelper() {
        mBaseHandler.postDelayed({
            tryCatchInRelease {
                scroll()
                mScrollCalculatorHelper?.onScrollStateChanged(mListRv, RecyclerView.SCROLL_STATE_IDLE)
            }
        }, 100)
    }

    fun isListReachTop() = mListReachTop

    fun setRefreshingLayoutEnable(listReachTop: Boolean) {
        (parentFragment as? ForumDetailFragment)?.setRefreshingLayoutEnable(listReachTop)
    }

    override fun scrollToTop() {
        mListRv?.scrollToPosition(0)
    }

    override fun addSyncPageObserver(): Boolean = true

    override fun provideSyncAdapter() = mAdapter

    override fun onBackPressed(): Boolean {
        mScrollCalculatorHelper?.currentPlayer?.run {
            return (isIfCurrentIsFullscreen
                    && CustomManager.backFromWindowFull(requireActivity(), getKey()))
        }
        return super.onBackPressed()
    }

    override fun isAutomaticLoad(): Boolean = false

    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onEvent(detail: EBDeleteDetail) {
        val currentEntity = mAdapter?.entityList?.find { it.id == detail.id }
        val indexOf = mAdapter?.entityList?.indexOf(currentEntity) ?: 0
        mAdapter?.entityList?.remove(currentEntity)
        mAdapter?.notifyItemRemoved(indexOf)
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onUserFollow(change: EBUserFollow) {
        mAdapter?.run {
            var count = 0
            entityList.forEach {
                if (it.user.id == change.userId) {
                    count++
                    it.me.isFollower = change.isFollow
                }
            }
            if (count > 1) notifyDataSetChanged()
        }
    }

    fun setSection(section: ForumDetailEntity.Section) {
        mViewModel?.selectedSection = section
        onRefresh()
    }

    override fun onDarkModeChanged() {
        super.onDarkModeChanged()
        mAdapter?.run { notifyItemRangeChanged(0, itemCount) }
    }
}