package com.gh.download

import android.annotation.SuppressLint
import android.text.TextUtils
import com.gh.common.util.ConcernUtils
import com.gh.common.util.DataCollectionUtils
import com.gh.common.util.PackageInstaller
import com.gh.common.util.PackageUtils
import com.gh.download.server.BrowserInstallHelper
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.loghub.LoghubUtils
import com.gh.gamecenter.common.retrofit.EmptyResponse
import com.gh.gamecenter.common.retrofit.Response
import com.gh.gamecenter.common.utils.isVGame
import com.gh.gamecenter.core.runOnIoThread
import com.gh.gamecenter.core.utils.SPUtils
import com.gh.gamecenter.core.utils.ThirdPartyPackageHelper
import com.gh.gamecenter.core.utils.UrlFilterUtils
import com.gh.gamecenter.entity.GameDigestEntity
import com.gh.gamecenter.eventbus.EBPackage
import com.gh.gamecenter.login.user.UserManager
import com.gh.gamecenter.packagehelper.PackageRepository
import com.gh.gamecenter.packagehelper.PackageViewModel
import com.gh.gamecenter.retrofit.RetrofitManager
import com.halo.assistant.HaloApp
import com.lightgame.download.DownloadEntity
import com.lightgame.download.FileUtils
import com.lightgame.utils.Utils
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
import okhttp3.MediaType
import okhttp3.RequestBody
import org.json.JSONException
import org.json.JSONObject

object PackageObserver {

    private val mPackageViewModel: PackageViewModel
            by lazy { PackageViewModel(HaloApp.getInstance().application, PackageRepository) }

    private val mPackageChangeListenerList: ArrayList<PackageChangeListener> = arrayListOf()

    fun registerPackageChangeChangeListener(listener: PackageChangeListener) {
        mPackageChangeListenerList.add(listener)
    }

    fun unregisterPackageChangeChangeListener(listener: PackageChangeListener) {
        mPackageChangeListenerList.remove(listener)
    }

    @JvmStatic
    fun onPackageChanged(busFour: EBPackage) {
        val application = HaloApp.getInstance().application
        val packageName = busFour.packageName
        val versionName = busFour.versionName
        val preciseGameId = busFour.gameId

        var gameId = ""
        var mDownloadEntity: DownloadEntity? = null

        var approximateGameId = "" // 模糊的 gameId
        var foundMatchedGame = false  // 是否找到準確的遊戲 (有可能出現同包名同版本的情況)

        for (downloadEntity in DownloadManager.getInstance().allDownloadEntity) {
            if (packageName == downloadEntity.packageName
                && (preciseGameId == null || preciseGameId == downloadEntity.gameId)
            ) {
                mDownloadEntity = downloadEntity
                gameId = mDownloadEntity.gameId
                if (TextUtils.isEmpty(busFour.versionName)) {
                    // 没有版本号的事件直接选用第一个找到的 downloadEntity
                    foundMatchedGame = true
                    break
                } else {
                    // 直接選擇安裝位置一樣的
                    if (downloadEntity.path == HaloApp.get(Constants.LAST_INSTALL_GAME, false)) {
                        foundMatchedGame = true
                        break
                    }

                    // 有版本号的事件直接尽量找到版本一致的 downloadEntity
                    if (versionName == downloadEntity.versionName) {
                        approximateGameId = gameId
                    }
                }
            }
        }

        if (!foundMatchedGame && approximateGameId.isNotEmpty()) {
            gameId = approximateGameId
        }

        if (EBPackage.TYPE_INSTALLED == busFour.type) {
            mPackageViewModel.addInstalledGame(packageName)

            BrowserInstallHelper.onApkInstalled(mDownloadEntity?.path)

            if (mDownloadEntity != null) {
                // 没有光环 ID 的都记录一下游戏 ID，供'我的游戏'区分同包名不同插件用
                val gh_id = PackageUtils.getMetaData(application, mDownloadEntity.packageName, "gh_id")
                if (gh_id == null) {
                    ThirdPartyPackageHelper.saveGameId(mDownloadEntity.packageName, mDownloadEntity.gameId)
                }
                if (mDownloadEntity.isVGame()) {
                    // 畅玩游戏安装完成的同时直接删除文件
                    runOnIoThread { FileUtils.deleteFile(mDownloadEntity.path) }
                }

                DownloadManager.getInstance().cancel(mDownloadEntity.url, false, true, false)

                if (SPUtils.getBoolean(Constants.SP_CONCERN_GAME, true)) { //设置页面控制是否安装后自动关注
                    // 安装后关注游戏
                    val finalDownloadEntity = mDownloadEntity
                    RetrofitManager.getInstance().api
                        .getGameDigestByPackageName(UrlFilterUtils.getFilterQuery("package", packageName))
                        .subscribeOn(Schedulers.io())
                        .observeOn(AndroidSchedulers.mainThread())
                        .subscribe(object : Response<List<GameDigestEntity?>?>() {
                            override fun onResponse(response: List<GameDigestEntity?>?) {
                                for (gameDigestEntity in response!!) {
                                    if (!TextUtils.isEmpty(gameDigestEntity?.id)) { // 关注游戏
                                        if (gameDigestEntity?.id == finalDownloadEntity.gameId) {
                                            ConcernUtils.postConcernGameId(
                                                application,
                                                gameDigestEntity?.id ?: "",
                                                null,
                                                false
                                            )
                                        }
                                    }
                                }
                            }
                        })
                }
            }

            runOnIoThread { postNewlyInstalledApp(gameId, packageName) }
        }

        if ("卸载" == busFour.type) {
            mPackageViewModel.addUninstalledGame(packageName)
            mDownloadEntity?.let {
                if (it.isVGame()) return@let

                if (it.isPluggable || it.isUpdate) {
                    PackageInstaller.install(application, mDownloadEntity)
                }
            }

            // 更新已安装游戏
            deleteInstalledPackage(packageName)
        }

        for (packageChangeListener in mPackageChangeListenerList) {
            packageChangeListener.onChanged(busFour)
        }

        DataCollectionUtils.uploadInorunstall(application, busFour.type, busFour.packageName)
    }

