package com.gh.ndownload.suspendwindow.utils

import android.app.Activity
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Build
import android.provider.Settings
import com.gh.common.util.PackageChangeHelper
import com.gh.common.xapk.XapkInstaller
import com.gh.download.DownloadManager
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.utils.asVGame
import com.gh.gamecenter.common.utils.getExtension
import com.gh.gamecenter.common.utils.isLocalDownloadInDualDownloadMode
import com.gh.gamecenter.common.utils.isSimulatorDownload
import com.gh.gamecenter.common.utils.isSimulatorGame
import com.gh.gamecenter.core.utils.SPUtils
import com.gh.gamecenter.manager.PackagesManager
import com.gh.ndownload.suspendwindow.data.NDownloadState
import com.gh.vspace.VHelper
import com.lightgame.download.DownloadEntity
import com.lightgame.download.DownloadStatus

object NDownloadSuspendWindowHelper {

    const val PRIORITY_INSTALLED = -1

    const val PRIORITY_DOWNLOAD = 0

    const val PRIORITY_DOWNLOADING = 1

    const val PRIORITY_DOWNLOADED = 2

    const val PRIORITY_INSTALLING = 3

    private const val SP_KEY_DRAW_OVERLAY_PERMISSION_WINDOW_SHOWN = "draw_overlay_permission_window_shown"

    private var isRequestingPermission = false

    fun calculateDownloadCount(context: Context): Int =
        DownloadManager.getInstance().allDownloadEntityExcludeDoneTask.count { !shouldSkipDownloadEntity(context, it) }

    fun calculateDoneCount(context: Context): Int =
        DownloadManager.getInstance().allDownloadEntity.count { !shouldSkipDownloadEntity(context, it) }

    /**
     * 从下载列表中获取悬浮窗最优先显示的游戏实例
     */
    fun findPriorDownloadEntityFromDownloadList(context: Context): DownloadEntity? {
        val downloadList = DownloadManager.getInstance().allDownloadEntity
        if (downloadList.isEmpty()) return null

        var priorDownloadEntity: DownloadEntity? = null
        for (downloadEntity in downloadList) {
            val shouldSkipDownloadEntity = shouldSkipDownloadEntity(context, downloadEntity)
            val shouldUpdatePriorDownloadEntity = isIconDownloadPriorityHigher(downloadEntity, priorDownloadEntity)
            if (!shouldSkipDownloadEntity && shouldUpdatePriorDownloadEntity) {
                priorDownloadEntity = downloadEntity
            }
        }
        return priorDownloadEntity
    }

    /**
     * 获取当前下载的DownloadState实例
     * @param downloadEntity 当前下载实例
     */
    @JvmStatic
    fun getIconDownloadState(downloadEntity: DownloadEntity): NDownloadState? = when (downloadEntity.status) {
        DownloadStatus.done -> getIconInstallState(downloadEntity)
        DownloadStatus.downloading -> NDownloadState.Downloading(downloadEntity.percent.toInt())
        DownloadStatus.download, DownloadStatus.add, DownloadStatus.subscribe, DownloadStatus.waiting -> NDownloadState.Install
        DownloadStatus.pause -> NDownloadState.Pause
        DownloadStatus.cancel -> getIconInstalledState(downloadEntity)// 安装完成以后会回调一个cancel事件，因此需要在cancel回调里面判断是否已安装应用
        else -> null
    }

    /**
     * 获取当前安装的DownloadState实例
     * @param downloadEntity 当前安装实例
     */
    @JvmStatic
    fun getIconInstallState(downloadEntity: DownloadEntity): NDownloadState =
        if (PackageChangeHelper.isInstallPendingPackage(downloadEntity.packageName)) {
            NDownloadState.Installing
        } else {
            NDownloadState.Install
        }

    /**
     * 获取当前已安装的DownloadState实例
     * @param downloadEntity 当前安装实例
     */
    @JvmStatic
    fun getIconInstalledState(downloadEntity: DownloadEntity): NDownloadState? =
        if (PackagesManager.isInstalled(downloadEntity.packageName)) {
            NDownloadState.Complete
        } else {
            null
        }

    @JvmStatic
    fun getIconResumeState(downloadEntity: DownloadEntity): NDownloadState =
        if (PackagesManager.isInstalled(downloadEntity.packageName)) {
            NDownloadState.Complete
        } else {
            NDownloadState.Install
        }

