package com.gh.gamecenter.feedback.view.help

import android.os.Build
import android.os.Bundle
import android.view.*
import android.view.ViewGroup.MarginLayoutParams
import android.widget.FrameLayout
import android.widget.LinearLayout
import android.widget.PopupWindow
import android.widget.TextView
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.core.view.isVisible
import androidx.core.view.updateLayoutParams
import androidx.recyclerview.widget.DefaultItemAnimator
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.RecyclerView.SimpleOnItemTouchListener
import androidx.viewpager2.widget.ViewPager2
import com.gh.gamecenter.common.base.GlobalActivityManager
import com.gh.gamecenter.common.base.fragment.BaseLazyFragment
import com.gh.gamecenter.common.baselist.LoadStatus
import com.gh.gamecenter.common.constant.EntranceConsts
import com.gh.gamecenter.common.databinding.ItemIconTabBinding
import com.gh.gamecenter.common.databinding.PopupAllTabsBinding
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.common.view.FixLinearLayoutManager
import com.gh.gamecenter.common.view.ScrollEventListener
import com.gh.gamecenter.core.utils.DisplayUtils
import com.gh.gamecenter.feedback.R
import com.gh.gamecenter.feedback.databinding.FragmentHelpAndFeedbackBinding
import com.gh.gamecenter.feedback.entity.HelpCategoryEntity
import com.gh.gamecenter.feedback.utils.NewLogUtils
import com.gh.gamecenter.feedback.view.qa.HelpQaDefaultAdapter
import com.gh.gamecenter.feedback.view.qa.QaActivity
import com.gh.gamecenter.feedback.view.qa.QaSearchActivity
import com.gh.gamecenter.feedback.view.suggest.SuggestionActivity
import com.lightgame.utils.Util_System_ClipboardManager
import splitties.views.bottomPadding
import kotlin.math.abs

class HelpAndFeedbackFragment : BaseLazyFragment() {
    private lateinit var mBinding: FragmentHelpAndFeedbackBinding
    private lateinit var mViewModel: HelpAndFeedbackViewModel
    private var mSnapHelper: LeftPagerSnapHelper? = null
    private var mHelpVideoAdapter: HelpVideoAdapter? = null
    private var mCategoryLayoutManager: LinearLayoutManager? = null
    private var mCategoryAdapter: HelpCategoryAdapter? = null
    private var mHelpContentAdapter: HelpQaDefaultAdapter? = null
    private var mPopupWindow: PopupWindow? = null

    private var mIsCollapsed = false

    override fun getLayoutId(): Int = 0

    override fun getInflatedLayout(): View =
        FragmentHelpAndFeedbackBinding.inflate(layoutInflater).apply { mBinding = this }.root

