package com.gh.gamecenter.download

import android.annotation.SuppressLint
import android.os.Bundle
import android.view.View
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.DefaultItemAnimator
import com.ethanhua.skeleton.Skeleton
import com.ethanhua.skeleton.ViewSkeletonScreen
import com.gh.common.exposure.ExposureListener
import com.gh.common.util.DownloadItemUtils
import com.gh.download.DownloadManager
import com.gh.gamecenter.MainActivity
import com.gh.gamecenter.R
import com.gh.gamecenter.common.base.fragment.ToolbarFragment
import com.gh.gamecenter.common.eventbus.EBReuse
import com.gh.gamecenter.common.utils.PermissionHelper
import com.gh.gamecenter.common.utils.isSimulatorGame
import com.gh.gamecenter.common.utils.toColor
import com.gh.gamecenter.common.view.FixLinearLayoutManager
import com.gh.gamecenter.common.view.VerticalItemDecoration
import com.gh.gamecenter.core.utils.DisplayUtils
import com.gh.gamecenter.core.utils.EmptyCallback
import com.gh.gamecenter.databinding.FragmentMyGameBinding
import com.gh.gamecenter.entity.GameEntity
import com.gh.gamecenter.entity.GameInstall
import com.gh.gamecenter.eventbus.EBDownloadStatus
import com.gh.gamecenter.eventbus.EBPackage
import com.gh.gamecenter.fragment.MainWrapperFragment
import com.gh.gamecenter.manager.PackagesManager
import com.gh.gamecenter.packagehelper.PackageRepository
import com.gh.gamecenter.packagehelper.PackageViewModel
import com.lightgame.download.DataWatcher
import com.lightgame.download.DownloadEntity
import com.lightgame.download.DownloadStatus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode

class NewInstalledGameFragment : ToolbarFragment() {

    private lateinit var mBinding: FragmentMyGameBinding
    private var mPackageViewModel: PackageViewModel? = null
    private lateinit var mInstallGameViewModel: InstalledGameViewModel
    private var mAdapter: NewInstalledGameFragmentAdapter? = null
    private var mExposureListener: ExposureListener? = null

    private var mSkeleton: ViewSkeletonScreen? = null
    private var mItemDecoration: VerticalItemDecoration? = null

    private val dataWatcher = object : DataWatcher() {
        override fun onDataChanged(downloadEntity: DownloadEntity) {
            if (downloadEntity.status == DownloadStatus.done && downloadEntity.isSimulatorGame()) {
                DownloadManager.getInstance().getEntryMap(downloadEntity.name)?.let {
                    it[downloadEntity.platform] = downloadEntity
                }
                mPackageViewModel?.getGameInstalledLiveData()?.value?.let {
                    mInstallGameViewModel.initData(
                        PackagesManager.filterSameApk(
                            PackagesManager.filterDownloadBlackPackage(
                                it as MutableList<GameInstall>?
                            )
                        )
                    )
                }
                return
            }
            val locationList = mInstallGameViewModel.locationMap[downloadEntity.packageName]
            if (locationList != null && locationList.size != 0) {
                var gameEntity: GameEntity?
                for (location in locationList) {
                    if (location < mInstallGameViewModel.gameListLiveData.value?.size ?: 0) {
                        gameEntity = mInstallGameViewModel.gameListLiveData.value?.get(location)
                        if (gameEntity != null) {
                            DownloadItemUtils.processDate(
                                gameEntity,
                                downloadEntity,
                                mAdapter,
                                location
                            )
                        }
                    }
                }
            }
        }
    }

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

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        mInstallGameViewModel = ViewModelProvider(this).get(InstalledGameViewModel::class.java)
        mBinding.reuseNoneData.reuseNoneData.visibility = View.GONE
        mSkeleton = Skeleton.bind(mBinding.listSkeleton).shimmer(false)
            .load(R.layout.activity_install_skeleton).show()

        mBinding.fmInstallRvShow.layoutManager = FixLinearLayoutManager(requireContext())
        (mBinding.fmInstallRvShow.itemAnimator as DefaultItemAnimator).supportsChangeAnimations =
            false
        mAdapter = NewInstalledGameFragmentAdapter(requireContext(), mInstallGameViewModel)
        mExposureListener = ExposureListener(this, mAdapter!!)
        mBinding.fmInstallRvShow.addItemDecoration(
            VerticalItemDecoration(
                requireContext(),
                8F,
                true
            ).apply { mItemDecoration = this })
        mBinding.fmInstallRvShow.addOnScrollListener(mExposureListener!!)
        mBinding.fmInstallRvShow.adapter = mAdapter