    /**
     * 获取下载任务的悬浮窗优先级，优先级最高的任务的游戏Icon将显示在悬浮窗上
     * 1. PRIORITY_DOWNLOAD - 正在进行下载
     * 1. PRIORITY_DOWNLOADED - 仅下载完成
     * 2. PRIORITY_INSTALLING - 下载完成并且处于安装中
     * 3. PRIORITY_INSTALLED - 下载完成并且已安装
     */
    @JvmStatic
    fun getIconDownloadPriority(downloadEntity: DownloadEntity): Int =
        if (PackagesManager.isInstalled(downloadEntity.packageName)) {
            PRIORITY_INSTALLED
        } else if (PackageChangeHelper.isInstallPendingPackage(downloadEntity.packageName)) {
            PRIORITY_INSTALLING
        } else if (downloadEntity.status == DownloadStatus.done) {
            PRIORITY_DOWNLOADED
        } else if (downloadEntity.status == DownloadStatus.downloading) {
            PRIORITY_DOWNLOADING
        } else {
            PRIORITY_DOWNLOAD
        }

    fun isIconDownloadPriorityHigher(a: DownloadEntity, b: DownloadEntity?): Boolean =
        b == null || compareToIconDownloadPriority(a, b) > 0

    /**
     * 对比两个下载实体的悬浮窗优先级
     */
    @JvmStatic
    fun compareToIconDownloadPriority(a: DownloadEntity, b: DownloadEntity): Int {
        val aPriority = getIconDownloadPriority(a)
        val bPriority = getIconDownloadPriority(b)
        return if (aPriority != bPriority) {
            aPriority - bPriority
        } else {
            (b.start - a.start).toInt()
        }
    }

    @JvmStatic
    fun canDrawOverLayer(context: Context): Boolean =
        Build.VERSION.SDK_INT < Build.VERSION_CODES.M || Settings.canDrawOverlays(context)

    @JvmStatic
    fun requestDrawOverlayPermission(activity: Activity, requestCode: Int, source: String) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            isRequestingPermission = true
            activity.startActivityForResult(
                Intent(
                    Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
                    Uri.parse("package:${activity.packageName}")
                ),
                requestCode
            )
        }
        setDownloadSuspendWindowFirstShownSource(source = source)
    }

    @JvmStatic
    fun doneRequestingPermission() {
        isRequestingPermission = false
    }

    @JvmStatic
    fun isRequestingPermission(): Boolean {
        return isRequestingPermission
    }

    @JvmStatic
    fun shouldSkipDownloadEntity(context: Context, downloadEntity: DownloadEntity): Boolean =
        downloadEntity.packageName == context.packageName
                || downloadEntity.packageName == VHelper.DEFAULT_VSPACE_PACKAGENAME
                || downloadEntity.packageName == VHelper.VSPACE_32BIT_PACKAGENAME
                || downloadEntity.path.getExtension() == XapkInstaller.XAPK_EXTENSION_NAME
                || downloadEntity.asVGame()
                || downloadEntity.isPluggable
                || downloadEntity.isSimulatorDownload()
                || downloadEntity.isSimulatorGame()
                || downloadEntity.isLocalDownloadInDualDownloadMode()

    @JvmStatic
    fun isDrawOverlayPermissionWindowShown(): Boolean =
        SPUtils.getBoolean(SP_KEY_DRAW_OVERLAY_PERMISSION_WINDOW_SHOWN, false)

    @JvmStatic
    fun markDrawOverlayPermissionWindowShown() {
        SPUtils.setBoolean(SP_KEY_DRAW_OVERLAY_PERMISSION_WINDOW_SHOWN, true)
    }

    fun isDownloadSuspendWindowFirstShown(): Boolean =
        SPUtils.getBoolean(Constants.SP_DOWNLOAD_SUSPEND_WINDOW_FIRST_SHOWN, false)

    fun markDownloadSuspendWindowFirstShown() {
        SPUtils.setBoolean(Constants.SP_DOWNLOAD_SUSPEND_WINDOW_FIRST_SHOWN, true)
    }

    fun setDownloadSuspendWindowFirstShownSource(source: String) {
        if (isDownloadSuspendWindowFirstShown()) return
        SPUtils.setString(Constants.SP_DOWNLOAD_SUSPEND_WINDOW_FIRST_SHOWN_SOURCE, source)
    }

    fun getDownloadSuspendWindowFirstShownSource(): String =
        SPUtils.getString(Constants.SP_DOWNLOAD_SUSPEND_WINDOW_FIRST_SHOWN_SOURCE, "其他") ?: "其他"
}