package com.gh.download.dialog

import android.app.Application
import androidx.lifecycle.*
import com.gh.common.constant.Config
import com.gh.common.util.PackageHelper
import com.gh.common.util.PackageUtils
import com.gh.download.DownloadManager
import com.gh.gamecenter.feature.entity.ApkEntity
import com.gh.gamecenter.feature.entity.GameCollectionEntity
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.feature.entity.Recommend
import com.gh.gamecenter.manager.PackagesManager
import com.halo.assistant.HaloApp
import com.lightgame.download.DownloadStatus
import java.util.*
import java.util.concurrent.ConcurrentHashMap
import kotlin.collections.ArrayList

/**
 * 已安装部分排序：安装插件化->安装更新->插件化下载中->更新下载中->插件化->更新->启动
 *
 * 其它部分排序：安装→下载中
 *
 * 注意：
 * 1.上述一级页面排序包含合集
 * 2.二级页面(合集详情),切勿打乱原有排序,按后台顺序显示
 */
class DownloadViewModel(application: Application, val gameEntity: GameEntity) : AndroidViewModel(application) {

    val listLiveData: MutableLiveData<List<DownloadDialogItemData>> = MutableLiveData()
    val collectionLiveData: MutableLiveData<GameCollectionEntity> = MutableLiveData()
    val dismissLiveData: MutableLiveData<Any> = MutableLiveData()

    private var mAllApkList: MutableList<ApkEntity> = ArrayList()
    private var mInstalledApkList: MutableList<ApkEntity> = ArrayList()
    private var mOtherApkList: MutableList<ApkEntity> = ArrayList()
    private var allPackageName: List<String>? = null
    var otherSectionPosition = -1

    init {
        getAllPackageName()
        if (gameEntity.pluggableCollection != null) {
            collectionLiveData.postValue(gameEntity.pluggableCollection)
        } else {
            initListData()
        }
    }

    fun getAllPackageName() {
        allPackageName = PackageHelper.getInstalledPackageNameList(HaloApp.getInstance(), 0)
    }

    fun initListData() {
        mAllApkList = ArrayList()
        mInstalledApkList = ArrayList()
        mOtherApkList = ArrayList()

        mergeApkCollection()
        mergeApkLink()

        mAllApkList.forEach { apk ->
            setSortValueToApkEntity(apk)

            val installed = if (apk.apkCollection != null) {
                var isInstalled = false
                apk.apkCollection?.saveApkEntity?.let {
                    for (entity in it) {
                        isInstalled = isInstalled(entity.packageName)
                        if (isInstalled) break
                    }
                }
                isInstalled
            } else {
                isInstalled(apk.packageName)
            }
            if (installed) {
                mInstalledApkList.add(apk)
            } else {
                mOtherApkList.add(apk)
            }
        }

        // 判断是否显示合集插件化提示
        mInstalledApkList.forEach { apk ->
            if (apk.apkCollection != null) {
                var hasPluggable = false
                var installedPlugin = false
                apk.apkCollection?.saveApkEntity?.forEach { collectionApk ->
                    if (PackageUtils.isCanPluggable(collectionApk)) {
                        hasPluggable = true
                    } else if (PackageUtils.getGhId(collectionApk.packageName) == gameEntity.id) {
                        installedPlugin = true
                    }
                    if (apk.apkCollection?.saveApkEntity?.last() == collectionApk) {
                        apk.apkCollection?.showPluggableHint = hasPluggable && !installedPlugin
                    }
                }
            }
        }

        mInstalledApkList.sortWith(Comparator { o1, o2 -> o2.order - o1.order })
        val count = mOtherApkList.count { it.recommend != null }
        if (count % 2 != 0) {
            mOtherApkList.add(ApkEntity(order = SORT_RECOMMEND_EMPTY, recommend = Recommend()))
        }
        mOtherApkList.sortWith(Comparator { o1, o2 -> o2.order - o1.order })

        val itemList: MutableList<DownloadDialogItemData> = ArrayList()

        val pluginLink = gameEntity.pluginLink
        if (pluginLink.isNotEmpty()) {
            itemList.add(DownloadDialogItemData(links = pluginLink))
        }

        if (mInstalledApkList.isNotEmpty()) {
            itemList.add(DownloadDialogItemData(section = DownloadDialogSectionType.INSTALLED))
        }

        mInstalledApkList.forEach { apk ->
            itemList.add(DownloadDialogItemData(installed = apk))
        }

        if (mOtherApkList.isNotEmpty()) {
            otherSectionPosition = itemList.size
            itemList.add(DownloadDialogItemData(section = DownloadDialogSectionType.OTHER))
        }

        mOtherApkList.forEach { apk ->
            itemList.add(DownloadDialogItemData(normal = apk))
        }

        itemList.add(DownloadDialogItemData(platformRequest = Any()))

        listLiveData.postValue(itemList)
    }

    fun setSortValueToApkEntity(apkEntity: ApkEntity) {
        if (apkEntity.apkCollection?.recommend != null) {
            apkEntity.recommend = apkEntity.apkCollection?.recommend
            apkEntity.order = getSortValue(apkEntity)
        } else {
            apkEntity.apkCollection?.saveApkEntity?.forEach { saveApk ->
                val sortValue = getSortValue(saveApk)
                if (apkEntity.order < sortValue) {
                    apkEntity.order = sortValue
                    apkEntity.recommend = saveApk.recommend
                    apkEntity.apkCollection?.recommend = saveApk.recommend
                }
            }
        }
        if (apkEntity.order == 0) {
            apkEntity.order = getSortValue(apkEntity)
        }
    }

