package com.gh.common.prioritychain

import android.app.Activity
import android.os.Handler
import android.view.LayoutInflater
import android.view.View
import android.widget.PopupWindow
import androidx.constraintlayout.widget.ConstraintLayout
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.utils.dip2px
import com.gh.gamecenter.common.utils.goneIf
import com.gh.gamecenter.common.view.BugFixedPopupWindow
import com.gh.gamecenter.common.view.NoDefaultMinWidthTabLayout
import com.gh.gamecenter.core.utils.DisplayUtils
import com.gh.gamecenter.core.utils.SPUtils
import com.gh.gamecenter.databinding.PopupMultiTabGuideBinding
import com.gh.gamecenter.entity.BottomTab
import com.gh.gamecenter.wrapper.BaseTabWrapperFragment
import com.gh.gamecenter.wrapper.MainWrapperFragment
import com.google.android.material.tabs.TabLayout
import com.google.android.material.tabs.TabLayout.TabView

class MultiTabGuideHandler(priority: Int): PriorityChainHandler(priority) {
    private var mActivity: Activity? = null
    private var mHandler: Handler? = null
    private var mGuide: BottomTab.Guide? = null
    private var mTabLayout: TabLayout? = null
    private var mTabView: TabView? = null
    private var mIsSingleLineTab = false
    private var mMainWrapperFragment: MainWrapperFragment? = null
    private var mTabWrapperFragment: BaseTabWrapperFragment? = null

    fun doPreProcess(
        shouldShow: Boolean,
        activity: Activity? = null,
        handler: Handler? = null,
        guide: BottomTab.Guide? = null,
        tabLayout: TabLayout? = null,
        tabView: TabLayout.TabView? = null,
        isSingleLineTab: Boolean = false,
        mainWrapperFragment: MainWrapperFragment? = null,
        tabWrapperFragment: BaseTabWrapperFragment? = null
    ) {
        mActivity = activity
        mHandler = handler
        mGuide = guide
        mTabLayout = tabLayout
        mTabView = tabView
        mIsSingleLineTab = isSingleLineTab
        mMainWrapperFragment = mainWrapperFragment
        mTabWrapperFragment = tabWrapperFragment

        if (getStatus() == STATUS_PENDING) {
            if (shouldShow) {
                updateStatus(STATUS_VALID)
                process()
            } else {
                processNext()
            }
        } else {
            if (shouldShow) {
                updateStatus(STATUS_VALID)
            } else {
                updateStatus(STATUS_INVALID)
            }
        }
    }

    override fun onProcess(): Boolean {
        when (getStatus()) {
            STATUS_VALID -> {
                if (mGuide == null || mActivity == null || mTabView == null || mTabLayout == null) {
                    processNext()
                    return false
                }

                return showMultiTabGuide(
                    true,
                    mActivity!!,
                    mHandler,
                    mGuide!!,
                    mTabLayout!!,
                    mTabView!!,
                    mIsSingleLineTab,
                    mMainWrapperFragment,
                    mTabWrapperFragment
                ) {
                    processNext()
                }
            }

            STATUS_INVALID -> {
                processNext()
            }
        }

        return false
    }