    fun initMenu() {
        requireActivity().menuInflater.inflate(R.menu.menu_feedback, mBinding.actionMenuView.menu)
        mBinding.actionMenuView.setOnMenuItemClickListener {
            startActivity(SuggestionActivity.getSuggestionCategoryIntent(requireContext(), arguments))
            false
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        mViewModel = viewModelProvider()
    }

    override fun onFragmentFirstVisible() {
        super.onFragmentFirstVisible()
        initMenu()
        changeToolbarStyle(mIsCollapsed)
        mBinding.run {
            val statusBarHeight = DisplayUtils.getStatusBarHeight(requireContext().resources)
            swipeRefreshLayout.setColorSchemeResources(com.gh.gamecenter.common.R.color.primary_theme)
            swipeRefreshLayout.setOnRefreshListener {
                mViewModel.initData()
                swipeRefreshLayout.postDelayed({
                    swipeRefreshLayout.isRefreshing = false
                }, 1000)
            }
            swipeRefreshLayout.setProgressViewOffset(
                false,
                0,
                118F.dip2px() + statusBarHeight
            )
            helpVideoLoading.root.gravity = Gravity.CENTER
            helpContentLoading.root.gravity = Gravity.CENTER
            helpContentNoConnection.connectionReloadTv.setOnClickListener {
                mViewModel.getHelpContents()
                helpContentNoConnection.root.visibility = View.GONE
                helpContentLoading.root.visibility = View.VISIBLE
            }
            if (!mIsFromTabWrapper) {
                ViewCompat.setOnApplyWindowInsetsListener(appbar) { _, insets ->
                    (toolbar.layoutParams as MarginLayoutParams).topMargin =
                        insets.getInsets(WindowInsetsCompat.Type.systemBars()).top
                    WindowInsetsCompat.CONSUMED
                }
            }
            if (mIsFromMainWrapper) {
                (toolbar.layoutParams as MarginLayoutParams).topMargin = statusBarHeight
            }
            if (mIsFromTabWrapper) {
                statusBar.visibility = View.GONE
                headIv.post {
                    collapsingToolbar.updateLayoutParams {
                        height = mBinding.headIv.height
                    }
                }
            }

            val collapsingTrigger = 97F.dip2px() + statusBarHeight

            if (mIsFromMainWrapper || mIsFromTabWrapper) {
                toolbar.navigationIcon = null
            } else {
                toolbar.setNavigationIcon(com.gh.gamecenter.common.R.drawable.ic_bar_back_light)
            }
            toolbar.setNavigationOnClickListener { requireActivity().finish() }

            collapsingToolbar.scrimVisibleHeightTrigger = collapsingTrigger
            collapsingToolbar.scrimShownAction = {
                if (mIsCollapsed != it) {
                    mIsCollapsed = it
                    updateStatusBar()
                    changeToolbarStyle(it)
                }
            }

            appbar.addOnOffsetChangedListener { appBarLayout, verticalOffset ->
                val absOffset = abs(verticalOffset)
                val appBarScrollMaxHeight = if (!mIsFromTabWrapper) {
                    appBarLayout.height - statusBarHeight - 96F.dip2px()
                } else {
                    appBarLayout.height - 96F.dip2px()
                }
                val percent = absOffset.toFloat() / appBarScrollMaxHeight
                searchLl.bottomPadding = (8F.dip2px() + (1 - percent) * 24F.dip2px()).toInt()
                mBinding.swipeRefreshLayout.isEnabled = absOffset <= 2
                headIv.translationY = verticalOffset.toFloat() + percent * 24F.dip2px()
            }

            searchContainer.setOnClickListener {
                requireContext().startActivity(QaSearchActivity.getIntent(requireContext()))
            }

            val layoutManager = FixLinearLayoutManager(requireContext(), RecyclerView.HORIZONTAL, false)
            mSnapHelper = LeftPagerSnapHelper()
            mHelpVideoAdapter = HelpVideoAdapter(requireContext(), viewLifecycleOwner, mSnapHelper!!, layoutManager, helpVideoRv)
            (helpVideoRv.itemAnimator as DefaultItemAnimator).supportsChangeAnimations = false
            helpVideoRv.layoutManager = layoutManager
            helpVideoRv.adapter = mHelpVideoAdapter
            helpVideoRv.addOnAttachStateChangeListener(object : View.OnAttachStateChangeListener {
                override fun onViewAttachedToWindow(v: View) {
                    // do nothing
                }

                override fun onViewDetachedFromWindow(v: View) {
                    mHelpVideoAdapter?.stopScroll()
                }
            })
            helpVideoRv.isNestedScrollingEnabled = false
            helpVideoRv.onFlingListener = null
            mSnapHelper?.attachToRecyclerView(helpVideoRv)
            helpVideoRv.addOnScrollListener(ScrollEventListener(helpVideoRv).apply {
                registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
                    override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {
                        super.onPageScrolled(position, positionOffset, positionOffsetPixels)
                        helpVideoIndicator.onPageScrolled(
                            mHelpVideoAdapter!!.getActualPosition(position),
                            positionOffset
                        )
                    }
                })
            })
            helpVideoRv.addOnItemTouchListener(object : SimpleOnItemTouchListener() {
                override fun onInterceptTouchEvent(rv: RecyclerView, e: MotionEvent): Boolean {
                    val isStop = e.action == MotionEvent.ACTION_DOWN || e.action == MotionEvent.ACTION_MOVE
                    if (isStop) mHelpVideoAdapter?.stopScroll() else mHelpVideoAdapter?.startScroll()
                    return false
                }
            })

            mCategoryLayoutManager = FixLinearLayoutManager(requireContext(), RecyclerView.HORIZONTAL, false)
            mCategoryAdapter = HelpCategoryAdapter(requireContext(), mViewModel)
            categoryRv.layoutManager = mCategoryLayoutManager
            categoryRv.adapter = mCategoryAdapter
            (categoryRv.itemAnimator as DefaultItemAnimator).supportsChangeAnimations = false
            categoryRv.isNestedScrollingEnabled = false
            categoryMoreBackground.setOnClickListener {
                showCategoryPopupWindow()
            }

            mHelpContentAdapter = HelpQaDefaultAdapter(requireContext(), false, mViewModel)
            helpContentRv.layoutManager = FixLinearLayoutManager(requireContext())
            helpContentRv.adapter = mHelpContentAdapter
            mBinding.helpContentMoreTv.setOnClickListener {
                val id =
                    if (mViewModel.selectedCategory.name == HelpAndFeedbackViewModel.MY_RELATED_QA_NAME) "" else mViewModel.selectedCategory.id
                requireContext().startActivity(
                    QaActivity.getNewIntent(
                        requireContext(),
                        mViewModel.selectedCategory.name,
                        id,
                        mViewModel.selectedCategory.name == HelpAndFeedbackViewModel.MY_RELATED_QA_NAME
                    )
                )
                NewLogUtils.logClickQaMoreBtn(mViewModel.selectedCategory.id, mViewModel.selectedCategory.name)
            }
        }

