package com.gh.gamecenter.category2

import android.os.Bundle
import android.view.View
import androidx.fragment.app.viewModels
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.ethanhua.skeleton.Skeleton
import com.gh.common.exposure.DefaultExposureStateChangeListener
import com.gh.common.util.DialogUtils
import com.gh.common.view.CategoryFilterView
import com.gh.common.xapk.XapkInstaller
import com.gh.common.xapk.XapkUnzipStatus
import com.gh.download.DownloadManager
import com.gh.gamecenter.R
import com.gh.gamecenter.common.baselist.ListFragment
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.constant.EntranceConsts
import com.gh.gamecenter.common.utils.goneIf
import com.gh.gamecenter.common.utils.observeNonNull
import com.gh.gamecenter.common.utils.toColor
import com.gh.gamecenter.common.utils.viewModelProvider
import com.gh.gamecenter.databinding.FragmentCategoryListBinding
import com.gh.gamecenter.entity.SubjectSettingEntity
import com.gh.gamecenter.eventbus.EBDownloadStatus
import com.gh.gamecenter.eventbus.EBPackage
import com.gh.gamecenter.feature.exposure.addExposureHelper
import com.google.android.flexbox.FlexboxLayout
import com.gh.gamecenter.feature.entity.GameEntity
import com.lightgame.download.DataWatcher
import com.lightgame.download.DownloadEntity
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode

class CategoryV2ListFragment : ListFragment<GameEntity, CategoryV2ListViewModel>() {

    private var pageId: String = ""
    private var pageName: String = ""
    private val parentViewModel by viewModels<CategoryV2ViewModel>(
        ownerProducer = { parentFragment ?: this }
    )

    override fun isAutomaticLoad(): Boolean {
        return false
    }

    private var mAdapter: CategoryV2ListAdapter? = null
    private var mBinding: FragmentCategoryListBinding? = null
    private var mLastPageDataMap: HashMap<String, String>? = null
    private val mDataWatcher = object : DataWatcher() {
        override fun onDataChanged(downloadEntity: DownloadEntity) {
            mAdapter?.notifyItemByDownload(downloadEntity)

            if (downloadEntity.meta[XapkInstaller.XAPK_UNZIP_STATUS] == XapkUnzipStatus.FAILURE.name) {
                showUnzipFailureDialog(downloadEntity)
            }
        }

        override fun onDataInit(downloadEntity: DownloadEntity) {
            mAdapter?.notifyItemByDownload(downloadEntity)
        }
    }

    private val selectedTagsAdapter by lazy {
        SelectedTagsAdapter {
            parentViewModel.removeSubCategorySelected(it.parentId, it.category.id, "游戏列表")
        }
    }

    override fun getLayoutId() = 0

    override fun getInflatedLayout() =
        FragmentCategoryListBinding.inflate(layoutInflater).apply { mBinding = this }.root

    override fun provideListViewModel() =
        viewModelProvider<CategoryV2ListViewModel>(
            CategoryV2ListViewModel.Factory(
                pageId,
                arguments?.getParcelableArrayList(EntranceConsts.KEY_EXPOSURE_SOURCE_LIST)
            )
        )

    override fun provideListAdapter() = mAdapter
        ?: CategoryV2ListAdapter(
            requireContext(),
            mListViewModel ?: provideListViewModel(),
            parentViewModel,
            mEntrance,
            mLastPageDataMap
        ).apply { mAdapter = this }

    override fun getItemDecoration() = null

