package com.gh.gamecenter.category2

import android.os.Bundle
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
import androidx.core.os.bundleOf
import androidx.core.view.GravityCompat
import androidx.drawerlayout.widget.DrawerLayout
import androidx.lifecycle.Observer
import androidx.recyclerview.widget.LinearLayoutManager
import com.gh.common.exposure.ExposureSource
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.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.CategoryEntity
import com.gh.gamecenter.entity.SidebarsEntity
import com.gh.gamecenter.fragment.HomeSearchToolWrapperViewModel

class CategoryV2Fragment : LazyFragment() {

    private var mBinding: FragmentCategoryBinding? = null
    private var mViewModel: CategoryV2ViewModel? = null
    private var mHomeViewModel: HomeSearchToolWrapperViewModel? = null
    private var mEntity: SidebarsEntity? = null
    private var mSpecialCatalogFragment: SpecialCatalogFragment? = null
    private var mCategoryV2ListFragment: CategoryV2ListFragment? = null
    private var mLastPageDataMap: HashMap<String, String>? = null

    private var mCategoryId: String = ""
    private var mCategoryTitle: String = ""
    private var mLastSelectedPosition = -1

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        savedInstanceState?.run {
            mLastSelectedPosition = getInt(EntranceConsts.KEY_LAST_SELECTED_POSITION)
        }
    }

    override fun onSaveInstanceState(outState: Bundle) {
        mViewModel?.run {
            outState.putInt(EntranceConsts.KEY_LAST_SELECTED_POSITION, selectedCategoryPosition)
        }
        super.onSaveInstanceState(outState)
    }

    override fun getRealLayoutId() = R.layout.fragment_category

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

    override fun onFragmentFirstVisible() {
        mCategoryId = arguments?.getString(EntranceConsts.KEY_CATEGORY_ID) ?: ""
        mCategoryTitle = arguments?.getString(EntranceConsts.KEY_CATEGORY_TITLE) ?: ""
        mLastPageDataMap = PageSwitchDataHelper.popLastPageData()
        mViewModel = viewModelProviderFromParent(CategoryV2ViewModel.Factory(mCategoryId, mCategoryTitle), mCategoryId)

        // 除了这里以外，下面还有一个判断是否为首页 tab 栏的赋值
        mViewModel?.entrance = if (mEntrance.contains("首页")) "首页" else "板块"
        if (arguments?.getBoolean(EntranceConsts.KEY_IS_HOME) == true) {
            mHomeViewModel = viewModelProviderFromParent()
            mViewModel?.entrance = "首页Tab栏"
        }
        mViewModel?.logAppearance()

        super.onFragmentFirstVisible()
    }

    override fun initRealView() {
        super.initRealView()

        setNavigationTitle(mCategoryTitle)

        mBinding?.run {
            val width = resources.displayMetrics.widthPixels * 260 / 360
            drawerLayout.setScrimColor(R.color.black_alpha_30.toColor())
            // 关闭手势滑动
            drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED)
            drawerLayout.addDrawerListener(object : DrawerLayout.DrawerListener {
                override fun onDrawerStateChanged(newState: Int) {
                }

                override fun onDrawerSlide(drawerView: View, slideOffset: Float) {
                }

                override fun onDrawerClosed(drawerView: View) {
                    showGuide()
                }

                override fun onDrawerOpened(drawerView: View) {
                }

            })
            directoryContainer.layoutParams.width = width
            directoryRv.layoutParams.width = width

            // 嵌入在首页时特殊处理
            if (arguments?.getBoolean(EntranceConsts.KEY_IS_HOME) == true) {
                root.setBackgroundColor(R.color.background_white.toColor(requireContext()))
                root.setPadding(0, 8F.dip2px(), 0, 0)
                directoryRv.isNestedScrollingEnabled = false
                categoryRv.setBackgroundColor(R.color.background.toColor(requireContext()))
            }
        }

        mViewModel?.directoriesLiveData?.observeNonNull(viewLifecycleOwner) {
            initDirectoryView(it)
        }

        mViewModel?.selectedCountLiveData?.observeNonNull(viewLifecycleOwner) {
            mBinding?.run {
                if (it == 0) {
                    confirmTv.text = "确定"
                } else {
                    mViewModel?.run {
                        if (selectedCategoryName != "全部") {
                            selectedCategoryName = "全部"
                            selectedCategoryPosition = if (mEntity?.hasSpecial == true) 1 else 0
                            categoryRv.adapter?.notifyDataSetChanged()
                            mCategoryV2ListFragment?.updateSubCategoryId("all")
                        }
                    }

                    confirmTv.text = "确定(已选${it})"
                }
            }
        }

        mViewModel?.sidebarsLiveData?.observe(viewLifecycleOwner, Observer {
            mBinding?.run {
                reuseLoading.root.visibility = View.GONE
                if (it != null) {
                    reuseNoConnection.root.visibility = View.GONE
                    categoryContainer.visibility = View.VISIBLE
                    reuseNoneData.root.visibility = View.GONE
                    mEntity = it
                    (mEntity!!.sidebars as ArrayList).run {
                        val allEntity = SidebarsEntity.SidebarEntity(name = "全部", categoryId = "all")
                        if (mEntity!!.hasSpecial) {
                            val specialEntity = SidebarsEntity.SidebarEntity(name = "精选")
                            add(0, specialEntity)
                            add(1, allEntity)
                        } else {
                            add(0, allEntity)
                        }
                    }
                    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
                        mViewModel?.getSidebars()
                        mViewModel?.getCategoryDirectories()
                    }
                }
            }
        })
    }

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

    private fun showGuide() {
        mBinding?.run {
            val isShow = SPUtils.getBoolean(Constants.SP_SHOW_CATEGORY_GUIDE)
            if (isShow) return

            guideContainer.layoutParams = (guideContainer.layoutParams as ViewGroup.MarginLayoutParams).apply {
                val screenWidth = resources.displayMetrics.widthPixels
                leftMargin = screenWidth * 66F.dip2px() / 360F.dip2px()
            }
            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", mCategoryTitle, "", "")
                val intent = SearchActivity.getIntent(
                    requireContext(),
                    false,
                    "",
                    "新分类2.0"
                )
                startActivity(intent)
            }
        }
    }

    private fun initDirectoryView(list: List<CategoryEntity>) {
        mBinding?.run {
            mViewModel?.run {
                if (directoryRv.adapter != null) {
                    (directoryRv.adapter as? CategoryDirectoryAdapter)?.setListData(list)
                } else {
                    directoryRv.layoutManager = FixLinearLayoutManager(requireContext())
                    directoryRv.adapter = CategoryDirectoryAdapter(
                        requireContext(),
                        this,
                        list
                    )
                }
            }

            resetTv.setOnClickListener {
                mViewModel?.logClickReset("全部类别")
                confirmTv.text = "确定"
                mViewModel?.resetDirectoryList()
                mCategoryV2ListFragment?.changeCategoryTab()
            }

            confirmTv.setOnClickListener {
                mViewModel?.logClickDetermine()
                drawerLayout.closeDrawer(GravityCompat.START)
            }
        }
    }

    private fun initView() {
        if (mEntity?.sidebars?.isNullOrEmpty() == true || mViewModel == null) return
        initSelectedCategory()
        initCategoryRv()
        initContentFragment()
    }

    private fun initSelectedCategory() {
        mEntity?.run {
            mViewModel?.run {
                if (mLastSelectedPosition != -1) {
                    selectedCategoryPosition = mLastSelectedPosition
                    selectedCategoryName = sidebars[mLastSelectedPosition].name
                } else {
                    selectedCategoryPosition = 0
                    selectedCategoryName = sidebars[0].name
                }
            }
        }
    }

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

    private fun initContentFragment() {
        mEntity?.apply {
            mViewModel?.apply {
                if (hasSpecial && selectedCategoryPosition == 0) {
                    initSpecialCatalogFragment()
                } else {
                    initCategoryV2ListFragment()

                    // 第一次点"全部"tab展开全部类别选择框
                    // 加延迟是为了防止卡顿
                    if (SPUtils.getBoolean(Constants.SP_FIRST_ENTER_CATEGORY_V2, true)) {
                        SPUtils.setBoolean(Constants.SP_FIRST_ENTER_CATEGORY_V2, false)
                        mBinding?.drawerLayout?.postDelayed({
                            tryCatchInRelease { openDrawer() }
                        }, 500L)
                    }
                }
            }
        }
    }

    private fun initSpecialCatalogFragment() {
        mEntity?.run {
            mSpecialCatalogFragment = childFragmentManager
                .findFragmentByTag(SpecialCatalogFragment::class.java.name)
                    as? SpecialCatalogFragment ?: SpecialCatalogFragment()
            mSpecialCatalogFragment?.arguments = bundleOf(
                EntranceConsts.KEY_IS_CATEGORY_V2 to true,
                EntranceConsts.KEY_CATALOG_ID to id,
                EntranceConsts.KEY_CATALOG_TITLE to mCategoryTitle,
                EntranceConsts.KEY_EXPOSURE_SOURCE_LIST to arguments?.getParcelableArrayList<ExposureSource>(
                    EntranceConsts.KEY_EXPOSURE_SOURCE_LIST
                ),
                EntranceConsts.KEY_LAST_PAGE_DATA to mLastPageDataMap
            )
            childFragmentManager
                .beginTransaction()
                .replace(
                    R.id.gamesContainer,
                    mSpecialCatalogFragment!!,
                    SpecialCatalogFragment::class.java.name
                )
                .commitAllowingStateLoss()
        }
    }

    private fun initCategoryV2ListFragment() {
        mEntity?.run {
            mViewModel?.run {
                mCategoryV2ListFragment = childFragmentManager
                    .findFragmentByTag(CategoryV2ListFragment::class.java.name)
                        as? CategoryV2ListFragment ?: CategoryV2ListFragment()
                mCategoryV2ListFragment?.arguments = bundleOf(
                    EntranceConsts.KEY_CATEGORY_ID to id,
                    EntranceConsts.KEY_SUB_CATEGORY_ID to sidebars[selectedCategoryPosition].categoryId,
                    EntranceConsts.KEY_CATEGORY_TITLE to mCategoryTitle,
                    EntranceConsts.KEY_EXPOSURE_SOURCE_LIST to arguments?.getParcelableArrayList<ExposureSource>(
                        EntranceConsts.KEY_EXPOSURE_SOURCE_LIST
                    ),
                    EntranceConsts.KEY_LAST_PAGE_DATA to mLastPageDataMap
                )
                childFragmentManager
                    .beginTransaction()
                    .replace(
                        R.id.gamesContainer,
                        mCategoryV2ListFragment!!,
                        CategoryV2ListFragment::class.java.name
                    )
                    .commitAllowingStateLoss()
            }
        }
    }

    fun changeCategory(position: Int) {
        mEntity?.run {
            mViewModel?.run {
                resetDirectoryList()

                if (hasSpecial) {
                    if (selectedCategoryPosition == 0) {
                        mCategoryV2ListFragment = childFragmentManager
                            .findFragmentByTag(CategoryV2ListFragment::class.java.name)
                                as? CategoryV2ListFragment ?: CategoryV2ListFragment()
                        mCategoryV2ListFragment?.arguments = bundleOf(
                            EntranceConsts.KEY_CATEGORY_ID to id,
                            EntranceConsts.KEY_SUB_CATEGORY_ID to sidebars[position].categoryId,
                            EntranceConsts.KEY_CATALOG_TITLE to mCategoryTitle,
                            EntranceConsts.KEY_EXPOSURE_SOURCE_LIST to arguments?.getParcelableArrayList<ExposureSource>(
                                EntranceConsts.KEY_EXPOSURE_SOURCE_LIST
                            ),
                            EntranceConsts.KEY_LAST_PAGE_DATA to mLastPageDataMap
                        )
                        childFragmentManager
                            .beginTransaction()
                            .replace(
                                R.id.gamesContainer,
                                mCategoryV2ListFragment!!,
                                CategoryV2ListFragment::class.java.name
                            )
                            .commitAllowingStateLoss()
                    } else {
                        if (position == 0) {
                            removeGuide()

                            mSpecialCatalogFragment = childFragmentManager
                                .findFragmentByTag(SpecialCatalogFragment::class.java.name)
                                    as? SpecialCatalogFragment ?: SpecialCatalogFragment()
                            mSpecialCatalogFragment?.arguments = bundleOf(
                                EntranceConsts.KEY_IS_CATEGORY_V2 to true,
                                EntranceConsts.KEY_CATALOG_ID to id,
                                EntranceConsts.KEY_CATALOG_TITLE to mCategoryTitle,
                                EntranceConsts.KEY_EXPOSURE_SOURCE_LIST to arguments?.getParcelableArrayList<ExposureSource>(
                                    EntranceConsts.KEY_EXPOSURE_SOURCE_LIST
                                ),
                                EntranceConsts.KEY_LAST_PAGE_DATA to mLastPageDataMap
                            )
                            childFragmentManager
                                .beginTransaction()
                                .replace(
                                    R.id.gamesContainer,
                                    mSpecialCatalogFragment!!,
                                    SpecialCatalogFragment::class.java.name
                                )
                                .commitAllowingStateLoss()
                        } else {
                            if (mCategoryV2ListFragment?.isStateSaved == false) {
                                mCategoryV2ListFragment?.arguments = bundleOf(
                                    EntranceConsts.KEY_CATEGORY_ID to id,
                                    EntranceConsts.KEY_SUB_CATEGORY_ID to sidebars[position].categoryId,
                                    EntranceConsts.KEY_CATALOG_TITLE to mCategoryTitle,
                                    EntranceConsts.KEY_EXPOSURE_SOURCE_LIST to arguments?.getParcelableArrayList<ExposureSource>(
                                        EntranceConsts.KEY_EXPOSURE_SOURCE_LIST
                                    ),
                                    EntranceConsts.KEY_LAST_PAGE_DATA to mLastPageDataMap
                                )
                            }
                            mCategoryV2ListFragment?.changeCategoryTab(sidebars[position].categoryId)
                        }
                    }

                    // 第一次点"全部"tab展开全部类别选择框
                    // 加延迟是为了防止卡顿
                    if (position == 1 && SPUtils.getBoolean(Constants.SP_FIRST_ENTER_CATEGORY_V2, true)) {
                        SPUtils.setBoolean(Constants.SP_FIRST_ENTER_CATEGORY_V2, false)
                        mBinding?.drawerLayout?.postDelayed({
                            tryCatchInRelease { openDrawer() }
                        }, 200L)
                    }
                } else {
                    if (mCategoryV2ListFragment?.isStateSaved == false) {
                        mCategoryV2ListFragment?.arguments = bundleOf(
                            EntranceConsts.KEY_CATEGORY_ID to id,
                            EntranceConsts.KEY_SUB_CATEGORY_ID to sidebars[position].categoryId,
                            EntranceConsts.KEY_CATALOG_TITLE to mCategoryTitle,
                            EntranceConsts.KEY_EXPOSURE_SOURCE_LIST to arguments?.getParcelableArrayList<ExposureSource>(
                                EntranceConsts.KEY_EXPOSURE_SOURCE_LIST
                            ),
                            EntranceConsts.KEY_LAST_PAGE_DATA to mLastPageDataMap
                        )
                    }
                    mCategoryV2ListFragment?.changeCategoryTab(sidebars[position].categoryId)
                }
                selectedCategoryPosition = position
            }
        }
    }

    fun openDirectoryLayout() {
        mBinding?.run {
            var i = 0
            mViewModel?.run {
                mEntity?.run {
                    val sidebar = sidebars[selectedCategoryPosition]
                    if (sidebar.name != "全部") {
                        directories.forEachIndexed { index, entity ->
                            if (sidebar.type == "level_one") {
                                if (sidebar.categoryId == entity.id) {
                                    i = index
                                    return@run
                                }
                            } else {
                                if (sidebar.parentId == entity.id) {
                                    i = index
                                    return@run
                                }
                            }
                        }
                    } else if (sidebar.name == "全部" && selectedCategoryList.isNotEmpty()) {
                        i = selectedCategoryList[0].primaryIndex
                    }
                }
            }
            openDrawer()
            (directoryRv.layoutManager as? LinearLayoutManager)?.scrollToPositionWithOffset(i, 0)
        }
    }

    private fun openDrawer() {
        mBinding?.drawerLayout?.openDrawer(GravityCompat.START)

        mHomeViewModel?.let {
            mBinding?.directoryContainer?.setPadding(
                0,
                0,
                0,
                requireContext().resources.getDimension(R.dimen.main_bottom_tab_height).toInt() - it.appBarOffset
            )
        }
    }

    override fun onDarkModeChanged() {
        super.onDarkModeChanged()
        mBinding?.categoryRv?.adapter?.run {
            mBinding?.categoryRv?.recycledViewPool?.clear()
            notifyItemRangeChanged(0, itemCount)
        }
        mBinding?.directoryRv?.adapter?.run {
            mBinding?.directoryRv?.recycledViewPool?.clear()
            notifyItemRangeChanged(0, itemCount)
        }
    }
}