    private fun getSortValue(apkEntity: ApkEntity): Int {
        val packageName = apkEntity.packageName
        if (apkEntity.recommend != null) {
            return SORT_RECOMMEND
        }
        val downloadEntity = DownloadManager.getInstance().getDownloadEntityByUrl(apkEntity.url)
        if (downloadEntity == null) {
            if (PackagesManager.isInstalled(packageName)) {
                when {
                    PackageUtils.isCanPluggable(apkEntity) -> {
                        return SORT_PLUGGABLE
                    }
                    PackageUtils.isCanUpdate(apkEntity, gameEntity.id) -> {
                        return SORT_UPDATE
                    }
                    PackageUtils.getGhId(packageName) == gameEntity.id -> {
                        return SORT_NORMAL_LAUNCH
                    }
                }
            }
            return SORT_NORMAL
        } else {
            return if (downloadEntity.status == DownloadStatus.done) {
                when {
                    downloadEntity.isPluggable -> SORT_PLUGGABLE_INSTALL
                    downloadEntity.isUpdate -> SORT_UPDATE_INSTALL
                    else -> SORT_NORMAL_INSTALL
                }
            } else {
                when {
                    downloadEntity.isPluggable -> SORT_PLUGGABLE_DOWNLOADING
                    downloadEntity.isUpdate -> SORT_UPDATE_DOWNLOADING
                    else -> SORT_NORMAL_DOWNLOADING
                }
            }
        }
    }


    private fun mergeApkCollection() {
        val gameCollectionApk = ArrayList<ApkEntity>()
        val hashMap = ConcurrentHashMap<String, Int>()
        var isCollection: Boolean

        for (apkEntity in gameEntity.getApk()) {
            isCollection = false
            for (gameCollectionEntity in gameEntity.collection) {
                for (packageName in gameCollectionEntity.packages) {
                    if (packageName == apkEntity.packageName) {
                        isCollection = true
                        val index = hashMap[gameCollectionEntity.name]
                        if (index != null) {
                            gameCollectionApk[index].apkCollection?.saveApkEntity?.add(apkEntity)
                        } else {
                            val newApkEntity = ApkEntity()
                            val saveApkList = ArrayList<ApkEntity>()
                            saveApkList.add(apkEntity)
                            gameCollectionEntity.saveApkEntity = saveApkList
                            newApkEntity.apkCollection = gameCollectionEntity
                            gameCollectionApk.add(newApkEntity)

                            hashMap[gameCollectionEntity.name] = gameCollectionApk.size - 1
                        }
                    }
                }
            }
            if (!isCollection) {
                gameCollectionApk.add(apkEntity)
            }
        }

        mAllApkList = gameCollectionApk
    }

    private fun mergeApkLink() {
        gameEntity.apkLink?.forEach { link ->
            val collection = link.collection
            if (collection.isNotEmpty()) {
                mAllApkList.forEach { apk ->
                    apk.apkCollection?.let { apkCollection ->
                        val saveApkEntity = apkCollection.saveApkEntity
                        if (saveApkEntity != null && collection == apkCollection.id) {
                            val element = ApkEntity()
                            element.apkLink = link
                            if (saveApkEntity.size > link.sort) {
                                saveApkEntity.add(link.sort, element)
                            } else {
                                saveApkEntity.add(element)
                            }
                        }
                    }
                }
            } else {
                val linkApkEntity = ApkEntity()
                linkApkEntity.apkLink = link
                if (mAllApkList.size > link.sort) {
                    mAllApkList.add(link.sort, linkApkEntity)
                } else {
                    mAllApkList.add(linkApkEntity)
                }
            }
        }
    }

    // 仅用于多平台面板的已安装判断
    private fun isInstalled(packageName: String): Boolean {
        val ghId = PackageUtils.getGhId(packageName)
        return (PackagesManager.isInstalled(packageName) || allPackageName?.contains(packageName) == true)
                && (ghId == null || ghId == gameEntity.id)
                && Config.getSettings()?.gameDownloadBlackList?.contains(packageName) != true
    }

    class Factory(val mApplication: Application, val gameEntity: GameEntity) : ViewModelProvider.NewInstanceFactory() {
        override fun <T : ViewModel> create(modelClass: Class<T>): T {
            return DownloadViewModel(mApplication, gameEntity) as T
        }
    }

    companion object {

        // 需要修改排序的话,只需要修改以下数值即可(由大到小排序)
        const val SORT_RECOMMEND = 12
        const val SORT_RECOMMEND_EMPTY = 11

        const val SORT_PLUGGABLE_INSTALL = 10
        const val SORT_PLUGGABLE_DOWNLOADING = 9
        const val SORT_PLUGGABLE = 8

        const val SORT_UPDATE_INSTALL = 7
        const val SORT_UPDATE_DOWNLOADING = 6
        const val SORT_UPDATE = 5

        const val SORT_NORMAL_INSTALL = 4
        const val SORT_NORMAL_DOWNLOADING = 3
        const val SORT_NORMAL_LAUNCH = 2
        const val SORT_NORMAL = 1
    }
}