package com.gh.gamecenter.download

import android.view.View
import com.gh.common.exposure.ExposureListener
import com.gh.download.DownloadManager
import com.gh.gamecenter.MainActivity
import com.gh.gamecenter.R
import com.gh.gamecenter.common.base.fragment.LazyFragment
import com.gh.gamecenter.common.constant.EntranceConsts
import com.gh.gamecenter.common.eventbus.EBReuse
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.common.view.FixLinearLayoutManager
import com.gh.gamecenter.core.utils.DisplayUtils
import com.gh.gamecenter.core.utils.EmptyCallback
import com.gh.gamecenter.databinding.FragmentGameUpdatableBinding
import com.gh.gamecenter.eventbus.EBDownloadStatus
import com.gh.gamecenter.fragment.MainWrapperFragment
import com.gh.gamecenter.packagehelper.PackageRepository
import com.gh.gamecenter.packagehelper.PackageViewModel
import com.lightgame.download.DataWatcher
import com.lightgame.download.DownloadEntity
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode

class UpdatableGameFragment : LazyFragment() {

    private var mViewModel: UpdatableGameViewModel? = null
    private var mPackageViewModel: PackageViewModel? = null
    private var mBinding: FragmentGameUpdatableBinding? = null
    private var mAdapter: UpdatableGameAdapter? = null

    private val dataWatcher = object : DataWatcher() {
        override fun onDataChanged(downloadEntity: DownloadEntity) {
            mAdapter?.notifyItemByDownload(downloadEntity)
        }

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


    override fun getRealLayoutId() = R.layout.fragment_game_updatable
    override fun onRealLayoutInflated(inflatedView: View) {
        mBinding = FragmentGameUpdatableBinding.bind(inflatedView)
    }

    override fun onFragmentFirstVisible() {
        val packageName = activity?.intent?.getStringExtra(EntranceConsts.KEY_PACKAGENAME) ?: ""
        val entrance = activity?.intent?.getStringExtra(EntranceConsts.KEY_ENTRANCE) ?: ""

        mViewModel = viewModelProvider(UpdatableGameViewModel.Factory(packageName, entrance))

        super.onFragmentFirstVisible()

        mPackageViewModel = viewModelProvider(PackageViewModel.Factory())
        mPackageViewModel?.getGameUpdateIncludeCurrentVersion()
            ?.observeNonNull(viewLifecycleOwner) { updatableList ->
                mViewModel?.setUpdatableList(updatableList)
            }
        mViewModel?.updatableData?.observe(viewLifecycleOwner) {
            mAdapter?.submitList(it)
            mBinding?.noDataContainer?.root?.goneIf(!it.isNullOrEmpty())
        }
    }

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

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

    override fun initRealView() {
        super.initRealView()

        mBinding?.run {
            mAdapter = UpdatableGameAdapter(mViewModel!!)
            recyclerView.itemAnimator = null
            recyclerView.layoutManager = FixLinearLayoutManager(requireContext())
            recyclerView.adapter = mAdapter?.also {
                recyclerView.addOnScrollListener(ExposureListener(this@UpdatableGameFragment, it))
            }

            updateNoDataView()
        }
    }

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

    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onEventMainThread(status: EBDownloadStatus) {
        if ("delete" == status.status || "download" == status.status || "done" == status.status) {
            mViewModel?.refreshList()
        }
    }

    // 更新平台信息
    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onEventMainThread(reuse: EBReuse) {
        if ("PlatformChanged" == reuse.type && isAdded) {
            mViewModel?.refreshList()
        }
    }

    override fun onDarkModeChanged() {
        super.onDarkModeChanged()
        mBinding?.recyclerView?.setBackgroundColor(R.color.background_white.toColor(requireContext()))
        mBinding?.noDataContainer?.reuseNoneDataTv?.setTextColor(R.color.text_title.toColor(requireContext()))
        mBinding?.noDataContainer?.reuseNoneDataDescTv?.setTextColor(R.color.text_subtitleDesc.toColor(requireContext()))
        mBinding?.noDataContainer?.reuseNoneDataIv?.setImageResource(R.drawable.ic_empty_data)
        mAdapter?.let { it.notifyItemRangeChanged(0, it.itemCount) }
    }
}