package com.gh.gamecenter.packagehelper

import android.annotation.SuppressLint
import com.gh.gamecenter.common.retrofit.BiResponse
import com.gh.gamecenter.common.utils.toRequestBody
import com.gh.gamecenter.common.utils.tryWithDefaultCatch
import com.gh.gamecenter.entity.PackageFilter
import com.gh.gamecenter.retrofit.RetrofitManager
import com.gh.gamecenter.room.AppDatabase
import io.reactivex.schedulers.Schedulers

object PackageFilterManager {

    private var mPackageKey = "" // 用于下次获取包名-游戏信息的 key
    private val mPendingPackageNameSet by lazy { hashSetOf<String>() } // 因遇到异常而等待下次操作更新的包名列表
    private val mValidPackageNameSet by lazy { hashSetOf<String>() } // 已被收录的游戏包名列表

    val packageKey: String
        get() = mPackageKey

    /**
     * 更新收录游戏的包名列表
     * @param packageList 列表
     * @param appendOnly 是否仅添加部分数据，不清空旧数据
     * @param callbackClosure 结果回调
     */
    @SuppressLint("CheckResult")
    fun updateFilterPackages(
        packageList: MutableList<String>,
        appendOnly: Boolean = true,
        callbackClosure: ((list: ArrayList<String>) -> Unit)? = null
    ) {
        if (appendOnly) {
            // 添加因为异常而没能正常更新的包名列表
            packageList.addAll(mPendingPackageNameSet)
        }

        RetrofitManager.getInstance()
            .newApi
            .postInstalledAppList(packageList.toRequestBody())
            .subscribeOn(Schedulers.io())
            .subscribe(object : BiResponse<PackageFilter>() {
                override fun onSuccess(data: PackageFilter) {
                    mPackageKey = data.key
                    mPendingPackageNameSet.clear()

                    val partialPackageList = arrayListOf<String>()

                    if (!appendOnly) {
                        mValidPackageNameSet.clear()
                        tryWithDefaultCatch {
                            AppDatabase.getInstance().packageFilterDao().deleteAllPackageName()
                        }
                    }

                    for (packageName in data.packages) {
                        tryWithDefaultCatch {
                            AppDatabase.getInstance().packageFilterDao().addPackageName(
                                FilterPackageNameEntity(packageName)
                            )
                        }

                        partialPackageList.add(packageName)
                        mValidPackageNameSet.add(packageName)
                    }

                    if (appendOnly) {
                        callbackClosure?.invoke(ArrayList(partialPackageList))
                    } else {
                        callbackClosure?.invoke(ArrayList(mValidPackageNameSet))
                    }
                }

                override fun onFailure(exception: Exception) {
                    super.onFailure(exception)

                    if (appendOnly) {
                        mPendingPackageNameSet.addAll(packageList)
                    } else {
                        // 接口访问失败时从数据库读取上一次缓存的已安装收录列表进行更新
                        val packageEntityList =
                            AppDatabase.getInstance().packageFilterDao().getAllPackageName()
                        for (packageEntity in packageEntityList) {
                            mValidPackageNameSet.add(packageEntity.packageName)
                        }

                        callbackClosure?.invoke(ArrayList(mValidPackageNameSet))
                    }
                }
            })
    }

    /**
     * 该包名是否有效 （即是否已被光环收录）
     */
    fun isPackageValid(packageName: String): Boolean {
        return mValidPackageNameSet.contains(packageName)
    }

    /**
     * 是否存在因为接口异常而导致没有查询收录情况的包名列表
     */
    fun hasPendingPackage(): Boolean {
        return mPendingPackageNameSet.isEmpty()
    }

}