    companion object {
        private const val TAB_GUIDE_TRIANGLE_OFFSET_DP = 5F
        private const val TAB_GUIDE_START_TRIANGLE_OFFSET_DP = 12F
        private const val TAB_GUIDE_RIGHT_SIDE_ICON_RIGHT_RESERVED_OFFSET_DP = 51F + TAB_GUIDE_TRIANGLE_OFFSET_DP // 光宝在文案右侧时预留引导到屏幕右侧的距离
        private const val TAB_GUIDE_RIGHT_SIDE_ICON_LEFT_RESERVED_OFFSET_DP = TAB_GUIDE_START_TRIANGLE_OFFSET_DP + TAB_GUIDE_TRIANGLE_OFFSET_DP // 光宝在文案作侧时预留引导到屏幕右侧的距离

        fun showMultiTabGuide(
            isImmediately: Boolean,
            activity: Activity,
            handler: Handler?,
            guide: BottomTab.Guide,
            tabLayout: TabLayout,
            tabView: TabView,
            isSingleLineTab: Boolean = false,
            mainWrapperFragment: MainWrapperFragment? = null,
            tabWrapperFragment: BaseTabWrapperFragment? = null,
            dismissCallback: (() -> Unit)? = null
        ): Boolean {
            val guideSet = HashSet(SPUtils.getStringSet(Constants.SP_MULTI_TAB_NAV_GUIDE_SET))
            val hasShownGuide = guideSet.contains(guide.multiTabId + guide.text)
            val isCurrentBottomTab = mainWrapperFragment == null || guide.bottomTabId == mainWrapperFragment.currentTab?.id
            if (!hasShownGuide && isCurrentBottomTab) {
                val screenWidth = DisplayUtils.getScreenWidth(activity)
                val outLocation = IntArray(2)
                tabView.getLocationOnScreen(outLocation)
                val tabViewCenterPosX = outLocation.first() + tabView.width / 2F
                val iconLeftMaxPosX = if (isSingleLineTab) tabLayout.width else tabLayout.width - TAB_GUIDE_RIGHT_SIDE_ICON_LEFT_RESERVED_OFFSET_DP.dip2px()
                val iconRightMaxPosX = if (isSingleLineTab) tabLayout.width else tabLayout.width - TAB_GUIDE_RIGHT_SIDE_ICON_RIGHT_RESERVED_OFFSET_DP.dip2px()
                val isIconLeftValid = tabViewCenterPosX <= iconLeftMaxPosX
                val isIconRightValid = tabViewCenterPosX <= iconRightMaxPosX
                val isTabViewShowOnScreen = tabViewCenterPosX > 0 && (isIconLeftValid || isIconRightValid)
                val isTabLayoutScrollStateIdle = (tabLayout as? NoDefaultMinWidthTabLayout)?.isScrollStateIdle == true
                if (isTabViewShowOnScreen && isTabLayoutScrollStateIdle) {
                    val trianglePosX = tabViewCenterPosX - TAB_GUIDE_TRIANGLE_OFFSET_DP.dip2px()
                    val guideStartPosX = trianglePosX - TAB_GUIDE_START_TRIANGLE_OFFSET_DP.dip2px()
                    val xoff = tabView.width / 2 - TAB_GUIDE_START_TRIANGLE_OFFSET_DP.dip2px() - TAB_GUIDE_TRIANGLE_OFFSET_DP.dip2px()
                    val restGuideWidth = screenWidth - guideStartPosX

                    showMultiTabPopupWindow(
                        activity,
                        handler,
                        guide,
                        tabView,
                        xoff,
                        screenWidth,
                        restGuideWidth,
                        isIconRightValid,
                        dismissCallback
                    )
                    guideSet.add(guide.multiTabId + guide.text)
                    SPUtils.setStringSet(Constants.SP_MULTI_TAB_NAV_GUIDE_SET, guideSet)

                    return true
                } else if (isImmediately) {
                    (tabLayout as? NoDefaultMinWidthTabLayout)?.let {
                        it.onScrollListener = object :
                            NoDefaultMinWidthTabLayout.OnScrollListener() {
                            override fun onScrollStateChanged(view: NoDefaultMinWidthTabLayout, scrollState: Int) {
                                if (scrollState == SCROLL_STATE_IDLE) {
                                    showMultiTabGuideIfTabViewShow(
                                        activity,
                                        handler,
                                        guide,
                                        it,
                                        tabView,
                                        isSingleLineTab,
                                        mainWrapperFragment
                                    )
                                }
                            }
                        }
                    }
                }
            } else if (isImmediately && !isCurrentBottomTab) {
                tabWrapperFragment?.setResumeAndPauseListener {
                    if (it) {
                        handler?.post {
                            (tabLayout as? NoDefaultMinWidthTabLayout)?.let { tl ->
                                showMultiTabGuideIfBottomTabShow(
                                    activity,
                                    handler,
                                    guide,
                                    tl,
                                    tabView,
                                    isSingleLineTab,
                                    mainWrapperFragment,
                                    tabWrapperFragment
                                )
                            }
                        }
                    }
                }
            }

            dismissCallback?.invoke()
            return false
        }

        fun showMultiTabGuideIfTabViewShow(
            activity: Activity,
            handler: Handler?,
            guide: BottomTab.Guide,
            tabLayout: NoDefaultMinWidthTabLayout,
            tabView: TabView,
            isSingleLineTab: Boolean = false,
            mainWrapperFragment: MainWrapperFragment?
        ) {
            if (showMultiTabGuide(
                    false,
                    activity,
                    handler,
                    guide,
                    tabLayout,
                    tabView,
                    isSingleLineTab,
                    mainWrapperFragment
                )
            ) {
                tabLayout.onScrollListener = null
            }
        }

        fun showMultiTabGuideIfBottomTabShow(
            activity: Activity,
            handler: Handler?,
            guide: BottomTab.Guide,
            tabLayout: NoDefaultMinWidthTabLayout,
            tabView: TabView,
            isSingleLineTab: Boolean = false,
            mainWrapperFragment: MainWrapperFragment?,
            tabWrapperFragment: BaseTabWrapperFragment?
        ) {
            if (showMultiTabGuide(
                    false,
                    activity,
                    handler,
                    guide,
                    tabLayout,
                    tabView,
                    isSingleLineTab,
                    mainWrapperFragment,
                    tabWrapperFragment
                )
            ) {
                tabWrapperFragment?.setResumeAndPauseListener(null)
            }
        }

        fun showMultiTabPopupWindow(
            activity: Activity,
            handler: Handler?,
            guide: BottomTab.Guide,
            tabView: TabView,
            xoff: Int,
            screenWidth: Int,
            restGuideWidth: Float,
            isIconRight: Boolean,
            dismissCallback: (() -> Unit)?
        ): PopupWindow {
            val binding = PopupMultiTabGuideBinding.inflate(LayoutInflater.from(activity))
            binding.guideTv.text = guide.text
            binding.guideTriangleIv.translationX = 12F.dip2px().toFloat()
            binding.guideTv.setPadding(if (isIconRight) 8F.dip2px() else 52F.dip2px(), 0, if (isIconRight) 52F.dip2px() else 8F.dip2px(), 0)
            binding.guideIconIv.goneIf(!isIconRight)
            binding.guideIconFlipIv.goneIf(isIconRight)

            val popupWindow = BugFixedPopupWindow(
                binding.root,
                ConstraintLayout.LayoutParams.WRAP_CONTENT,
                ConstraintLayout.LayoutParams.WRAP_CONTENT
            )
            popupWindow.contentView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED)
            val measureWidth = popupWindow.contentView.measuredWidth
            if (measureWidth >= screenWidth) {
                popupWindow.width = screenWidth
                binding.guideTriangleIv.translationX += screenWidth - restGuideWidth
            } else if (measureWidth > restGuideWidth) {
                binding.guideTriangleIv.translationX += measureWidth - restGuideWidth
            }

            return popupWindow.apply {
                isTouchable = false
                isFocusable = false
                isOutsideTouchable = true
                animationStyle = com.gh.gamecenter.common.R.style.popup_window_ease_in_and_out_anim_style
                setOnDismissListener {
                    dismissCallback?.invoke()
                }
                handler?.post {
                    if (!activity.isFinishing) {
                        showAsDropDown(tabView, xoff, (-25F).dip2px())
                    }
                }
            }
        }
    }
}