    @SuppressLint("CheckResult")
    private fun postNewlyInstalledApp(gameId: String, packageName: String) {

        // 发送应用变更前都检查一下是否需要把所有应用都上传
        PackageRepository.checkAndUploadAppList()

        // 更新已安装游戏
        val packageObject = PackageUtils.getAppBasicInfoByPackageName(packageName)
        val dataObject = JSONObject()
        val wrapperObject = JSONObject()
        try {
            dataObject.put("type", "POST")
            dataObject.put("device_id", HaloApp.getInstance().gid)
            dataObject.put("app", packageObject)
            dataObject.put("time", Utils.getTime(HaloApp.getInstance().application))
            wrapperObject.put("content", dataObject.toString())
        } catch (e: JSONException) {
            e.printStackTrace()
        }
        LoghubUtils.log(wrapperObject, "halo-api-device-installed", true)
        if (!TextUtils.isEmpty(gameId) && UserManager.getInstance().isLoggedIn) {
            val jsonObject = JSONObject()
            try {
                jsonObject.put("game_id", gameId)
                jsonObject.put("package", packageName)
                val rBody = RequestBody.create(MediaType.parse("application/json"), jsonObject.toString())
                RetrofitManager.getInstance().api
                    .postPlayedGame(UserManager.getInstance().userId, rBody)
                    .subscribeOn(Schedulers.io())
                    .observeOn(Schedulers.io())
                    .subscribe(EmptyResponse())
            } catch (e: JSONException) {
                e.printStackTrace()
            }
        }

    }

    @SuppressLint("CheckResult")
    private fun deleteInstalledPackage(packageName: String) {

        // 发送应用变更前都检查一下是否需要把所有应用都上传
        PackageRepository.checkAndUploadAppList()

        // 删除已安装游戏
        val dataObject = JSONObject()
        val wrapperObject = JSONObject()
        try {
            dataObject.put("type", "DELETE")
            dataObject.put("device_id", HaloApp.getInstance().gid)
            dataObject.put("package", packageName)
            dataObject.put("time", Utils.getTime(HaloApp.getInstance().application))
            wrapperObject.put("content", dataObject.toString())
        } catch (e: JSONException) {
            e.printStackTrace()
        }
        LoghubUtils.log(wrapperObject, "halo-api-device-installed", true)
    }

    fun interface PackageChangeListener {
        fun onChanged(data: EBPackage)
    }
}