package com.gh.common.util

import androidx.lifecycle.DefaultLifecycleObserver
import androidx.lifecycle.LifecycleOwner
import com.gh.common.dialog.AccelerateExpirationDialogFragment
import com.gh.download.DownloadManager
import com.gh.download.PackageObserver
import com.gh.gamecenter.DownloadManagerActivity
import com.gh.gamecenter.R
import com.gh.gamecenter.common.utils.NewFlatLogUtils
import com.gh.gamecenter.common.utils.SensorsBridge
import com.gh.gamecenter.core.provider.IAcceleratorProvider
import com.gh.gamecenter.core.utils.CurrentActivityHolder
import com.gh.gamecenter.eventbus.EBPackage
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.hud.HeadUpDisplayHelper
import com.gh.gamecenter.hud.HeadUpDisplayLogHelper
import com.gh.gamecenter.manager.PackagesManager
import com.gh.gamecenter.packagehelper.PackageRepository
import com.halo.assistant.HaloApp
import com.halo.assistant.accelerator.repository.AcceleratorDataHolder

import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.utils.getMetaExtra
import com.gh.gamecenter.dsp.DspReportHelper
import com.lightgame.utils.Utils
import com.therouter.TheRouter
import org.greenrobot.eventbus.EventBus

object PackageChangeHelper : DefaultLifecycleObserver {

    private const val TAG = "PackageChangeHelper"

    private const val INSTALL_PENDING = 1
    private const val UNINSTALL_PENDING = 2
    private const val UPDATE_PENDING = 3

    // <包名，pending 类型，应用版本，光环ID> 的 pending 集合
    private var pendingPackageMap: HashMap<String, PackageEntity> = hashMapOf()

    private var pendingHUDShowed: Boolean = false

    private var isLaunching = true

    /**
     * 添加一个等待中，待确定是否已成功安装的应用
     */
    fun addInstallPendingPackage(packageName: String) {
        val installData = PackagesManager.getInstalledData(packageName)

        if (installData == null) {
            Utils.log(TAG, "添加了: $packageName 包名等待安装成功")

            pendingHUDShowed = false
            pendingPackageMap[packageName] = PackageEntity(packageName, INSTALL_PENDING, "")
        } else {
            Utils.log(TAG, "添加了: $packageName 包名等待安装更新成功")

            // 记录光环插件相关信息，用于安装成功后的处理
            val ghId = PackageUtils.getGhId(packageName)?.toString() ?: ""

            pendingHUDShowed = false
            pendingPackageMap[packageName] =
                PackageEntity(packageName, UPDATE_PENDING, installData.version, ghId)
        }
    }

    fun isInstallPendingPackage(packageName: String): Boolean {
        return pendingPackageMap[packageName]?.packageName == packageName
    }

    /**
     * 添加一个等待中，待确定是否已成功卸载的应用
     */
    fun addUninstallPendingPackage(packageName: String) {
        Utils.log(TAG, "添加了: $packageName 包名等待卸载成功")
        pendingPackageMap[packageName] = PackageEntity(packageName, UNINSTALL_PENDING, "")
    }

    override fun onCreate(owner: LifecycleOwner) {
        super.onCreate(owner)
        isLaunching = true
    }

    override fun onResume(owner: LifecycleOwner) {
        super.onResume(owner)

        if (pendingPackageMap.size > 0) {
            calculateAndDispatchPackageChanges()
        }

        refreshVipStatus()
    }

    /**
     * 应用从后台切到前台，如果是登录状态，需要刷新用户的vip状态
     */
    private fun refreshVipStatus() {
        val iAcceleratorProvider = TheRouter.get(IAcceleratorProvider::class.java)
        if (iAcceleratorProvider?.hasToken() == true &&
            AcceleratorDataHolder.instance.enableRefresh &&
            AcceleratorDataHolder.instance.vipEntity != null &&
            !isLaunching
        ) {
            iAcceleratorProvider.loadQyUserPermissionData {
                val vip = AcceleratorDataHolder.instance.vipEntity
                if (vip != null && !vip.vipStatus && !vip.isNewUser && !vip.isVipRefundUser && !vip.isDurationRefundUser) {
                    // 获取当前
                    val currentActivity = CurrentActivityHolder.getCurrentActivity()
                    val reminder = AccelerateExpirationDialogFragment.ExpirationReminder.TimeRunsOut("")
                    if (currentActivity != null && HaloApp.getInstance().isRunningForeground) {
                        AccelerateExpirationDialogFragment.checkDialogShown(currentActivity, reminder)
                    }

                }
            }
        }
    }