        updateFeedbackContentIfAvailable()
        observeData()

        val gameId = arguments?.getString(EntranceConsts.KEY_GAME_ID, "") ?: ""
        val gameName = arguments?.getString(EntranceConsts.KEY_GAME_NAME, "") ?: ""
        SensorsBridge.trackEvent(
            "QAEnter",
            "source_entrance",
            mEntrance,
            "game_id",
            gameId,
            "game_name",
            gameName,
            "last_page_name",
            GlobalActivityManager.getLastPageEntity().pageName
        )
    }

    override fun onFragmentPause() {
        super.onPause()
        mHelpVideoAdapter?.stopScroll()
    }

    override fun onFragmentResume() {
        super.onResume()
        updateStatusBar()
        mHelpVideoAdapter?.startScroll()
    }

    /**
     * 根据历史功能，如果剪贴板中有符合条件的内容（插件跳转时的反馈内容），就更新 argument 里的 content
     */
    private fun updateFeedbackContentIfAvailable() {
        // 默认不带参跳转内容包含 null
        if (arguments?.getString(EntranceConsts.KEY_CONTENT)?.contains("null") == false) {
            return
        }

        val updateArgumentClosure = {
            val clipboardText = Util_System_ClipboardManager.getText(requireContext())
            if (clipboardText != null
                && clipboardText.contains("游戏名")
                && clipboardText.contains("游戏ID")
                && clipboardText.contains("游戏包MD5")
            ) {
                arguments?.putString(EntranceConsts.KEY_CONTENT, clipboardText)
            }
        }

        // Android 10.0 及以后版本需要在获取到了 windowsFocus 后才能访问粘贴版内容
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
            val listener = object : ViewTreeObserver.OnWindowFocusChangeListener {
                override fun onWindowFocusChanged(hasFocus: Boolean) {
                    if (hasFocus) {
                        updateArgumentClosure.invoke()
                        mBinding.root.viewTreeObserver.removeOnWindowFocusChangeListener(this)
                    }
                }
            }
            mCachedView?.viewTreeObserver?.addOnWindowFocusChangeListener(listener)
        } else {
            updateArgumentClosure.invoke()
        }
    }

    private fun showCategoryPopupWindow() {
        val binding = PopupAllTabsBinding.inflate(LayoutInflater.from(requireContext()), null, false)
        val popupWindow = PopupWindow(
            binding.root,
            LinearLayout.LayoutParams.MATCH_PARENT,
            LinearLayout.LayoutParams.WRAP_CONTENT
        ).apply { mPopupWindow = this }

        binding.flexbox.setDividerDrawable(com.gh.gamecenter.common.R.drawable.shape_flexbox_divider_w8_h8.toDrawable(requireContext()))
        binding.flexbox.bottomPadding = 16F.dip2px()
        mViewModel.categoryLiveData.value?.forEachIndexed { index, entity ->
            val item = getCategoryItemView(entity)
            binding.flexbox.addView(item)
            item.tag = entity.name
            toggleHighlightedView(item, mViewModel.selectedCategory.id == entity.id)
            item.setOnClickListener {
                toggleHighlightedView(item, true)
                mViewModel.setCategory(entity)
                mCategoryAdapter?.run {
                    notifyItemRangeChanged(0, itemCount)
                }
                mBinding.categoryRv.smoothScrollToPosition(index)
                popupWindow.dismiss()
            }
        }
        binding.titleContainer.layoutParams = binding.titleContainer.layoutParams.apply { height = 40F.dip2px() }
        binding.titleTv.text = "全部标签"
        binding.background.setOnClickListener {
            popupWindow.dismiss()
            mPopupWindow = null
        }
        binding.closeIv.run {
            layoutParams = (layoutParams as FrameLayout.LayoutParams).apply {
                width = 48F.dip2px()
                height = 40F.dip2px()
            }
            setPadding(16F.dip2px(), 12F.dip2px(), 16F.dip2px(), 12F.dip2px())
            setImageResource(R.drawable.icon_close)
            setOnClickListener {
                popupWindow.dismiss()
                mPopupWindow = null
            }
        }
        popupWindow.width = mBinding.helpCenterTv.width
        popupWindow.isTouchable = true
        popupWindow.isFocusable = true
        popupWindow.animationStyle = 0
        popupWindow.showAsDropDown(mBinding.helpCenterTv, 0, 0)
    }

    private fun toggleHighlightedView(targetView: View, highlightIt: Boolean) {
        val titleTv = targetView.findViewById<TextView>(R.id.titleTv)
        if (highlightIt) {
            targetView.background = com.gh.gamecenter.common.R.drawable.button_round_theme_alpha_10.toDrawable(requireContext())
            titleTv?.setTextColor(com.gh.gamecenter.common.R.color.text_theme.toColor(requireContext()))
        } else {
            targetView.background = com.gh.gamecenter.feature.R.drawable.button_round_gray_light.toDrawable(requireContext())
            titleTv?.setTextColor(com.gh.gamecenter.common.R.color.text_secondary.toColor(requireContext()))
        }
    }

    private fun getCategoryItemView(entity: HelpCategoryEntity): View {
        return ItemIconTabBinding.bind(
            LayoutInflater.from(requireContext()).inflate(com.gh.gamecenter.common.R.layout.item_icon_tab, null)
        ).apply {
            iconIv.goneIf(entity.id.isNotEmpty()) {
                iconIv.setImageResource(if (entity.id == mViewModel.selectedCategory.id) R.drawable.icon_my_selected else R.drawable.icon_my_unselected)
            }
            iconIv.layoutParams = (iconIv.layoutParams as MarginLayoutParams).apply {
                rightMargin = 2F.dip2px()
            }
            titleTv.text = entity.name
        }.root.apply {
            layoutParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, 28F.dip2px())
        }
    }

    private fun observeData() {
        mViewModel.helpVideosLiveData.observe(viewLifecycleOwner) {
            mBinding.helpVideoLoading.root.visibility = View.GONE
            mBinding.helpVideoCv.goneIf(it.isNullOrEmpty())
            mBinding.helpCenterCv.layoutParams =
                (mBinding.helpCenterCv.layoutParams as LinearLayout.LayoutParams).apply {
                    topMargin = if (it.isNullOrEmpty()) 0 else 12F.dip2px()
                }
            if (it != null) {
                mHelpVideoAdapter?.submitList(it)
                mBinding.helpVideoRv.scrollToPosition(mHelpVideoAdapter!!.getActualFirstPositionInCenter())
                mBinding.helpVideoIndicator.run {
                    pageSize = it.size
                    notifyDataChanged()
                }
            }
        }

        mViewModel.categoryLiveData.observeNonNull(this) {
            mCategoryAdapter?.submitList(it)
            mBinding.categoryRv.scrollToPosition(0)
            mBinding.categoryRv.post {
                mCategoryLayoutManager?.run {
                    mBinding.categoryMoreIv.isVisible =
                        findLastCompletelyVisibleItemPosition() != itemCount - 1
                    mBinding.categoryMoreBackground.isVisible =
                        findLastCompletelyVisibleItemPosition() != itemCount - 1
                }
                if (mViewModel.selectedCategory.id.isNotEmpty()) {
                    val checkedPosition = it.indexOfFirst { helpCategoryEntity ->
                        helpCategoryEntity.id == mViewModel.selectedCategory.id
                    }
                    mBinding.categoryRv.scrollToPosition(checkedPosition)
                }
            }
        }

        mViewModel.helpContentsLiveData.observe(viewLifecycleOwner) {
            mBinding.helpContentLoading.root.visibility = View.GONE
            if (it == null) {
                mBinding.helpContentNoConnection.root.visibility = View.VISIBLE
                mBinding.helpContentNoneData.root.visibility = View.GONE
            } else {
                mBinding.helpContentNoConnection.root.visibility = View.GONE
                mBinding.helpContentNoneData.root.goneIf(it.isNotEmpty())
                mHelpContentAdapter?.setListData(it)
                mHelpContentAdapter?.loadChange(LoadStatus.INIT_OVER)
                mBinding.helpContentDivider.goneIf(it.size < HelpAndFeedbackViewModel.HELP_CONTENT_NORMAL_SIZE)
                mBinding.helpContentMoreTv.goneIf(it.size < HelpAndFeedbackViewModel.HELP_CONTENT_NORMAL_SIZE)
            }
        }
    }

    private fun updateStatusBar() {
        if (!mIsFromTabWrapper && isSupportVisible) {
            DisplayUtils.transparentStatusBar(requireActivity())
            DisplayUtils.setLightStatusBar(requireActivity(), !mIsDarkModeOn && mIsCollapsed)
        }
    }

    private fun changeToolbarStyle(isCollapsed: Boolean) {
        if (isCollapsed) {
            if (!mIsFromMainWrapper && !mIsFromTabWrapper) {
                mBinding.toolbar.setNavigationIcon(com.gh.gamecenter.common.R.drawable.ic_bar_back)
            }
            mBinding.titleTv.alpha = 1F
            mBinding.titleTv.visibility = View.VISIBLE
            mBinding.titleTv.setTextColor(com.gh.gamecenter.common.R.color.text_black.toColor(requireContext()))
            mBinding.actionMenuView.menu.findItem(R.id.menu_feedback)?.setIcon(R.drawable.ic_feedback)
            mBinding.collapsingToolbar.setContentScrimColor(com.gh.gamecenter.common.R.color.ui_surface.toColor(requireContext()))
            mBinding.searchContainer.background = com.gh.gamecenter.common.R.drawable.bg_shape_f5_radius_999.toDrawable(requireContext())
        } else {
            if (!mIsFromMainWrapper && !mIsFromTabWrapper) {
                mBinding.toolbar.setNavigationIcon(com.gh.gamecenter.common.R.drawable.ic_bar_back_light)
            }
            mBinding.titleTv.visibility = View.GONE
            mBinding.actionMenuView.menu.findItem(R.id.menu_feedback)?.setIcon(R.drawable.ic_feedback_light)
            mBinding.collapsingToolbar.setContentScrimColor(com.gh.gamecenter.common.R.color.ui_background.toColor(requireContext()))
            mBinding.searchContainer.background =
                com.gh.gamecenter.common.R.drawable.background_shape_white_radius_999.toDrawable(requireContext())
        }
    }

    override fun onDarkModeChanged() {
        super.onDarkModeChanged()
        updateStatusBar()
        changeToolbarStyle(mIsCollapsed)
        mBinding.run {
            helpVideoCv.setCardBackgroundColor(com.gh.gamecenter.common.R.color.ui_surface.toColor(requireContext()))
            helpCenterCv.setCardBackgroundColor(com.gh.gamecenter.common.R.color.ui_surface.toColor(requireContext()))
            mHelpVideoAdapter?.let {
                it.notifyItemRangeChanged(0, it.itemCount)
            }
            mCategoryAdapter?.let {
                it.notifyItemRangeChanged(0, it.itemCount)
            }
        }
    }
}