package com.gh.gamecenter.feature.view.dialog

import android.annotation.SuppressLint
import android.app.Application
import android.content.pm.ApplicationInfo
import android.content.pm.PackageManager
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.MutableLiveData
import com.therouter.TheRouter
import com.gh.gamecenter.common.constant.RouteConsts
import com.gh.gamecenter.common.retrofit.Response
import com.gh.gamecenter.common.utils.BitmapUtils
import com.gh.gamecenter.common.utils.singleToMain
import com.gh.gamecenter.core.provider.IPackageUtilsProvider
import com.gh.gamecenter.feature.entity.InstallGameEntity
import com.gh.gamecenter.feature.provider.IVHelperProvider
import com.gh.gamecenter.feature.retrofit.RetrofitManager
import io.reactivex.Observable
import io.reactivex.ObservableEmitter
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
import java.io.File

class SelectGameViewModel(application: Application) : AndroidViewModel(application) {
    private val mApi = RetrofitManager.getInstance().newApi
    private val mApkList = arrayListOf<InstallGameEntity>()
    private val mAccurateFilterPackageNameSet = hashSetOf<String>()
    private val mFuzzyFilterPackageNameSet = hashSetOf<String>()

    val gameListLiveData = MutableLiveData<List<InstallGameEntity>>()

    init {
        getFilterPackageNameList()
    }

    @SuppressLint("CheckResult")
    private fun getFilterPackageNameList() {
        mApi.getFeedbackFilterPackages()
            .compose(singleToMain())
            .subscribe({ list ->
                mFuzzyFilterPackageNameSet.clear()
                mAccurateFilterPackageNameSet.clear()
                list.forEach {
                    if (it.matchMode == "fuzzy") {
                        mFuzzyFilterPackageNameSet.addAll(it.packages)
                    } else if (it.matchMode == "accurate") {
                        mAccurateFilterPackageNameSet.addAll(it.packages)
                    }
                }
                getInstalledGameList()
            }, {
                it.printStackTrace()
                getInstalledGameList()
            })
    }

    private fun shouldThisPackageBeFiltered(packageName: String) = mAccurateFilterPackageNameSet.contains(packageName) || isMatchFuzzyList(packageName)

    private fun isMatchFuzzyList(packageName: String): Boolean {
        mFuzzyFilterPackageNameSet.forEach {
            if (packageName.contains(it)) {
                return true
            }
        }
        return false
    }

    private fun getInstalledGameList() {
        Observable
            .create<Any?> { emitter: ObservableEmitter<Any?> ->
                mApkList.clear()
                val pm: PackageManager = getApplication<Application?>().applicationContext.packageManager
                val packageUtilsConfig = TheRouter.get(IPackageUtilsProvider::class.java)
                val installedPackages =
                    packageUtilsConfig?.getInstalledPackages(getApplication(), 0) ?: listOf()
                for (installedPackage in installedPackages) {
                    if ((installedPackage.applicationInfo.flags and ApplicationInfo.FLAG_SYSTEM == 0) && !shouldThisPackageBeFiltered(installedPackage.packageName)) {
                        val installGameEntity = InstallGameEntity()
                        installGameEntity.gamePath = installedPackage.applicationInfo.sourceDir
                        try {
                            val drawable = installedPackage.applicationInfo.loadIcon(pm)
                            installGameEntity.gameBm = BitmapUtils.drawableIconToBitmapIconWithDownsampling(drawable, true)
                            installGameEntity.gameVersion = installedPackage.versionName
                            installGameEntity.gameName = installedPackage.applicationInfo.loadLabel(pm).toString()
                            installGameEntity.packageName = installedPackage.packageName
                            installGameEntity.versionCode = installedPackage.versionCode
                            if (installGameEntity.gamePath != null && installGameEntity.gamePath!!.isNotEmpty()) {
                                val dot = installGameEntity.gamePath!!.lastIndexOf('.')
                                if (dot > -1 && (dot < installGameEntity.gamePath!!.length - 1)) {
                                    installGameEntity.format = installGameEntity.gamePath!!.substring(dot + 1)
                                }
                            }
                            val file = File(installedPackage.applicationInfo.sourceDir)
                            installGameEntity.gameSize = file.length()
                            mApkList.add(installGameEntity)
                        } catch (ignore: Exception) {
                        }
                    }
                }

                val vHelperProvider = TheRouter.get(IVHelperProvider::class.java)
                if (vHelperProvider?.isVGameOn() == true) {
                    vHelperProvider.getAllInstalledVGameEntity().forEach {
                        if (!shouldThisPackageBeFiltered(it.packageName ?: "")) {
                            mApkList.add(it)
                        }
                    }
                }
                emitter.onComplete()
            }
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(object : Response<Any?>() {
                override fun onComplete() {
                    super.onComplete()
                    gameListLiveData.postValue(mApkList)
                }
            })
    }
}