    /**
     * 计算并分发包名的安装状态
     */
    private fun calculateAndDispatchPackageChanges() {
        val completeList = arrayListOf<PackageEntity>()
        val pendingHudPackageList = arrayListOf<String>()

        for (packageEntity in pendingPackageMap.values) {
            val packageName = packageEntity.packageName
            val pendingVersion = packageEntity.version
            val pendingGhId = packageEntity.ghId

            val installedVersionName = PackageUtils.getVersionNameByPackageName(packageName)
            val isInstalled = installedVersionName != null

            if (packageEntity.isInstallPending()) {
                if (isInstalled) {
                    completeList += packageEntity

                    PackageRepository.addInstalledGame(
                        PackageRepository.packageFilterManager,
                        packageName
                    )

                    // 添加到额外的包名白名单，下次启动同时查询此包的安装情况
                    PackageHelper.updateAdditionalWhiteListPackageName(
                        packageName = packageName,
                        isAdd = true
                    )

                    performInstallSuccessAction(packageName)
                } else {
                    // 任务不存在了，将等待更新安装结果的 packageEntity 置为 null
                    if (DownloadManager.getInstance()
                            .getDownloadEntitySnapshotByPackageName(packageName) == null
                    ) {
                        completeList += packageEntity
                    } else {
                        pendingHudPackageList.add(packageName)
                    }
                }
            } else if (packageEntity.isUninstallPending() && !isInstalled) {
                completeList += packageEntity

                // 从额外的包名白名单移除，下次启动时不再查询此包的安装情况
                PackageHelper.updateAdditionalWhiteListPackageName(
                    packageName = packageName,
                    isAdd = false
                )

                performUninstallSuccessAction(packageName)
            } else if (packageEntity.isUpdatePending()) {
                val isUpdateValid = if (installedVersionName != pendingVersion) {
                    true
                } else {
                    pendingGhId.isNotEmpty()
                            && pendingGhId != PackageUtils.getGhId(packageName).toString()
                }

                if (isUpdateValid) {
                    performUninstallSuccessAction(packageName)
                    performInstallSuccessAction(packageName)

                    completeList += packageEntity
                } else {
                    // 任务不存在了，将等待更新安装结果的 packageEntity 置为 null
                    if (DownloadManager.getInstance()
                            .getDownloadEntitySnapshotByPackageName(packageName) == null
                    ) {
                        completeList += packageEntity
                    } else {
                        pendingHudPackageList.add(packageName)
                    }
                }

                // 添加到额外的包名白名单，下次启动同时查询此包的安装情况
                PackageHelper.updateAdditionalWhiteListPackageName(
                    packageName = packageName,
                    isAdd = true
                )
            }
        }

        for (invalidPackage in completeList) {
            pendingPackageMap.remove(invalidPackage.packageName)
        }

        if (pendingHudPackageList.isNotEmpty()) {
            showHUDIfNeeded(pendingHudPackageList.last())
        }
    }

    override fun onStop(owner: LifecycleOwner) {
        super.onStop(owner)
        isLaunching = false
    }

    private fun showHUDIfNeeded(packageName: String) {
        if (pendingHUDShowed) return

        val downloadEntity =
            DownloadManager.getInstance().getDownloadEntitySnapshotByPackageName(packageName)
                ?: return
        if (downloadEntity.gameId == Constants.GHZS_GAME_ID) return
        val activity = CurrentActivityHolder.getCurrentActivity() ?: return
        if (activity is DownloadManagerActivity) return

        pendingHUDShowed = true
        HeadUpDisplayHelper.showHUD(
            activity,
            downloadEntity.icon ?: "",
            activity.getString(R.string.hud_has_pending_install_game),
            activity.getString(R.string.hud_head_to_download_manager),
            showingCallback = {
                HeadUpDisplayLogHelper.trackInstallationShow(downloadEntity, "游戏下载")
            },
            clickedCallback = {
                DirectUtils.directToDownloadManager(activity, "HUD")
                HeadUpDisplayLogHelper.trackInstallationClick(downloadEntity, "游戏下载")
            })
    }

