package com.gh.gamecenter.servers.gametest2

import android.animation.AnimatorSet
import android.animation.ValueAnimator
import android.annotation.SuppressLint
import android.graphics.Typeface
import android.os.Bundle
import android.view.Gravity
import android.view.View
import android.widget.FrameLayout
import android.widget.LinearLayout
import android.widget.TextView
import androidx.core.view.isVisible
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.constant.EntranceConsts
import com.gh.gamecenter.common.pagelevel.IPageLevelProvider
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.core.utils.SPUtils
import com.gh.gamecenter.core.utils.doOnEnd
import com.gh.gamecenter.core.utils.doOnStart
import com.gh.gamecenter.databinding.FragmentGameServerTestV2Binding
import com.gh.gamecenter.databinding.LayoutGameServerTestV2SettingBinding
import com.gh.gamecenter.feature.entity.PageLocation
import com.gh.gamecenter.mygame.MyGameActivity

class GameServerTestV2Fragment : LazyFragment() {

    private var mBinding: FragmentGameServerTestV2Binding? = null
    private var mViewModel: GameServerTestV2ViewModel? = null
    private var mSettingBinding: LayoutGameServerTestV2SettingBinding? = null
    private var mCurrentFragment: GameServerTestV2ListFragment? = null
    private var mLinkText = ""
    private var mPageLocation: PageLocation? = null
    private var mIsSettingAnimating = false

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

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        mLinkText = requireArguments().getString(EntranceConsts.KEY_NAME, "")
        val topTabIndex = requireArguments().getInt(EntranceConsts.KEY_TAB_INDEX, -1)
        val bottomTabIndex = requireArguments().getInt(EntranceConsts.KEY_BOTTOM_TAB_INDEX, -1)
        val precisePageLevelString = (activity as? IPageLevelProvider)
            ?.getPageLevel()
            ?.getTempNewPageLevel(topTabPosition = topTabIndex, bottomTabPosition = bottomTabIndex)
            ?.toFormattedString(ignoreBottomTabPositionMap = true)
            ?: ""
        mPageLocation = PageLocation(
            requireArguments().getString(EntranceConsts.KEY_BOTTOM_TAB_NAME, ""),
            bottomTabIndex,
            precisePageLevelString,
            requireArguments().getString(EntranceConsts.KEY_MULTI_TAB_NAV_NAME, ""),
            requireArguments().getString(EntranceConsts.KEY_MULTI_TAB_NAV_ID, ""),
            topTabIndex,
            requireArguments().getString(EntranceConsts.KEY_TAB_NAME, "")
        )
    }

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

    override fun onFragmentFirstVisible() {
        mViewModel = viewModelProviderFromParent()
        super.onFragmentFirstVisible()
        mViewModel?.run {
            mBinding?.filterView?.setItemList(timeFilterList, DEFAULT_TIME_FILTER_INDEX)
            selectedTimeFilterLiveData.observe(this@GameServerTestV2Fragment) {
                mBinding?.filterView?.setCurrentItem(timeFilterList.indexOf(it))
            }
        }
        changeFragment()

        if (SPUtils.getBoolean(Constants.SP_SHOW_GAME_SERVER_TEST_V2_SETTING_GUIDE, true)) {
            mBaseHandler.post {
                showGuide()
            }
            SPUtils.setBoolean(Constants.SP_SHOW_GAME_SERVER_TEST_V2_SETTING_GUIDE, false)
        }
    }

    override fun initRealView() {
        super.initRealView()
        setNavigationTitle("新游开测")
        mBinding?.run {
            filterContainer.setBackgroundColor(com.gh.gamecenter.common.R.color.ui_background.toColor(requireContext()))
            filterView.onCheckedAction = { index ->
                mViewModel?.let {
                    it.setSelectedTimeFilter(it.timeFilterList[index])
                    mCurrentFragment?.changeTimeFilter()
                    SensorsBridge.trackColumnTestClick(
                        location = "详情页",
                        recommendType = mLinkText,
                        text = "时间定位",
                        bottomTab = mPageLocation?.bottomTab,
                        multiTabName = mPageLocation?.severalTabPageName,
                        multiTabId = mPageLocation?.severalTabPageId,
                        position = mPageLocation?.tabPosition,
                        tabContent = mPageLocation?.tabContent,
                        buttonType = it.timeFilterList[index]
                    )
                }
            }
            myReserveTv.setOnClickListener {
                SensorsBridge.trackColumnTestClick(
                    location = "详情页",
                    recommendType = mLinkText,
                    text = "我的预约",
                    bottomTab = mPageLocation?.bottomTab,
                    multiTabName = mPageLocation?.severalTabPageName,
                    multiTabId = mPageLocation?.severalTabPageId,
                    position = mPageLocation?.tabPosition,
                    tabContent = mPageLocation?.tabContent
                )
                ifLogin("新游开测") {
                    requireContext().startActivity(
                        MyGameActivity.getIntentWithConfig(
                            requireContext(),
                            MyGameActivity.RESERVATION_INDEX
                        )
                    )
                }
            }
            optionIv.setOnClickListener {
                showSettingView()
                SensorsBridge.trackColumnTestClick(
                    location = "详情页",
                    recommendType = mLinkText,
                    text = "设置",
                    bottomTab = mPageLocation?.bottomTab,
                    multiTabName = mPageLocation?.severalTabPageName,
                    multiTabId = mPageLocation?.severalTabPageId,
                    position = mPageLocation?.tabPosition,
                    tabContent = mPageLocation?.tabContent
                )
            }
        }
    }

    @SuppressLint("ClickableViewAccessibility")
    private fun showSettingView(onShowAction: (() -> Unit)? = null) {
        if (mIsSettingAnimating) return

        mBinding?.dismissView?.visibility = View.VISIBLE
        mBinding?.dismissView?.setOnClickListener {
            mBinding?.background?.performClick()
        }
        mBinding?.background?.setOnClickListener {
            mViewModel?.run {
                tempCategoryFilterSet = HashSet(selectedCategoryFilterSet)
            }
            dismissSettingView()
        }

        val binding =
            LayoutGameServerTestV2SettingBinding.inflate(layoutInflater, null, false).apply { mSettingBinding = this }
        binding.bigImageModeItem.run {
            root.background = null
            titleTv.textSize = 16F
            titleTv.setTypeface(Typeface.DEFAULT, Typeface.BOLD)
            titleTv.text = "大图模式"
            tipsTv.text = "开启后，列表内的热门游戏将展开大图进行展示"
            tipsTv.visibility = View.VISIBLE
            switchLottie.visibility = View.VISIBLE
            switchLottie.setSwitchAnimation(mViewModel?.bigImageMode ?: true)
            root.setDebouncedClickListener {
                if (switchLottie.isAnimating) return@setDebouncedClickListener
                switchLottie.setSwitchAnimation(mViewModel?.bigImageMode ?: true)
                mViewModel?.bigImageMode = !(mViewModel?.bigImageMode ?: true)
                SPUtils.setBoolean(Constants.SP_GAME_SERVER_TEST_V2_BIG_IMAGE_MODE, mViewModel?.bigImageMode ?: true)
                switchLottie.playAnimation()
                mCurrentFragment?.changeBigImageMode()
                SensorsBridge.trackEvent(
                    "ColumnTestSetUp",
                    "picture_mode",
                    if (mViewModel?.bigImageMode != false) "开启开关" else "关闭开关",
                    "original_game_type",
                    mViewModel?.getCategoryFilterString() ?: "",
                    "new_game_type",
                    mViewModel?.getCategoryFilterString() ?: ""
                )
            }
        }
        binding.confirmTv.setOnClickListener {
            mViewModel?.run {
                val originalCategoryFilter = getCategoryFilterString()
                val isCategoryFilterChanged = selectedCategoryFilterSet != tempCategoryFilterSet
                selectedCategoryFilterSet = HashSet(tempCategoryFilterSet)
                SPUtils.setStringSet(Constants.SP_GAME_SERVER_TEST_V2_CATEGORY_SET, selectedCategoryFilterSet)
                setSelectedTimeFilter(GameServerTestV2ViewModel.TODAY_GAME)
                if (isCategoryFilterChanged) {
                    mCurrentFragment?.changeCategoryFilter()
                }

                val pictureMode = if (bigImageMode) "保持开启" else "保持关闭"
                val newCategoryFilter = getCategoryFilterString()
                SensorsBridge.trackEvent(
                    "ColumnTestSetUp",
                    "picture_mode",
                    pictureMode,
                    "original_game_type",
                    originalCategoryFilter,
                    "new_game_type",
                    newCategoryFilter
                )

                dismissSettingView()
            }
        }

        val itemList = arrayListOf<TextView>()
        val allItem = getItemTextView("全部")
        allItem.tag = "全部"
        binding.flexbox.addView(allItem)
        toggleHighlightedTextView(allItem, mViewModel?.tempCategoryFilterSet.isNullOrEmpty())
        allItem.setOnClickListener {
            mViewModel?.tempCategoryFilterSet?.clear()
            toggleHighlightedTextView(allItem, true)
            itemList.forEach { textView ->
                toggleHighlightedTextView(textView, false)
            }
        }

        for (filter in mViewModel?.categoryFilterList!!) {
            val item = getItemTextView(filter)
            binding.flexbox.addView(item)
            item.tag = filter
            toggleHighlightedTextView(item, mViewModel?.tempCategoryFilterSet?.contains(filter) == true)
            item.setOnClickListener {
                toggleHighlightedTextView(item, mViewModel?.tempCategoryFilterSet?.contains(filter) == false)
                if (mViewModel?.tempCategoryFilterSet?.contains(filter) == true) {
                    mViewModel?.tempCategoryFilterSet?.remove(filter)
                } else {
                    mViewModel?.tempCategoryFilterSet?.add(filter)
                }
                toggleHighlightedTextView(allItem, mViewModel?.tempCategoryFilterSet.isNullOrEmpty())
            }
            itemList.add(item)
        }

        mBinding?.settingContainer?.addView(
            binding.root,
            FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.WRAP_CONTENT)
        )
        mBinding?.settingContainer?.post {
            val height = mBinding?.settingContainer?.height ?: 0
            mBinding?.background?.visibility = View.VISIBLE
            AnimatorSet().apply {
                val translateAnimator = ValueAnimator.ofFloat(0F, height.toFloat()).apply {
                    addUpdateListener { va -> mBinding?.settingContainer?.translationY = (va.animatedValue as Float) }
                }
                val alphaAnimator = ValueAnimator.ofFloat(0F, 0.2F).apply {
                    addUpdateListener { va -> mBinding?.background?.alpha = (va.animatedValue as Float) }
                }
                playTogether(translateAnimator, alphaAnimator)
                duration = ANIMATOR_SET_DURATION
                doOnStart {
                    mIsSettingAnimating = true
                }
                doOnEnd {
                    mIsSettingAnimating = false
                    mBinding?.filterBackground?.visibility = View.GONE
                    mBinding?.filterContainer?.setBackgroundColor(com.gh.gamecenter.common.R.color.ui_surface.toColor(requireContext()))

                    onShowAction?.invoke()
                }
            }.start()
        }
    }

    private fun dismissSettingView() {
        if (mSettingBinding == null || mIsSettingAnimating) return

        val height = mBinding?.settingContainer?.height ?: 0
        AnimatorSet().apply {
            val translateAnimator = ValueAnimator.ofFloat(height.toFloat(), 0F).apply {
                addUpdateListener { va -> mBinding?.settingContainer?.translationY = (va.animatedValue as Float) }
            }
            val alphaAnimator = ValueAnimator.ofFloat(0.2F, 0F).apply {
                addUpdateListener { va -> mBinding?.background?.alpha = (va.animatedValue as Float) }
            }
            playTogether(translateAnimator, alphaAnimator)
            duration = ANIMATOR_SET_DURATION
            doOnStart {
                mIsSettingAnimating = true
            }
            doOnEnd {
                mIsSettingAnimating = false
                mBinding?.background?.visibility = View.GONE
                mBinding?.dismissView?.visibility = View.GONE
                mBinding?.filterBackground?.visibility = View.VISIBLE
                mBinding?.filterContainer?.setBackgroundColor(com.gh.gamecenter.common.R.color.ui_background.toColor(requireContext()))
                mBinding?.settingContainer?.removeAllViews()
                mSettingBinding = null
            }
        }.start()
    }

    private fun showGuide() {
        mBinding?.settingGuideContainer?.setOnClickListener {
            dismissGuide()
        }
        mBinding?.settingGuideContainer?.isVisible = true
    }

    private fun dismissGuide() {
        mBinding?.settingGuideIv?.animate()?.alpha(0F)?.setDuration(200L)?.doOnEnd {
            mBinding?.settingGuideContainer?.isVisible = false
        }?.start()
    }

    private fun getItemTextView(type: String): TextView {
        return TextView(requireContext()).apply {
            text = type
            includeFontPadding = false
            textSize = 12F
            gravity = Gravity.CENTER
            background = R.drawable.bg_shape_f8_radius_8.toDrawable(context)
            setTypeface(Typeface.DEFAULT, Typeface.BOLD)
            setTextColor(com.gh.gamecenter.common.R.color.text_secondary.toColor(context))
            setPadding(16F.dip2px(), 0, 16F.dip2px(), 0)
            val params = LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, 32F.dip2px())
            layoutParams = params
        }
    }

    private fun toggleHighlightedTextView(targetTextView: TextView, highlightIt: Boolean) {
        if (highlightIt) {
            targetTextView.background = R.drawable.bg_shape_2496ff_alpha_10_radius_8.toDrawable(targetTextView.context)
            targetTextView.setTextColor(com.gh.gamecenter.common.R.color.text_theme.toColor(targetTextView.context))
        } else {
            targetTextView.background = R.drawable.bg_shape_f8_radius_8.toDrawable(targetTextView.context)
            targetTextView.setTextColor(com.gh.gamecenter.common.R.color.text_secondary.toColor(targetTextView.context))
        }
    }

    private fun changeFragment() {
        mViewModel?.selectedTimeFilterLiveData?.value = mViewModel?.timeFilterList?.get(DEFAULT_TIME_FILTER_INDEX) ?: ""
        mCurrentFragment =
            childFragmentManager.findFragmentByTag(GameServerTestV2ViewModel::class.java.name) as? GameServerTestV2ListFragment
                ?: GameServerTestV2ListFragment()

        val bundle = requireArguments().clone() as Bundle
        mCurrentFragment?.arguments = bundle
        childFragmentManager
            .beginTransaction()
            .replace(R.id.contentContainer, mCurrentFragment!!, GameServerTestV2ViewModel::class.java.name)
            .commitAllowingStateLoss()
    }

    fun showPullDownTip(show: Boolean) {
        mBinding?.pullDownTipIv?.isVisible = show
    }

    override fun onBackPressed(): Boolean {
        if (mBinding?.settingGuideContainer?.isVisible == true) {
            dismissGuide()
            return true
        }
        if (mSettingBinding != null) {
            dismissSettingView()
            return true
        }
        return super.onBackPressed()
    }

    override fun onDarkModeChanged() {
        super.onDarkModeChanged()
        mBinding?.filterContainer?.setBackgroundColor(
            if (mSettingBinding == null)
                com.gh.gamecenter.common.R.color.ui_background.toColor(requireContext())
            else
                com.gh.gamecenter.common.R.color.ui_surface.toColor(requireContext())
        )
        mBinding?.filterView?.updateView(mIsDarkModeOn)
        mSettingBinding?.run {
            contentContainer.background =
                com.gh.gamecenter.common.R.drawable.background_shape_white_radius_12_bottom_only.toDrawable(requireContext())
            divider.setBackgroundColor(com.gh.gamecenter.common.R.color.ui_divider.toColor(requireContext()))
            bigImageModeItem.run {
                titleTv.setTextColor(com.gh.gamecenter.common.R.color.text_primary.toColor(requireContext()))
                tipsTv.setTextColor(com.gh.gamecenter.common.R.color.text_tertiary.toColor(requireContext()))
                switchLottie.setSwitchAnimation(mViewModel?.bigImageMode ?: true)
            }
            preferTv.setTextColor(com.gh.gamecenter.common.R.color.text_primary.toColor(requireContext()))
            preferDesTv.setTextColor(com.gh.gamecenter.common.R.color.text_tertiary.toColor(requireContext()))
            confirmTv.background = com.gh.gamecenter.common.R.drawable.button_blue_oval.toDrawable(requireContext())
            for (i in 0 until flexbox.childCount) {
                val childView = flexbox.getChildAt(i) as? TextView ?: return
                if (i == 0) {
                    toggleHighlightedTextView(childView, mViewModel?.tempCategoryFilterSet.isNullOrEmpty())
                } else {
                    toggleHighlightedTextView(
                        childView,
                        mViewModel?.tempCategoryFilterSet?.contains(childView.tag) == true
                    )
                }
            }
        }
    }

    companion object {
        const val DEFAULT_TIME_FILTER_INDEX = 1
        private const val ANIMATOR_SET_DURATION = 200L
    }
}