package com.gh.gamecenter.category2

import android.content.res.ColorStateList
import android.graphics.Typeface
import android.os.Bundle
import android.view.Gravity
import android.view.MenuItem
import android.view.View
import androidx.core.os.bundleOf
import androidx.core.widget.TextViewCompat
import androidx.fragment.app.viewModels
import com.gh.common.util.LogUtils
import com.gh.gamecenter.R
import com.gh.gamecenter.SearchActivity
import com.gh.gamecenter.catalog.SpecialCatalogFragment
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.exposure.ExposureSource
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.common.view.FixLinearLayoutManager
import com.gh.gamecenter.core.utils.PageSwitchDataHelper
import com.gh.gamecenter.core.utils.SPUtils
import com.gh.gamecenter.databinding.FragmentCategoryBinding
import com.gh.gamecenter.entity.SidebarsEntity
import com.gh.gamecenter.livedata.EventObserver
import com.gh.gamecenter.wrapper.SearchToolbarTabWrapperViewModel

class CategoryV2Fragment : LazyFragment() {

    private var mBinding: FragmentCategoryBinding? = null

    private val viewModel by viewModels<CategoryV2ViewModel>()

    private var mHomeViewModel: SearchToolbarTabWrapperViewModel? = null
    private var mEntity: SidebarsEntity? = null
    private var mLastPageDataMap: HashMap<String, String>? = null

    private var pageId: String = ""
    private var pageName: String = ""
    private var mLastSelectedPosition = -1

    private var searchCategoryPop: SearchCategoryPop? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        pageId = arguments?.getString(EntranceConsts.KEY_PAGE_ID) ?: ""
        pageName = arguments?.getString(EntranceConsts.KEY_PAGE_NAME) ?: ""
        mLastPageDataMap = PageSwitchDataHelper.popLastPageData()
        savedInstanceState?.run {
            mLastSelectedPosition = getInt(EntranceConsts.KEY_LAST_SELECTED_POSITION)
        }

        // 除了这里以外，下面还有一个判断是否为首页 tab 栏的赋值
        var entrance = if (mEntrance.contains("首页")) "首页" else "板块"