    /**
     * 对外暴露的方法，用于添加一个安装成功的应用
     * @param packageName 包名
     * @param cachedGameEntity 缓存的 GameEntity，用于快速更新状态
     */
    fun addInstall(packageName: String, cachedGameEntity: GameEntity? = null) {
        performInstallSuccessAction(packageName, cachedGameEntity)
    }

    /**
     * 对外暴露的方法，用于添加一个卸载成功的应用
     * @param packageName 包名
     * @param cachedGameEntity 缓存的 GameEntity，用于快速更新状态
     */
    fun addUpdate(packageName: String, cachedGameEntity: GameEntity? = null) {
        performUninstallSuccessAction(packageName)
        performInstallSuccessAction(packageName, cachedGameEntity)
    }

    /**
     * 对应包名安装成功后的操作，继承至 PackageChangeBroadcastObserver
     * @param packageName 包名
     * @param cachedGameEntity 缓存的 GameEntity，用于快速更新状态
     * @param withLog 是否需要记录日志
     */
    private fun performInstallSuccessAction(
        packageName: String,
        cachedGameEntity: GameEntity? = null,
        withLog: Boolean = true,
    ) {
        Utils.log(TAG, "安装了: $packageName 包名的程序")
        val downloadEntity =
            DownloadManager.getInstance().getDownloadEntitySnapshotByPackageName(packageName)
        val gameId = downloadEntity?.gameId ?: ""
        val gameName = downloadEntity?.name ?: ""

        if (withLog && gameId.isNotEmpty()) {
            NewFlatLogUtils.logGameInstallComplete(gameId, gameName)
            SensorsBridge.trackInstallGameFinish(
                gameId,
                gameName,
                downloadEntity?.getMetaExtra(Constants.DSP_GAME) == "true",
                downloadEntity?.getMetaExtra(Constants.DSP_AD_ID) ?: ""
            )

            if (downloadEntity?.getMetaExtra(Constants.DSP_GAME) == "true") {
                DspReportHelper.report(downloadEntity.getMetaExtra(Constants.INSTALL_URL))
            }
        }

        InstallUtils.getInstance().removeInstall(packageName)
        PackageHelper.refreshLocalPackageList()

        val versionName = PackageUtils.getVersionNameByPackageName(packageName)
        val installEb = EBPackage(EBPackage.TYPE_INSTALLED, packageName, versionName)

        PackageObserver.onPackageChanged(installEb, cachedGameEntity)
        EventBus.getDefault().post(installEb)
    }

    fun addUninstall(packageName: String) {
        performUninstallSuccessAction(packageName)
    }

    /**
     * 对应包名卸载成功后的操作，继承至 PackageChangeBroadcastObserver
     */
    private fun performUninstallSuccessAction(packageName: String, withLog: Boolean = true) {
        Utils.log(TAG, "卸载了: $packageName 包名的程序")
        val install = PackagesManager.getInstalledData(packageName)
        val gameId = if (install?.id != null) install.id else ""
        val gameName = if (install?.name != null) install.name else ""

        if (withLog) {
            NewFlatLogUtils.logGameUninstallComplete(gameId!!, gameName!!)
            SensorsBridge.trackUnloadGameFinish(gameId, gameName)
        }

        InstallUtils.getInstance().removeUninstall(packageName)
        PackageHelper.refreshLocalPackageList()

        val uninstallEb = EBPackage(EBPackage.TYPE_UNINSTALLED, packageName, "")
        PackageObserver.onPackageChanged(uninstallEb)
        EventBus.getDefault().post(uninstallEb)
    }

    private class PackageEntity(
        val packageName: String,
        val type: Int,
        val version: String,
        val ghId: String = "",
    ) {
        fun isInstallPending(): Boolean {
            return type == INSTALL_PENDING
        }

        fun isUninstallPending(): Boolean {
            return type == UNINSTALL_PENDING
        }

        fun isUpdatePending(): Boolean {
            return type == UPDATE_PENDING
        }
    }

}