package com.gh.gamecenter.forum.home

import android.annotation.SuppressLint
import android.graphics.drawable.GradientDrawable
import android.view.MotionEvent
import android.view.View
import android.widget.ImageView
import android.widget.LinearLayout
import androidx.core.graphics.ColorUtils
import androidx.core.widget.NestedScrollView
import androidx.lifecycle.Observer
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import com.ethanhua.skeleton.Skeleton
import com.ethanhua.skeleton.ViewSkeletonScreen
import com.gh.common.util.*
import com.gh.common.util.NewLogUtils
import com.gh.gamecenter.R
import com.gh.gamecenter.common.base.fragment.LazyFragment
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.common.view.GridSpacingItemColorDecoration
import com.gh.gamecenter.databinding.ForumBannerIndicatorItemBinding
import com.gh.gamecenter.databinding.FragmentForumBinding
import com.gh.gamecenter.entity.ForumBannerEntity
import com.gh.gamecenter.entity.ForumEntity
import com.gh.gamecenter.eventbus.EBForumFollowChange
import com.gh.gamecenter.eventbus.EBForumRecordChange
import com.gh.gamecenter.forum.list.ForumListActivity
import com.gh.gamecenter.login.user.UserViewModel
import com.halo.assistant.HaloApp
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode

class ForumFragment : LazyFragment(), SwipeRefreshLayout.OnRefreshListener {

    private var mBinding: FragmentForumBinding? = null
    private var mViewModel: ForumViewModel? = null
    private var mUserViewModel: UserViewModel? = null
    private var mSkeleton: ViewSkeletonScreen? = null
    private var mHaveFollowForum = false
    private var mHaveHotForum = false
    private var mIsFirst = true
    private var mIsAutoScroll = true
    private var mIsLogin = CheckLoginUtils.isLogin()
    private var mBanners = listOf<ForumBannerEntity>()
    var translationY = 0

    override fun getRealLayoutId(): Int {
        return R.layout.fragment_forum
    }

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

    override fun onFragmentFirstVisible() {
        mViewModel = viewModelProvider()
        mUserViewModel = viewModelProvider(UserViewModel.Factory(HaloApp.getInstance().application))
        super.onFragmentFirstVisible()
    }

    override fun initRealView() {
        super.initRealView()

        mSkeleton = Skeleton.bind(mBinding?.skeleton)
            .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_forum_skeleton)
            .show()

        mUserViewModel?.loginObsUserinfo?.observe(this, Observer {
            debounceActionWithInterval(id, 500L) {
                if (!mIsFirst && mIsLogin != CheckLoginUtils.isLogin()) {
                    mIsLogin = CheckLoginUtils.isLogin()
                    if (it?.data == null) {
                        mViewModel?.followForums?.clear()
                        mBinding?.followForumContainer?.visibility = View.GONE
                    }
                    onRefresh()
                }
            }
        })

        mViewModel?.banners?.observeNonNull(viewLifecycleOwner) {
            mBanners = it
            initBanners()
        }

        mViewModel?.followForumsLiveData?.observe(viewLifecycleOwner, Observer {
            hideRefreshingLayout()
            mBinding?.run {
                mSkeleton?.hide()
                if (it != null) {
                    reuseNoConnection.root.visibility = View.GONE
                    if (it.isNotEmpty()) {
                        mHaveFollowForum = true
                        initFollowForums(it)
                    }
                    if (!mHaveHotForum) mViewModel?.getHotForum()
                } else {
                    reuseLoading.root.visibility = View.GONE
                    reuseNoneData.root.visibility = View.GONE
                    reuseNoConnection.root.visibility = View.VISIBLE
                    reuseNoConnection.root.setOnClickListener {
                        onRefresh()
                    }
                }
            }
        })

        mViewModel?.hotForums?.observe(viewLifecycleOwner, Observer {
            hideRefreshingLayout()
            mBinding?.run {
                reuseLoading.root.visibility = View.GONE
                mSkeleton?.hide()
                if (mHaveFollowForum) {
                    if (it != null && it.isNotEmpty()) {
                        mHaveHotForum = true
                        initHotForums(it)
                        mBinding?.contentContainer?.visibility = View.VISIBLE
                    }
                } else {
                    if (it != null) {
                        reuseNoConnection.root.visibility = View.GONE
                        if (it.isNotEmpty()) {
                            initHotForums(it)
                            mBinding?.contentContainer?.visibility = View.VISIBLE
                        }
                    } else {
                        reuseNoneData.root.visibility = View.GONE
                        reuseNoConnection.root.visibility = View.VISIBLE
                        reuseNoConnection.root.setOnClickListener {
                            onRefresh()
                        }
                    }
                }
            }
        })

