package com.gh.gamecenter.category

import android.os.Bundle
import android.view.View
import androidx.recyclerview.widget.LinearLayoutManager
import com.ethanhua.skeleton.Skeleton
import com.gh.common.exposure.ExposureListener
import com.gh.common.util.DialogUtils
import com.gh.common.view.ConfigFilterView
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.constant.Constants
import com.gh.gamecenter.common.baselist.ListAdapter
import com.gh.gamecenter.common.baselist.ListFragment
import com.gh.gamecenter.common.constant.EntranceConsts
import com.gh.gamecenter.common.utils.observeNonNull
import com.gh.gamecenter.common.utils.toColor
import com.gh.gamecenter.common.utils.tryCatchInRelease
import com.gh.gamecenter.common.utils.viewModelProvider
import com.gh.gamecenter.databinding.FragmentTagsBinding
import com.gh.gamecenter.entity.CategoryEntity
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.entity.SubjectSettingEntity
import com.gh.gamecenter.eventbus.EBDownloadStatus
import com.gh.gamecenter.eventbus.EBPackage
import com.lightgame.download.DataWatcher
import com.lightgame.download.DownloadEntity
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode

class NewCategoryListFragment : ListFragment<GameEntity, NewCategoryListViewModel>() {

    private var mPrimeCategory: CategoryEntity? = null
    private var mSubCategoryList = arrayListOf<CategoryEntity>()
    private val mBinding by lazy { FragmentTagsBinding.inflate(layoutInflater) }

    private var mAdapter: NewCategoryListAdapter? = 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 lateinit var mExposureListener: ExposureListener
    private lateinit var mViewModel: NewCategoryListViewModel

    override fun onCreate(savedInstanceState: Bundle?) {
        mViewModel = provideListViewModel()

        mViewModel.title = arguments?.getString(EntranceConsts.KEY_NAME) ?: ""
        mViewModel.categoryTitle = arguments?.getString(EntranceConsts.KEY_CATEGORY_TITLE) ?: ""
        mEntrance = arguments?.getString(EntranceConsts.KEY_ENTRANCE) ?: Constants.ENTRANCE_UNKNOWN
        mPrimeCategory = arguments?.getParcelable(EntranceConsts.KEY_DATA)
        mSubCategoryList = mPrimeCategory?.data as? ArrayList<CategoryEntity> ?: arrayListOf()

        val initSelectedCategory = arguments?.getString(EntranceConsts.KEY_CATEGORY_INIT_TITLE)

        mViewModel.selectedCategory =
            mSubCategoryList.find { categoryEntity -> categoryEntity.name == initSelectedCategory }
                ?: CategoryEntity()

        super.onCreate(savedInstanceState)
    }

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

        setNavigationTitle(mViewModel.title)

        mViewModel.refresh.observeNonNull(this) { onRefresh() }

        mBinding.configContainer.visibility = View.VISIBLE
        mBinding.configContainer.updateAllTextView(mViewModel.sortType)
        mBinding.configContainer.setOnConfigSetupListener(object : ConfigFilterView.OnConfigFilterSetupListener {
            override fun onShowSortSize() {}

            override fun onSetupSortSize(sortSize: SubjectSettingEntity.Size) {
                mViewModel.updateSortConfig(sortSize = sortSize)
            }

            override fun onSetupSortType(sortType: ConfigFilterView.SortType) {
                mViewModel.updateSortConfig(sortType = sortType)
            }
        })

        mExposureListener = ExposureListener(this, mAdapter!!)
        mListRv.addOnScrollListener(mExposureListener)

        updateCategoriesView(mSubCategoryList)

        mSkeletonScreen =
            Skeleton.bind(mBinding.listSkeleton).shimmer(false).load(R.layout.fragment_subject_skeleton).show()
    }

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

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

    override fun getItemDecoration() = null

    override fun getLayoutId() = 0

    override fun getInflatedLayout() = mBinding.root

    override fun provideListViewModel(): NewCategoryListViewModel {
        return viewModelProvider()
    }

    override fun provideListAdapter(): ListAdapter<GameEntity> {
        return mAdapter
            ?: NewCategoryListAdapter(requireContext(), mViewModel, mEntrance).apply { mAdapter = this }
    }

    private fun updateCategoriesView(categoryList: ArrayList<CategoryEntity>) {
        mBinding.tagsRecyclerView.layoutManager =
            LinearLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL, false)
        mBinding.tagsRecyclerView.adapter = NewCategoryHorizontalAdapter(requireContext(), mViewModel, categoryList) {
            mBinding.tagsRecyclerView.smoothScrollToPosition(it)
        }

        // 调整选中标签位置
        for (index in 0 until categoryList.size) {
            if (categoryList[index].name == mViewModel.selectedCategory.name) {
                mBinding.tagsRecyclerView.postDelayed({
                    tryCatchInRelease { mBinding.tagsRecyclerView.smoothScrollToPosition(index) }
                }, 200)
                break
            }
        }
    }

    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.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.run {
            divider.setBackgroundColor(R.color.background.toColor(requireContext()))
            tagsRecyclerView.setBackgroundColor(R.color.background_white.toColor(requireContext()))
            tagsRecyclerView.adapter?.run {
                notifyItemRangeChanged(0, itemCount)
            }
            configContainer.run {
                container.setBackgroundColor(R.color.background_white.toColor(requireContext()))
                updateAllTextView(mViewModel.sortType)
                updatePopupWindow()
            }
        }
    }
}