        val multiTabNavId = arguments?.getString(EntranceConsts.KEY_MULTI_TAB_NAV_ID, "") ?: ""
        if (arguments?.getBoolean(EntranceConsts.KEY_IS_HOME) == true && multiTabNavId.isNotEmpty()) {
            mHomeViewModel =
                viewModelProviderFromParent(SearchToolbarTabWrapperViewModel.Factory(multiTabNavId, ""), multiTabNavId)
            entrance = "首页Tab栏"
        }
        viewModel.init(entrance)
    }

    override fun onSaveInstanceState(outState: Bundle) {
        outState.putInt(EntranceConsts.KEY_LAST_SELECTED_POSITION, viewModel.selectedSidebarsPosition.value ?: 0)
        super.onSaveInstanceState(outState)
    }

    override fun getRealLayoutId() = R.layout.fragment_category

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

    override fun onFragmentFirstVisible() {

        viewModel.logAppearance()

        super.onFragmentFirstVisible()

        viewModel.loadData(pageId, pageName)
    }


    override fun initRealView() {
        super.initRealView()
        initMenu(R.menu.menu_search)
        setNavigationTitle(pageName)

        mBinding?.run {
            tvMoreCategory.setTextColor(com.gh.gamecenter.common.R.color.text_primary.toColor(requireContext()))
            tvTagNumber.typeface =
                Typeface.createFromAsset(requireContext().assets, Constants.DIN_FONT_PATH)
        }

        viewModel.sidebarsLiveData.observe(viewLifecycleOwner) { sidebars ->
            mBinding?.run {
                reuseLoading.root.visibility = View.GONE
                if (sidebars != null) {
                    reuseNoConnection.root.visibility = View.GONE
                    categoryContainer.visibility = View.VISIBLE
                    reuseNoneData.root.visibility = View.GONE
                    mEntity = sidebars
                    (sidebars.sidebars as ArrayList).run {
                        val allEntity = SidebarsEntity.SidebarEntity(name = "全部", categoryId = "all")
                        add(0, allEntity)
                        if (sidebars.hasSpecial) {
                            val specialEntity = SidebarsEntity.SidebarEntity(name = "精选")
                            add(1, specialEntity)
                        }
                    }
                    initView()
                } else {
                    categoryContainer.visibility = View.GONE
                    reuseNoneData.root.visibility = View.GONE
                    reuseNoConnection.root.visibility = View.VISIBLE
                    reuseNoConnection.root.setOnClickListener {
                        reuseNoConnection.root.visibility = View.GONE
                        reuseLoading.root.visibility = View.VISIBLE
                        viewModel.loadData(pageId, pageName)
                    }
                }
            }
        }

        viewModel.directoriesLiveData.observe(viewLifecycleOwner) {
            searchCategoryPop?.setData(it)
        }

        viewModel.selectedSubCategories.observe(viewLifecycleOwner) { selectedList ->
            searchCategoryPop?.updateCategorySelected(selectedList)
            updateMoreCategory(selectedList.size)
        }

        viewModel.selectedSidebarsPosition.observe(viewLifecycleOwner) {
            mLastSelectedPosition = it
            onSelectedPositionChanged(it)

            val adapter = mBinding?.categoryRv?.adapter
            if (adapter is CategoryV2Adapter) {
                adapter.selectPosition(it)
            }
        }

        viewModel.notifySubCategorySelected.observe(
            viewLifecycleOwner,
            EventObserver {
                searchCategoryPop?.notifyItemSelectedChanged(it)
            })
    }

    private fun createSearchPop(isAutoRequestFocus: Boolean): SearchCategoryPop {
        val height = mBinding!!.root.height
        return SearchCategoryPop.newInstance(requireContext(), height, isAutoRequestFocus, pageId, pageName).apply {
            val data = viewModel.directoriesLiveData.value ?: listOf()
            setData(data)
            val selectedList = viewModel.selectedSubCategories.value
            updateCategorySelected(selectedList)
            setOnSearchCategoryListener(object : SearchCategoryPop.OnSearchCategoryListener {
                override fun isEnableSelected(): Boolean {
                    val size = viewModel.selectedSubCategories.value?.size ?: 0
                    return size < 5
                }

                override fun onItemSelected(selected: CategoryV2ViewModel.SelectedTags) {
                    viewModel.addSubCategorySelected(selected)
                }

                override fun onItemRemoved(parentId: String, subCategoryId: String) {
                    viewModel.removeSubCategorySelected(parentId, subCategoryId, "全部游戏")
                }

                override fun onResetSelected() {
                    viewModel.clearSelectedTag()
                    viewModel.updateGameFiltered()
                }

                override fun onSubmit() {
                    viewModel.logClickDetermine()
                }

            })
        }
    }

    fun removeGuide() {
        mBinding?.run {
            guideContainer.visibility = View.GONE
            SPUtils.setBoolean(Constants.SP_SHOW_CATEGORY_GUIDE, true)
        }
    }

    private fun showGuide() {
        mBinding?.run {
            guideContainer.visibility = View.VISIBLE

            postDelayedRunnable({
                tryCatchInRelease {
                    guideContainer.visibility = View.GONE
                    SPUtils.setBoolean(Constants.SP_SHOW_CATEGORY_GUIDE, true)
                }
            }, 3000)
        }
    }

    override fun onMenuItemClick(menuItem: MenuItem?) {
        menuItem?.run {
            if (itemId == R.id.menu_search) {
                LogUtils.uploadSearchGame("access_to_search", pageName, "", "")
                val intent = SearchActivity.getIntent(
                    requireContext(),
                    false,
                    "",
                    "新分类2.0",
                    "新分类2.0"
                )
                startActivity(intent)
            }
        }
    }

    private fun initView() {
        if (mEntity?.sidebars.isNullOrEmpty()) return
        initSelectedCategory()
        initCategoryRv()

        mBinding?.run {

            vSearchCategory.setOnClickListener {
                SensorsBridge.logClassificationSearch(pageId, pageName)
                removeGuide()
                showSearchPop(true)
            }

            vMoreCategory.setOnClickListener {
                removeGuide()
                showSearchPop(false)
            }
        }

        val isShow = SPUtils.getBoolean(Constants.SP_SHOW_CATEGORY_GUIDE)
        if (!isShow) {
            postDelayedRunnable({
                showSearchPop(false)
                searchCategoryPop?.setOnDismissListener {
                    showGuide()
                }
            }, 200)
        }

    }

    private fun showSearchPop(isAutoRequestFocus: Boolean) {
        mBinding?.run {
            val location = IntArray(2)
            vSearchCategory.getLocationOnScreen(location)

            val popTop = location[1] - 8F.dip2px()
            searchCategoryPop = createSearchPop(isAutoRequestFocus)
            searchCategoryPop?.showAtLocation(vSearchCategory, Gravity.TOP, 0, popTop)
        }
    }

    private fun initSelectedCategory() {
        if (mLastSelectedPosition != -1) {
            viewModel.selectSidebarsPosition(mLastSelectedPosition)
        } else {
            // 默认选中第 0 个 位置
            viewModel.selectSidebarsPosition(0)
        }

    }

    private fun initCategoryRv() {
        mEntity?.run {
            viewModel.run {
                mBinding?.categoryRv?.layoutManager = FixLinearLayoutManager(requireContext())
                mBinding?.categoryRv?.adapter = CategoryV2Adapter(
                    requireContext(),
                    this,
                    sidebars
                )
            }
        }
    }

    private fun onSelectedPositionChanged(position: Int) {
        mEntity?.run {
            viewModel.run {
                clearSelectedTag()
                val targetFragment =
                    if (hasSpecial && position == 1) {
                        val fragment = childFragmentManager.findFragmentByTag(SpecialCatalogFragment::class.java.name)
                            ?: SpecialCatalogFragment()
                        fragment.arguments = bundleOf(
                            EntranceConsts.KEY_IS_CATEGORY_V2 to true,
                            EntranceConsts.KEY_CATALOG_ID to pageId,
                            EntranceConsts.KEY_CATALOG_TITLE to pageName,
                            EntranceConsts.KEY_EXPOSURE_SOURCE_LIST to arguments?.getParcelableArrayList<ExposureSource>(
                                EntranceConsts.KEY_EXPOSURE_SOURCE_LIST
                            ),
                            EntranceConsts.KEY_LAST_PAGE_DATA to mLastPageDataMap
                        )
                        fragment

                    } else {
                        val fragment = (childFragmentManager.findFragmentByTag(CategoryV2ListFragment::class.java.name)
                            ?: CategoryV2ListFragment())
                        fragment.arguments = bundleOf(
                            EntranceConsts.KEY_PAGE_ID to id,
                            EntranceConsts.KEY_PAGE_NAME to pageName,
                            EntranceConsts.KEY_EXPOSURE_SOURCE_LIST to arguments?.getParcelableArrayList<ExposureSource>(
                                EntranceConsts.KEY_EXPOSURE_SOURCE_LIST
                            ),
                            EntranceConsts.KEY_LAST_PAGE_DATA to mLastPageDataMap
                        )
                        fragment
                    }
                childFragmentManager
                    .beginTransaction()
                    .replace(R.id.gamesContainer, targetFragment, targetFragment::class.java.name)
                    .commitAllowingStateLoss()
            }
        }
    }

    private fun updateMoreCategory(size: Int) {
        mBinding?.run {
            if (size > 0) {
                vMoreCategory.setBackgroundResource(R.drawable.bg_more_category_filtered)
                TextViewCompat.setCompoundDrawableTintList(
                    tvMoreCategory,
                    ColorStateList.valueOf(com.gh.gamecenter.common.R.color.text_theme.toColor(requireContext()))
                )
                tvMoreCategory.setTextColor(com.gh.gamecenter.common.R.color.text_theme.toColor(requireContext()))
                tvTagNumber.goneIf(false) {
                    tvTagNumber.text = "$size"
                }
            } else {
                vMoreCategory.setBackgroundResource(R.drawable.bg_more_category_default)
                TextViewCompat.setCompoundDrawableTintList(
                    tvMoreCategory,
                    ColorStateList.valueOf(com.gh.gamecenter.common.R.color.text_primary.toColor(requireContext()))
                )
                tvMoreCategory.setTextColor(com.gh.gamecenter.common.R.color.text_primary.toColor(requireContext()))
                tvTagNumber.goneIf(true)
            }
        }
    }

    override fun onDarkModeChanged() {
        super.onDarkModeChanged()
        getItemMenu(R.id.menu_search)?.setIcon(R.drawable.ic_column_search)
        mBinding?.run {
            categoryRv.adapter?.run {
                categoryRv.recycledViewPool.clear()
                notifyItemRangeChanged(0, itemCount, "")
            }

            val selectedTagsSize = viewModel.selectedSubCategories.value?.size ?: 0
            updateMoreCategory(selectedTagsSize)

            context?.let {
                ivSearchCategory.imageTintList =
                    ColorStateList.valueOf(com.gh.gamecenter.common.R.color.text_instance.toColor(it))
            }
        }
    }

    companion object {

        private const val SPECIAL_CATEGORY_POSITION = 1
    }
}