        mViewModel?.officialForums?.observeNonNull(viewLifecycleOwner) {
            hideRefreshingLayout()
            if (it.isNotEmpty()) initOfficialForums(it)
        }

        initWelfare()

        mBinding?.run {
            refreshLayout.setOnRefreshListener(this@ForumFragment)
            contentContainer.setOnScrollChangeListener(NestedScrollView.OnScrollChangeListener { _, _, scrollY, _, _ ->
                translationY = scrollY
                (parentFragment as? CommunityHomeFragment)?.translateTopBg(translationY)
            })
        }
    }

    override fun onFragmentResume() {
        super.onFragmentResume()

        if (mIsFirst) {
            mIsFirst = false
        } else {
            mViewModel?.getForumUnreadStatus()
        }

        if (mBanners.size > 1) {
            mIsAutoScroll = true
            mBinding?.bannerViewPager?.startAutoScroll()
        }

        NewLogUtils.logForumPageEvent("view_forum")
    }

    override fun onFragmentPause() {
        super.onFragmentPause()
        if (mBanners.size > 1) {
            mIsAutoScroll = false
            mBinding?.bannerViewPager?.stopAutoScroll()
        }
    }

    override fun onRefresh() {
        mHaveFollowForum = false
        mHaveHotForum = false
        mSkeleton = Skeleton.bind(mBinding?.skeleton)
            .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_forum_skeleton)
            .show()

        mBinding?.run {
            contentContainer.visibility = View.GONE
            reuseNoConnection.root.visibility = View.GONE
            reuseLoading.root.visibility = if (refreshLayout.isRefreshing) View.GONE else View.VISIBLE
        }
        mBaseHandler.postDelayed({
            tryCatchInRelease { mViewModel?.getData() }
        }, 500)

    }

    private fun hideRefreshingLayout() {
        mBinding?.refreshLayout?.isRefreshing = false
    }

    private fun initBanners() {
        mBinding?.apply {
            if (mBanners.isEmpty()) {
                bannerContainer.visibility = View.GONE
                return
            }
            bannerContainer.visibility = View.VISIBLE
            if (bannerViewPager.adapter != null) {
                (bannerViewPager.adapter as? ForumBannerAdapter)?.checkResetData(mBanners)
            } else {
                val rootWidth = resources.displayMetrics.widthPixels - (16F + 16F).dip2px()
                bannerContainer.layoutParams = bannerContainer.layoutParams.apply {
                    height = rootWidth / 2 + (38F + 8F + 8F).dip2px()
                }
                viewPagerCardView.layoutParams = viewPagerCardView.layoutParams.apply {
                    height = rootWidth / 2
                }

                initBannerViewpager()
            }

            if (indicatorContainer.childCount != mBanners.size) {
                updateViewpagerConfig(indicatorContainer.childCount == 0)
                initBannerIndicator()
            }

            val realPosition =
                (bannerViewPager.adapter as ForumBannerAdapter).getRealPosition(bannerViewPager.currentItem)
            if (realPosition < mBanners.size) {
                changeBannerItem(mBanners[realPosition], realPosition, true)
            }
        }
    }

    private fun initBannerViewpager() {
        mBinding?.bannerViewPager?.run {
            adapter = ForumBannerAdapter(requireContext(), mBanners)
            doOnScroll(
                onPageSelected = { position ->
                    if (mBanners.size <= 1) return@doOnScroll
                    val realPosition = (adapter as ForumBannerAdapter).getRealPosition(position)
                    changeBannerItem(mBanners[realPosition], realPosition)
                },

                onPageScrolled = { position, positionOffset, _ ->
                    if (mBanners.size <= 1) return@doOnScroll
                    val currentPosition = (adapter as ForumBannerAdapter).getRealPosition(position)
                    val nextPosition = (adapter as ForumBannerAdapter).getRealPosition(position + 1)
                    val currentColor =
                        mBanners.safelyGetInRelease(currentPosition)?.placeholderColor?.hexStringToIntColor(
                            R.color.background_white.toColor(requireContext())
                        ) ?: R.color.background_white.toColor(requireContext())
                    val nextColor =
                        mBanners.safelyGetInRelease(nextPosition)?.placeholderColor?.hexStringToIntColor(
                            R.color.background_white.toColor(requireContext())
                        ) ?: R.color.background_white.toColor(requireContext())

                    val colorInBetween = if (currentColor == nextColor) {
                        currentColor
                    } else {
                        ColorUtils.blendARGB(currentColor, nextColor, positionOffset)
                    }

                    changeBannerBg(colorInBetween)
                }
            )

            setBannerViewPagerListener()
        }
    }

    private fun updateViewpagerConfig(isFirst: Boolean) {
        mBinding?.bannerViewPager?.run {
            if (mBanners.size > 1) {
                if (isFirst) {
                    setCurrentItem(mBanners.size * 10, false)
                } else {
                    val offset = mBanners.size - (adapter as ForumBannerAdapter).getRealPosition(currentItem)
                    setCurrentItem(currentItem + offset, false)
                }
                interval = 3000L
                startAutoScroll()
            } else {
                currentItem = 0
                stopAutoScroll()
            }
        }
    }

    @SuppressLint("ClickableViewAccessibility")
    private fun setBannerViewPagerListener() {
        mBinding?.bannerViewPager?.run {
            setOnTouchListener { _, event ->
                if (mBanners.size > 1 && mIsAutoScroll) {
                    if (event.action == MotionEvent.ACTION_DOWN || event.action == MotionEvent.ACTION_MOVE) {
                        stopAutoScroll()
                    } else {
                        startAutoScroll()
                    }
                }
                false
            }
        }
    }

    private fun initBannerIndicator() {
        mBinding?.run {
            indicatorContainer.removeAllViews()
            if (mBanners.size > 1) {
                var i = 0
                val size = mBanners.size
                while (i < size) {
                    indicatorContainer.addView(getBannerIndicatorItemView(i))
                    i++
                }
            }
        }
    }

    private fun getBannerIndicatorItemView(index: Int): View {
        val binding = ForumBannerIndicatorItemBinding.inflate(layoutInflater)
        binding.selectedIv.visibility = if (index == 0) View.VISIBLE else View.GONE
        binding.unSelectIv.visibility = if (index == 0) View.GONE else View.VISIBLE
        binding.root.layoutParams = LinearLayout.LayoutParams(
            LinearLayout.LayoutParams.WRAP_CONTENT,
            LinearLayout.LayoutParams.WRAP_CONTENT
        ).apply {
            if (index != 0) leftMargin = 4F.dip2px() else 0F.dip2px()
        }
        return binding.root
    }

    private fun changeBannerItem(banner: ForumBannerEntity, realPosition: Int, isChangeBg: Boolean = false) {
        mBinding?.run {
            bannerItemTitle.text = banner.title
            if (isChangeBg) {
                changeBannerBg(
                    banner.placeholderColor.hexStringToIntColor(
                        R.color.background_white.toColor(
                            requireContext()
                        )
                    )
                )
            }
            for (i in 0 until indicatorContainer.childCount) {
                indicatorContainer.getChildAt(i).findViewById<ImageView>(R.id.selectedIv).visibility =
                    if (i == realPosition) View.VISIBLE else View.GONE
                indicatorContainer.getChildAt(i).findViewById<ImageView>(R.id.unSelectIv).visibility =
                    if (i == realPosition) View.GONE else View.VISIBLE
            }
        }
    }

    private fun changeBannerBg(color: Int) {
        mBinding?.run {
            if (bannerBg.background == null) {
                bannerBg.background = GradientDrawable().apply {
                    shape = GradientDrawable.RECTANGLE
                    cornerRadius = 12F.dip2px().toFloat()
                    setColor(color)
                }
            } else if (bannerBg.background is GradientDrawable) {
                (bannerBg.background as GradientDrawable).setColor(color)
            }
        }
    }

    private fun initFollowForums(list: List<ForumEntity>) {
        mBinding?.run {
            followForumContainer.visibility = View.VISIBLE
            followMore.setOnClickListener {
                NewLogUtils.logForumPageEvent("click_following_forum_more")
                NewLogUtils.logForumPageEnterOrReturnClick("view_followforum", "关注论坛页")
                startActivity(ForumListActivity.getIntent(requireContext(), ForumListActivity.TYPE_FOLLOW))
            }
            if (followForumRv.adapter != null) {
                (followForumRv.adapter as? HorizontalForumsAdapter)?.checkResetData(list)
            } else {
                followForumRv.layoutManager = LinearLayoutManager(requireContext(), RecyclerView.HORIZONTAL, false)
                followForumRv.adapter = HorizontalForumsAdapter(requireContext(), "社区-论坛-关注论坛", ArrayList(list))
            }
        }
    }

    private fun initHotForums(list: List<ForumEntity>) {
        mBinding?.run {
            hotForumContainer.visibility = View.VISIBLE
            hotMore.setOnClickListener {
                NewLogUtils.logForumPageEvent("click_hot_forum_more")
                NewLogUtils.logForumPageEnterOrReturnClick("view_hotforum", "热门论坛页")
                startActivity(ForumListActivity.getIntent(requireContext(), ForumListActivity.TYPE_HOT))
            }
            if (hotForumRv.adapter != null) {
                (hotForumRv.adapter as? HorizontalForumsAdapter)?.checkResetData(list)
            } else {
                hotForumRv.layoutManager = LinearLayoutManager(requireContext(), RecyclerView.HORIZONTAL, false)
                hotForumRv.adapter = HorizontalForumsAdapter(requireContext(), "社区-论坛-热门论坛", list, mViewModel)
            }
        }
    }

    private fun initOfficialForums(list: List<ForumEntity>) {
        mBinding?.run {
            officialForumContainer.visibility = View.VISIBLE
            officialMore.setOnClickListener {
                NewLogUtils.logForumPageEvent("click_multiple_forum_more")
                NewLogUtils.logForumPageEnterOrReturnClick("view_multipleforum", "综合论坛页")
                startActivity(ForumListActivity.getIntent(requireContext(), ForumListActivity.TYPE_OFFICIAL))
            }
            if (officialForumRv.adapter !is OfficialForumAdapter) {
                officialForumRv.addItemDecoration(
                    GridSpacingItemColorDecoration(
                        requireContext(),
                        0,
                        16,
                        R.color.transparent
                    )
                )
            }
            officialForumRv.layoutManager = GridLayoutManager(requireContext(), 2)
            val newList = if (list.size > 6) list.subList(0, 6) else list
            officialForumRv.adapter = OfficialForumAdapter(requireContext(), "社区-论坛-热门论坛", newList)
        }
    }

    private fun initWelfare() {
        val welfareLists = arrayListOf<Triple<Int, String, String>>()
        welfareLists.run {
            add(Triple(R.drawable.ic_forum_tool_box, "游戏工具箱", "TOOLS BOX"))
            add(Triple(R.drawable.ic_forum_libao_center, "礼包中心", "GIFT CENTER"))
            add(Triple(R.drawable.ic_forum_game_moment, "游戏动态", "INFORMATION"))
            add(Triple(R.drawable.ic_forum_news, "资讯中心", "GAME NEWS"))
        }

        mBinding?.run {
            otherWelfareContainer.visibility = View.VISIBLE
            otherWelfareRv.layoutManager = GridLayoutManager(requireContext(), 2)
            otherWelfareRv.adapter = WelfaresAdapter(requireContext(), welfareLists)
            otherWelfareRv.addItemDecoration(
                GridSpacingItemColorDecoration(
                    requireContext(),
                    8,
                    8,
                    R.color.transparent
                )
            )
        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onFollowForumChange(forumFollowChange: EBForumFollowChange) {
        mBinding?.run {
            if (forumFollowChange.isFollow) {
                if (followForumContainer.visibility == View.VISIBLE) {
                    mViewModel?.run {
                        followForums.add(0, forumFollowChange.forumEntity)
                        (followForumRv.adapter as? HorizontalForumsAdapter)?.checkResetData(followForums)
                    }
                } else {
                    mViewModel?.followForums = arrayListOf(forumFollowChange.forumEntity)
                    initFollowForums(listOf(forumFollowChange.forumEntity))
                }
            } else {
                mViewModel?.run {
                    val findEntity = followForums.find { it.id == forumFollowChange.forumEntity.id }
                    followForums.remove(findEntity)
                    if (followForums.isEmpty()) {
                        followForumContainer.visibility = View.GONE
                    } else {
                        (followForumRv.adapter as? HorizontalForumsAdapter)?.checkResetData(followForums)
                    }
                }
            }

            val entityList = (hotForumRv.adapter as? HorizontalForumsAdapter)?.list ?: return
            val findEntity = entityList.find { it.id == forumFollowChange.forumEntity.id } ?: return
            val index = entityList.indexOfFirst { it.id == forumFollowChange.forumEntity.id }
            findEntity.me.isFollowForum = forumFollowChange.isFollow
            hotForumRv.adapter?.notifyItemChanged(index)
        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onForumRecordChange(change: EBForumRecordChange) {
        mBinding?.run {
            if (followForumContainer.visibility == View.VISIBLE) {
                mViewModel?.run {
                    val findIndex = followForums.indexOfFirst { it.id == change.forumEntity.id }
                    if (findIndex != -1 && followForums[findIndex].unread) {
                        followForums[findIndex].unread = false
                    }
                }
            }
        }
    }

    override fun onDarkModeChanged() {
        super.onDarkModeChanged()
        mBinding?.hotForumRv?.adapter?.let { it.notifyItemRangeChanged(0, it.itemCount) }
    }
}