package com.gh.gamecenter.catalog

import android.os.Bundle
import android.view.View
import androidx.core.os.bundleOf
import androidx.lifecycle.Observer
import com.gh.gamecenter.common.base.fragment.LazyFragment
import com.gh.gamecenter.common.constant.EntranceConsts
import com.gh.gamecenter.common.utils.dip2px
import com.gh.gamecenter.common.utils.toColor
import com.gh.gamecenter.common.utils.viewModelProviderFromParent
import com.gh.gamecenter.common.view.FixLinearLayoutManager
import com.gh.gamecenter.R
import com.gh.gamecenter.databinding.FragmentCatalogBinding
import com.gh.gamecenter.entity.CatalogEntity

class CatalogFragment : LazyFragment() {

    private var mBinding: FragmentCatalogBinding? = null
    private var mViewModel: CatalogViewModel? = null
    private var mEntity: CatalogEntity? = null
    private var mSpecialCatalogFragment: SpecialCatalogFragment? = null
    private var mSubCatalogFragment: SubCatalogFragment? = null

    private var mCatalogId: String = ""
    private var mCatalogTitle: 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, selectedCatalogPosition)
        }
        super.onSaveInstanceState(outState)
    }

    override fun getRealLayoutId() = R.layout.fragment_catalog

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

    override fun onFragmentFirstVisible() {
        mCatalogId = arguments?.getString(EntranceConsts.KEY_CATALOG_ID) ?: ""
        mCatalogTitle = arguments?.getString(EntranceConsts.KEY_CATALOG_TITLE) ?: ""
        mViewModel = viewModelProviderFromParent(CatalogViewModel.Factory(mCatalogId, mCatalogTitle), mCatalogId)

        mViewModel?.validEntranceName = if (mEntrance.contains("首页")) "首页" else "板块"
        if (arguments?.getBoolean(EntranceConsts.KEY_IS_HOME) == true) {
            mViewModel?.validEntranceName = "首页Tab栏"
        }
        mViewModel?.logAppearance()

        super.onFragmentFirstVisible()
    }

    override fun initRealView() {
        super.initRealView()

        setNavigationTitle(mCatalogTitle)
        mViewModel?.catalogs?.observe(viewLifecycleOwner, Observer {
            mBinding?.run {
                reuseLoading.root.visibility = View.GONE
                if (it != null) {
                    reuseNoConnection.root.visibility = View.GONE
                    if (it.subCatalog.isNotEmpty()) {
                        containerCatalog.visibility = View.VISIBLE
                        reuseNoneData.root.visibility = View.GONE
                        mEntity = it
                        if (mEntity!!.hasSpecial) {
                            val specialEntity = CatalogEntity.SubCatalogEntity(name = "精选")
                            (mEntity!!.subCatalog as ArrayList).add(0, specialEntity)
                        }
                        initView()
                    } else {
                        containerCatalog.visibility = View.GONE
                        reuseNoneData.root.visibility = View.VISIBLE
                    }
                } else {
                    containerCatalog.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?.getCatalogs()
                    }
                }
            }
        })

        // 嵌入在首页时特殊处理
        if (arguments?.getBoolean(EntranceConsts.KEY_IS_HOME) == true) {
            mBinding?.divider?.visibility = View.GONE
            mBinding?.root?.setBackgroundColor(R.color.background_white.toColor(requireContext()))
            mBinding?.root?.setPadding(0, 8F.dip2px(), 0, 0)
            mBinding?.rvCatalog?.setBackgroundColor(R.color.background.toColor(requireContext()))
        }
    }

    private fun initView() {
        mEntity?.run {
            mViewModel?.run {
                if (subCatalog.isNotEmpty()) {
                    if (mLastSelectedPosition != -1) {
                        selectedCatalogPosition = mLastSelectedPosition
                        selectedCatalogName = subCatalog[mLastSelectedPosition].name
                    } else {
                        selectedCatalogPosition = 0
                        selectedCatalogName = subCatalog[0].name
                    }
                    mBinding?.rvCatalog?.layoutManager = FixLinearLayoutManager(requireContext())
                    mBinding?.rvCatalog?.adapter =
                        CatalogAdapter(requireContext(), this@CatalogFragment, this, subCatalog)

                    if (hasSpecial && selectedCatalogPosition == 0) {
                        mSpecialCatalogFragment =
                            childFragmentManager.findFragmentByTag(SpecialCatalogFragment::class.java.name) as? SpecialCatalogFragment
                                ?: SpecialCatalogFragment()
                        mSpecialCatalogFragment?.arguments = bundleOf(
                            EntranceConsts.KEY_IS_CATEGORY_V2 to false,
                            EntranceConsts.KEY_CATALOG_ID to id,
                            EntranceConsts.KEY_CATALOG_TITLE to mCatalogTitle,
                            EntranceConsts.KEY_EXPOSURE_SOURCE to arguments?.getParcelable(
                                EntranceConsts.KEY_EXPOSURE_SOURCE
                            )
                        )
                        childFragmentManager.beginTransaction().replace(
                            R.id.container_sub_catalog,
                            mSpecialCatalogFragment!!,
                            SpecialCatalogFragment::class.java.name
                        ).commitAllowingStateLoss()
                    } else {
                        mSubCatalogFragment =
                            childFragmentManager.findFragmentByTag(SubCatalogFragment::class.java.name) as? SubCatalogFragment
                                ?: SubCatalogFragment()
                        mSubCatalogFragment?.arguments = bundleOf(
                            EntranceConsts.KEY_CATALOG_ID to id,
                            EntranceConsts.KEY_PRIMARY_CATALOG_ID to subCatalog[selectedCatalogPosition].id,
                            EntranceConsts.KEY_CATALOG_TITLE to mCatalogTitle
                        )
                        childFragmentManager.beginTransaction().replace(
                            R.id.container_sub_catalog,
                            mSubCatalogFragment!!,
                            SubCatalogFragment::class.java.name
                        ).commitAllowingStateLoss()
                    }
                }
            }
        }
    }

    fun changeCatalog(position: Int) {
        mEntity?.run {
            mViewModel?.run {
                if (hasSpecial) {
                    changeCatalogIfHasSpecial(position)
                } else {
                    changeSubCatalogInSubCatalogFragment(position)
                }
                selectedCatalogPosition = position
            }
        }
    }

    private fun changeCatalogIfHasSpecial(position: Int) {
        mViewModel?.run {
            when {
                selectedCatalogPosition == 0 -> changeToSubCatalogFragment(position)
                position == 0 -> changeToSpecialCatalogFragment()
                else -> changeSubCatalogInSubCatalogFragment(position)
            }
        }
    }

    private fun changeToSubCatalogFragment(position: Int) {
        mEntity?.run {
            mSubCatalogFragment =
                childFragmentManager.findFragmentByTag(SubCatalogFragment::class.java.name) as? SubCatalogFragment
                    ?: SubCatalogFragment()
            mSubCatalogFragment?.arguments = bundleOf(
                EntranceConsts.KEY_CATALOG_ID to id,
                EntranceConsts.KEY_PRIMARY_CATALOG_ID to subCatalog[position].id,
                EntranceConsts.KEY_CATALOG_TITLE to mCatalogTitle
            )
            childFragmentManager.beginTransaction().replace(
                R.id.container_sub_catalog,
                mSubCatalogFragment!!,
                SubCatalogFragment::class.java.name
            ).commitAllowingStateLoss()
        }
    }

    private fun changeToSpecialCatalogFragment() {
        mEntity?.run {
            mSpecialCatalogFragment =
                childFragmentManager.findFragmentByTag(SpecialCatalogFragment::class.java.name) as? SpecialCatalogFragment
                    ?: SpecialCatalogFragment()
            mSpecialCatalogFragment?.arguments = bundleOf(
                EntranceConsts.KEY_IS_CATEGORY_V2 to false,
                EntranceConsts.KEY_CATALOG_ID to id,
                EntranceConsts.KEY_CATALOG_TITLE to mCatalogTitle,
                EntranceConsts.KEY_EXPOSURE_SOURCE to arguments?.getParcelable(
                    EntranceConsts.KEY_EXPOSURE_SOURCE
                )
            )
            childFragmentManager.beginTransaction().replace(
                R.id.container_sub_catalog,
                mSpecialCatalogFragment!!,
                SpecialCatalogFragment::class.java.name
            ).commitAllowingStateLoss()
        }
    }

    private fun changeSubCatalogInSubCatalogFragment(position: Int) {
        mEntity?.run {
            if (mSubCatalogFragment?.isStateSaved == false) {
                mSubCatalogFragment?.arguments = bundleOf(
                    EntranceConsts.KEY_CATALOG_ID to id,
                    EntranceConsts.KEY_PRIMARY_CATALOG_ID to subCatalog[position].id,
                    EntranceConsts.KEY_CATALOG_TITLE to mCatalogTitle
                )
            }
            mSubCatalogFragment?.changeSubCatalog(subCatalog[position].id)
        }
    }

    override fun onDarkModeChanged() {
        super.onDarkModeChanged()
        mBinding?.rvCatalog?.adapter?.run {
            notifyItemRangeChanged(0, itemCount)
        }
    }
}