    override fun onCreate(savedInstanceState: Bundle?) {
        pageId = arguments?.getString(EntranceConsts.KEY_PAGE_ID) ?: ""
        pageName = arguments?.getString(EntranceConsts.KEY_PAGE_NAME) ?: ""
        mLastPageDataMap = arguments?.getSerializable(EntranceConsts.KEY_LAST_PAGE_DATA) as? HashMap<String, String>

        mEntrance = arguments?.getString(EntranceConsts.KEY_ENTRANCE) ?: Constants.ENTRANCE_UNKNOWN

        super.onCreate(savedInstanceState)
        mBinding?.reuseNoneData?.reuseResetLoadTv?.visibility = View.VISIBLE
        mBinding?.reuseNoneData?.reuseNoneDataTv?.text = getString(R.string.game_empty_second)
        mBinding?.reuseNoneData?.reuseNoneDataDescTv?.visibility = View.VISIBLE
        mBinding?.reuseNoneData?.reuseNoneDataDescTv?.text = getString(R.string.game_empty_second_desc)
        mBinding?.reuseNoneData?.reuseResetLoadTv?.text = "重置"
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        initFilterView()

        mListViewModel?.refresh?.observeNonNull(viewLifecycleOwner) {
            onRefresh()
        }

        mListRv.addExposureHelper(this, DefaultExposureStateChangeListener())

        mSkeletonScreen = Skeleton.bind(mBinding?.listSkeleton)
            .shimmer(true)
            .angle(Constants.SHIMMER_ANGLE)
            .color(com.gh.gamecenter.common.R.color.ui_skeleton_highlight)
            .duration(Constants.SHIMMER_DURATION)
            .maskWidth(Constants.MASK_WIDTH)
            .gradientCenterColorWidth(Constants.GRADIENT_CENTER_COLOR_WIDTH)
            .load(R.layout.fragment_category_game_list_skeleton)
            .show()

        mBinding?.reuseNoneData?.reuseResetLoadTv?.setOnClickListener {
            // 重试时，
            // 清空所有筛选条件
            with(parentViewModel) {
                logClickReset("游戏列表")
                clearSelectedTag()
                // 移除大小限制
                mBinding?.filterContainer?.resetSortSize()
                val size = SubjectSettingEntity.Size()
                updateGameFiltered(size)
            }

        }

        with(parentViewModel) {
            gameFiltered.observe(viewLifecycleOwner) {
                mListViewModel.updateSortConfig(it)
            }

            selectedSubCategories.observe(viewLifecycleOwner) {
                updateSelectedTags(it)
            }
        }
    }

    private fun updateSelectedTags(selectedTags: List<CategoryV2ViewModel.SelectedTags>) {
        mBinding?.run {
            flTagsContainer.goneIf(selectedTags.isEmpty()) {
                if (rvTags.adapter == null) {
                    rvTags.layoutManager = LinearLayoutManager(requireContext(), RecyclerView.HORIZONTAL, false)
                    rvTags.adapter = selectedTagsAdapter
                }
                selectedTagsAdapter.submitList(selectedTags)
            }
        }

    }

    private fun initFilterView() {
        mBinding?.filterContainer?.run {
            visibility = View.VISIBLE

            setOnConfigSetupListener(object : CategoryFilterView.OnCategoryFilterSetupListener {
                override fun onSetupSortSize(sortSize: SubjectSettingEntity.Size) {
                    parentViewModel.updateGameFiltered(size = sortSize)
                }

                override fun onSetupSortType(sortType: CategoryFilterView.SortType) {
                    parentViewModel.updateGameFiltered(sortType = sortType)
                }

                override fun getPopHeight(): Int {
                    return (mBinding?.root?.height ?: 0) - (mBinding?.flTagsContainer?.height ?: 0)
                }
            })

            setOnFilterClickListener(object : CategoryFilterView.OnFilterClickListener {

                override fun onTypeClick() {
                    removeGuide()
                }

                override fun onSizeClick() {
                    removeGuide()
                }

            })
        }
    }

    private fun removeGuide() {
        (parentFragment as? CategoryV2Fragment)?.removeGuide()
    }

    override fun onResume() {
        super.onResume()
        DownloadManager.getInstance().addObserver(mDataWatcher)
    }

    override fun onPause() {
        super.onPause()
        DownloadManager.getInstance().removeObserver(mDataWatcher)
    }

    override fun onRefresh() {
        mAdapter?.clearPositionAndPackageMap()

        super.onRefresh()
    }

    // 下载被删除事件
    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onEventMainThread(status: EBDownloadStatus) {
        if ("delete" == status.status) {
            mAdapter?.notifyItemAndRemoveDownload(status)
        }
    }

    // 安装/卸载 事件
    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onEventMainThread(busFour: EBPackage) {
        // 忽略首次初始化触发的事件
        if (!busFour.fromInit && busFour.isInstalledOrUninstalled()) {
            mAdapter?.notifyDataSetChanged()
        }
    }

    fun showUnzipFailureDialog(downloadEntity: DownloadEntity) {
        val data = mAdapter?.positionAndPackageMap ?: return
        for (gameAndPosition in data) {
            if (gameAndPosition.key.contains(downloadEntity.packageName)) {
                val targetView = mLayoutManager.findViewByPosition(gameAndPosition.value)
                if (targetView != null) {
                    DialogUtils.showUnzipFailureDialog(requireContext(), downloadEntity)
                    return
                }
            }
        }
    }

    override fun onDarkModeChanged() {
        super.onDarkModeChanged()
        mBinding?.filterContainer?.run {
            setRootBackgroundColor(com.gh.gamecenter.common.R.color.ui_surface.toColor(requireContext()))
            setItemTextColor(com.gh.gamecenter.common.R.color.text_secondary.toColor(requireContext()))
            updatePopupWindow()
        }
    }
}