        mPackageViewModel =
            ViewModelProvider(this, PackageViewModel.Factory()).get(PackageViewModel::class.java)
        mPackageViewModel?.getGameInstalledLiveData()?.observe(
            this
        ) { gameInstalls ->
            mInstallGameViewModel.initData(
                PackagesManager.filterSameApk(
                    PackagesManager.filterDownloadBlackPackage(gameInstalls as MutableList<GameInstall>?)
                )
            )
        }
        mInstallGameViewModel.gameListLiveData.observe(this) {
            mSkeleton?.hide()
            if (!it.isNullOrEmpty()) {
                mBinding.fmInstallRvShow.visibility = View.VISIBLE
                mBinding.reuseNoneData.reuseNoneData.visibility = View.GONE
                mAdapter?.submitList(it)
            } else {
                mBinding.fmInstallRvShow.visibility = View.GONE
                mBinding.reuseNoneData.reuseNoneData.visibility = View.VISIBLE
                mBinding.reuseNoneData.reuseNoneData.setBackgroundColor(R.color.background_white.toColor(requireContext()))
            }
        }
    }

    private fun updateNoDataView() {
        val layoutParam = mBinding.reuseNoneData.reuseResetLoadTv.layoutParams
        layoutParam.width = DisplayUtils.dip2px(150F)
        mBinding.reuseNoneData.reuseResetLoadTv.layoutParams = layoutParam
        mBinding.reuseNoneData.reuseResetLoadTv.visibility = View.VISIBLE
        mBinding.reuseNoneData.reuseNoneDataTv.text = getString(R.string.game_no_data)
        mBinding.reuseNoneData.reuseNoneDataDescTv.visibility = View.VISIBLE
        mBinding.reuseNoneData.reuseNoneDataDescTv.text = getString(R.string.game_no_data_desc)
        mBinding.reuseNoneData.reuseResetLoadTv.text = "去首页看看"
        mBinding.reuseNoneData.reuseResetLoadTv.setOnClickListener {
            MainActivity.skipToMainActivity(requireContext(), MainWrapperFragment.INDEX_HOME)
        }

        mBinding.run {
            if (PermissionHelper.isGetInstalledListPermissionDisabled(requireContext())) {
                reuseNoneData.reuseNoneDataIv.visibility = View.GONE
                reuseNoneData.reuseNoneDataTv.text = "开启应用列表权限"
                reuseNoneData.reuseNoneDataDescTv.text = " 及时获悉游戏最新的更新消息"
                reuseNoneData.reuseResetLoadTv.text = "去开启"
                reuseNoneData.reuseResetLoadTv.setOnClickListener {
                    PermissionHelper.checkGetInstalledAppsListBeforeAction(
                        requireActivity(),
                        object : EmptyCallback {
                            override fun onCallback() {
                                updateNoDataView()
                                PackageRepository.initData()
                            }
                        })
                }
            } else {
                reuseNoneData.reuseNoneDataIv.visibility = View.VISIBLE
                reuseNoneData.reuseNoneDataTv.text = getString(R.string.game_no_data)
                reuseNoneData.reuseNoneDataDescTv.text = getString(R.string.game_no_data_desc)
                reuseNoneData.reuseResetLoadTv.setOnClickListener {
                    MainActivity.skipToMainActivity(activity, MainWrapperFragment.INDEX_HOME)
                }
            }
        }
    }

    override fun getLayoutId(): Int = 0

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

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

    // 打开下载按钮事件
    @SuppressLint("NotifyDataSetChanged")
    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onEventMainThread(reuse: EBReuse) {
        if (("Refresh" == reuse.type || "PlatformChanged" == reuse.type) && mAdapter != null) {
            mAdapter?.notifyDataSetChanged()
        }
    }

    //下载被删除事件
    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onEventMainThread(status: EBDownloadStatus) {
        if ("delete" == status.status) {
            DownloadManager.getInstance()
                .removePlatform(status.name, status.platform)
            val locationList = mInstallGameViewModel.locationMap[status.packageName]
            var gameEntity: GameEntity?
            if (locationList != null && locationList.size != 0) {
                val gameList = mInstallGameViewModel.gameListLiveData.value
                for (location in locationList) {
                    gameEntity = gameList?.get(location)
                    gameEntity?.getEntryMap()?.remove(status.platform)
                }
                mInstallGameViewModel.gameListLiveData.postValue(gameList)
            }
        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onEventMainThread(packageEb: EBPackage) {
        if (packageEb.isInstalledOrUninstalled()) {
            mInstallGameViewModel.initData(
                PackagesManager.filterSameApk(
                    PackagesManager.filterDownloadBlackPackage(mPackageViewModel?.getGameInstalledLiveData()?.value as MutableList<GameInstall>?)
                )
            )
        }
    }

    override fun onDarkModeChanged() {
        super.onDarkModeChanged()
        mBinding.root.setBackgroundColor(R.color.background.toColor(requireContext()))
        mBinding.reuseNoneData.reuseNoneData.setBackgroundColor(R.color.background_white.toColor(requireContext()))
        mBinding.reuseNoneData.reuseNoneDataTv.setTextColor(R.color.text_title.toColor(requireContext()))
        mBinding.reuseNoneData.reuseNoneDataDescTv.setTextColor(R.color.text_subtitleDesc.toColor(requireContext()))
        mBinding.reuseNoneData.reuseNoneDataIv.setImageResource(R.drawable.ic_empty_data)
        mAdapter?.let { it.notifyItemRangeChanged(0, it.itemCount) }
        mBinding.fmInstallRvShow.run {
            mItemDecoration?.let { removeItemDecoration(it) }
            addItemDecoration(VerticalItemDecoration(requireContext(), 8F, true).apply { mItemDecoration = this })
        }
    }
}