package com.gh.common.util

import android.annotation.SuppressLint
import android.content.Context
import android.text.TextUtils
import androidx.appcompat.app.AppCompatActivity
import com.gh.common.DefaultJsApi
import com.gh.common.constant.Config
import com.gh.common.dialog.CertificationDialog
import com.gh.common.exposure.ExposureEvent
import com.gh.common.exposure.ExposureManager
import com.gh.common.exposure.ExposureSource
import com.gh.common.exposure.ExposureType
import com.gh.common.history.HistoryHelper
import com.gh.common.repository.ReservationRepository
import com.gh.common.simulator.NewSimulatorGameManager
import com.gh.common.simulator.SimulatorDownloadManager
import com.gh.common.simulator.SimulatorGameManager
import com.gh.download.DownloadManager
import com.gh.download.dialog.DownloadDialog
import com.gh.gamecenter.R
import com.gh.gamecenter.WebActivity
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.retrofit.ApiResponse
import com.gh.gamecenter.common.retrofit.EmptyResponse
import com.gh.gamecenter.common.retrofit.Response
import com.gh.gamecenter.common.utils.DataLogUtils
import com.gh.gamecenter.common.utils.DialogHelper
import com.gh.gamecenter.common.utils.observableToMain
import com.gh.gamecenter.common.utils.singleToMain
import com.gh.gamecenter.common.view.dsbridge.CompletionHandler
import com.gh.gamecenter.core.runOnUiThread
import com.gh.gamecenter.core.utils.EmptyCallback
import com.gh.gamecenter.core.utils.MtaHelper
import com.gh.gamecenter.core.utils.SPUtils
import com.gh.gamecenter.core.utils.ToastUtils
import com.gh.gamecenter.energy.EnergyBridge
import com.gh.gamecenter.entity.ApkEntity
import com.gh.gamecenter.entity.GameEntity
import com.gh.gamecenter.entity.PluginLocation
import com.gh.gamecenter.gamedetail.dialog.GamePermissionDialogFragment
import com.gh.gamecenter.login.user.UserManager
import com.gh.gamecenter.retrofit.RetrofitManager
import com.gh.gamecenter.teenagermode.TeenagerModeActivity
import com.gh.vspace.VHelper
import com.lightgame.download.DownloadEntity
import com.lightgame.download.FileUtils
import com.lightgame.utils.Utils
import java.io.File

/**
 * 游戏活动下载辅助类
 */
object GameActivityDownloadHelper {

    private var mTraceEvent: ExposureEvent? = null
    private var mGameEntity: GameEntity? = null

    fun start(context: Context, event: DefaultJsApi.GameActivityEvent) {
        if (mGameEntity != null && mGameEntity?.id == event.gameId) {
            runOnUiThread {
                handleGameEntity(context, event, mGameEntity!!)
            }
        } else {
            RetrofitManager.getInstance()
                .api
                .getGameDigest(event.gameId)
                .map(ApkActiveUtils.filterMapper)
                .compose(observableToMain())
                .subscribe(object : Response<GameEntity>() {
                    override fun onResponse(gameEntity: GameEntity?) {
                        mGameEntity = gameEntity
                        gameEntity?.let {
                            handleGameEntity(context, event, it)
                        }
                    }
                })
        }
    }

    private fun handleGameEntity(
        context: Context,
        event: DefaultJsApi.GameActivityEvent,
        gameEntity: GameEntity
    ) {
        // 青少年模式
        if (isTeenageMode(context)) return

        val entrance = "(游戏活动[${event.activityTitle}])"
        val location = "游戏活动:${event.activityTitle}-${gameEntity.name}"
        if (mTraceEvent == null) {
            val exposureSources = arrayListOf(
                ExposureSource("游戏活动", "${event.activityTitle}+${event.activityId}")
            )
            mTraceEvent = ExposureEvent.createEvent(gameEntity, exposureSources, null, ExposureType.EXPOSURE)
        }

        mTraceEvent?.run {
            when {
                // 预约
                gameEntity.isReservable -> reserve(context, gameEntity, entrance, this)
                // 开始玩
                gameEntity.getApk().size == 0 && gameEntity.h5Link != null -> play(context, gameEntity)
                // 下载
                else -> handleDownload(context, event, gameEntity, entrance, location, this)
            }
        }
    }

    // 青少年模式
    private fun isTeenageMode(context: Context): Boolean {
        if (SPUtils.getBoolean(Constants.SP_TEENAGER_MODE)) {
            DialogHelper.showDialog(
                context,
                "提示",
                "当前处于儿童/青少年模式， \n暂不提供游戏下载",
                "退出青少年模式",
                "关闭",
                { context.startActivity(TeenagerModeActivity.getIntent(context)) },
                {},
                DialogHelper.Config(
                    centerTitle = true,
                    centerContent = true
                )
            )
            return true
        }
        return false
    }

    // 预约
    private fun reserve(
        context: Context,
        gameEntity: GameEntity,
        entrance: String,
        traceEvent: ExposureEvent
    ) {
        if (!ReservationRepository.thisGameHasBeenReserved(gameEntity.id)) {
            CheckLoginUtils.checkLogin(context, entrance) {
                ReservationHelper.reserve(context, gameEntity.id, object : EmptyCallback {
                    override fun onCallback() {
                        LogUtils.logReservation(gameEntity, traceEvent)
                        clear()
                    }
                })
            }
        } else {
            ToastUtils.toast("游戏已成功预约")
        }
    }

    // 开始玩(H5链接)
    private fun play(context: Context, gameEntity: GameEntity) {
        val linkEntity = gameEntity.h5Link
        val isPlay = "play" == linkEntity!!.type // 是否为开始玩
        if (isPlay) {
            HistoryHelper.insertGameEntity(gameEntity)
        }
        val i = WebActivity.getIntentForWebGame(
            context,
            gameEntity.h5Link!!.link,
            gameEntity.name,
            isPlay,
            linkEntity.closeButton
        )
        context.startActivity(i)
    }

    // 下载
    private fun handleDownload(
        context: Context,
        event: DefaultJsApi.GameActivityEvent,
        gameEntity: GameEntity,
        entrance: String,
        location: String,
        traceEvent: ExposureEvent
    ) {
        val apk = getApk(gameEntity, event, true) ?: return
        val downloadEntity = DownloadManager.getInstance().getDownloadEntitySnapshot(gameEntity)
        val str = GameUtils.getDownloadBtnText(context, gameEntity, PluginLocation.only_game)
        if (downloadEntity != null &&
            str != context.getString(R.string.install) &&
            str != context.getString(R.string.launch)
        ) {
            ToastUtils.toast("${gameEntity.name}已加入下载队列")
        } else {
            if (str == context.getString(R.string.download) || str == context.getString(R.string.attempt)) {
                GamePermissionDialogFragment.show((context as AppCompatActivity), gameEntity, gameEntity.info) {
                    CertificationDialog.showCertificationDialog(context, gameEntity) {
                        DialogUtils.checkDownload(context, apk.size) { isSubscribe: Boolean ->
                            download(context, gameEntity, apk, isSubscribe, entrance, location, traceEvent)
                        }
                    }
                }
                DataLogUtils.uploadGameLog(context, gameEntity.id, gameEntity.name, entrance)
            } else if (str == context.getString(R.string.smooth)) {
                VHelper.validateVSpaceBeforeAction(context, gameEntity) {
                    GamePermissionDialogFragment.show((context as AppCompatActivity), gameEntity, gameEntity.info) {
                        CertificationDialog.showCertificationDialog(context, gameEntity) {
                            DialogUtils.checkDownload(context, apk.size) { isSubscribe: Boolean ->
                                download(context, gameEntity, apk, isSubscribe, entrance, location, traceEvent)
                            }
                        }
                    }
                }
            } else if (str.contains("化")) {
                if (gameEntity.pluggableCollection != null) {
                    DownloadDialog.showDownloadDialog(context, gameEntity, traceEvent, entrance, location)
                } else {
                    CertificationDialog.showCertificationDialog(context, gameEntity) {
                        DialogUtils.checkDownload(context, apk.size) { isSubscribe: Boolean ->
                            plugin(context, gameEntity, apk, entrance, location, isSubscribe, traceEvent)
                        }
                    }
                }
            } else if (str == context.getString(R.string.install)) {
                val simulatorDownloadEntity = SimulatorGameManager.findDownloadEntityByUrl(apk.url)
                if (gameEntity.simulator != null) {
                    val isInstalled =
                        PackageUtils.isInstalledFromAllPackage(context, gameEntity.simulator!!.apk!!.packageName)
                    val isInstalledNewSimulator = SimulatorGameManager.isNewSimulatorInstalled(context)
                    val isInstalledOldSimulator = SimulatorGameManager.isOldSimulatorInstalled(context)
                    var simulator = gameEntity.simulator
                    val newSimulator = Config.getNewSimulatorEntitySetting()
                    if (!isInstalledOldSimulator && newSimulator != null) {//在没有安装旧的模拟器且有配置新版模拟器 才使用新版模拟器 否则还是用以前旧的
                        if (newSimulator.active) {
                            simulator = newSimulator
                        }
                    }
                    if (simulatorDownloadEntity != null && SimulatorGameManager.isSimulatorGame(gameEntity) && !isInstalled && !isInstalledNewSimulator) {
                        SimulatorDownloadManager.getInstance().showDownloadDialog(
                            context, simulator,
                            SimulatorDownloadManager.SimulatorLocation.LAUNCH, gameEntity.id, gameEntity.name!!, null
                        )
                        return
                    }
                }

                if (gameEntity.isVGame()) {
                    VHelper.installOrLaunch((context as AppCompatActivity), gameEntity.getUniquePackageName() ?: "")
                } else {
                    downloadEntity?.run {
                        install(context, gameEntity, apk, this)
                    }
                }
            } else if (str == context.getString(R.string.launch)) {
                EnergyBridge.postEnergyTask("play_game", gameEntity.id, gameEntity.getApk()[0].packageName)
                //启动模拟器游戏
                if (SimulatorGameManager.isSimulatorGame(gameEntity)) {
                    if (NewSimulatorGameManager.shouldShowUpdateNewSimulatorAlert(context)) {
                        NewSimulatorGameManager.showUpdateNewsSimulator(context, null)
                        return
                    }
                    val simulatorDownloadEntity =
                        SimulatorGameManager.findDownloadEntityByUrl(gameEntity.getApk()[0].url)
                    if (simulatorDownloadEntity != null) {
                        val file = File(simulatorDownloadEntity.path)
                        if (!file.exists()) {
                            download(context, gameEntity, apk, false, entrance, location, traceEvent)
                            return
                        }
                        NewFlatLogUtils.logSimulatorGameCardClick("启动")
                        SimulatorGameManager.launchSimulatorGame(simulatorDownloadEntity, gameEntity)
                    }
                    return
                }

                if (gameEntity.isVGame()) {
                    VHelper.installOrLaunch((context as AppCompatActivity), gameEntity.getUniquePackageName() ?: "")
                    return
                }

                if (entrance.contains("我的游戏")) {
                    MtaHelper.onEvent("我的游戏_启动", "启动", gameEntity.name)
                }
                PackageUtils.launchApplicationByPackageName(context, gameEntity.getApk()[0].packageName)
            } else if (str == context.getString(R.string.update)) {
                DialogUtils.checkDownload(context, apk.size) { isSubscribe: Boolean ->
                    update(context, gameEntity, apk, entrance, location, isSubscribe, traceEvent)
                }
            } else {
                ToastUtils.toast("${gameEntity.name}已加入下载队列")
            }
        }
    }

    private fun getApk(
        gameEntity: GameEntity,
        event: DefaultJsApi.GameActivityEvent,
        isRemoveOther: Boolean
    ): ApkEntity? {
        return when {
            gameEntity.getApk().isEmpty() -> null

            gameEntity.getApk().size == 1 -> gameEntity.getApk()[0]

            // 找出对应平台版本Apk且移除掉其他平台版本Apk
            isRemoveOther -> {
                // 当前游戏为多版本时，只保留活动指定的版本即可，方便之后判断
                var apk: ApkEntity? = null
                val iterator = gameEntity.getApk().iterator()
                while (iterator.hasNext()) {
                    val tempApk = iterator.next()
                    if (tempApk.getPlatform() == event.platform) {
                        apk = tempApk
                    } else {
                        iterator.remove()
                    }
                }
                apk
            }

            // 找出对应平台版本Apk即可
            else -> {
                var apk: ApkEntity? = null
                run outside@{
                    gameEntity.getApk().forEach {
                        if (it.getPlatform() == event.platform) {
                            apk = it
                            return@outside
                        }
                    }
                }
                apk
            }
        }
    }

    private fun download(
        context: Context,
        gameEntity: GameEntity,
        apk: ApkEntity,
        isSubscribe: Boolean,
        entrance: String,
        location: String,
        traceEvent: ExposureEvent
    ) {
        val msg = FileUtils.isCanDownload(context, apk.size)
        if (TextUtils.isEmpty(msg)) {
            DownloadManager.createDownload(
                context, apk, gameEntity, context.getString(
                    R.string.download
                ), entrance, location, isSubscribe, traceEvent
            )
            ToastUtils.toast("${gameEntity.name}已加入下载队列")
        } else {
            ToastUtils.toast(msg)
        }
    }

    // 插件化
    private fun plugin(
        context: Context,
        gameEntity: GameEntity,
        apk: ApkEntity,
        entrance: String,
        location: String,
        isSubscribe: Boolean,
        traceEvent: ExposureEvent?
    ) {
        val msg = FileUtils.isCanDownload(context, apk.size)
        if (TextUtils.isEmpty(msg)) {
            DownloadManager.createDownload(context, apk, gameEntity, "插件化", entrance, location, isSubscribe, traceEvent)
            ToastUtils.toast("${gameEntity.name}已加入下载队列")
        } else {
            ToastUtils.toast(msg)
        }
    }

    // 安装
    private fun install(
        context: Context,
        gameEntity: GameEntity,
        apkEntity: ApkEntity,
        downloadEntity: DownloadEntity
    ) {
        val path = downloadEntity.path
        when {
            FileUtils.isEmptyFile(path) -> {
                Utils.toast(context, R.string.install_failure_hint)
                DownloadManager.getInstance().cancel(downloadEntity.url)
                gameEntity.getEntryMap().remove(apkEntity.getPlatform())
            }
            PackageUtils.isCanPluggable(apkEntity) -> {
                DialogHelper.showPluginDialog(context) { PackageInstaller.uninstall(context, path) }
            }
            else -> {
                PackageInstaller.install(context, downloadEntity)
            }
        }
    }

    // 更新
    private fun update(
        context: Context,
        gameEntity: GameEntity,
        apk: ApkEntity,
        entrance: String,
        location: String,
        isSubscribe: Boolean,
        traceEvent: ExposureEvent?
    ) {
        DownloadManager.createDownload(context, apk, gameEntity, "更新", entrance, location, isSubscribe, traceEvent)
        ToastUtils.toast("${gameEntity.name}已加入下载队列")
    }

    @SuppressLint("CheckResult")
    fun postTaskComplete(gameId: String) {
        val api = RetrofitManager.getInstance().newApi
        val single = if (UserManager.getInstance().isLoggedIn) {
            api.postGameActivityTask(gameId)
        } else {
            api.postGameActivityTaskForNoLogin(gameId)
        }
        single.compose(singleToMain()).subscribe(EmptyResponse())
    }

    // 判断是否完成任务(预约完成或者已安装且无更新)
    @SuppressLint("CheckResult")
    fun checkTaskComplete(
        context: Context,
        event: DefaultJsApi.GameActivityEvent,
        handler: CompletionHandler<Any>
    ) {
        // 预约完成
        if (ReservationRepository.thisGameHasBeenReserved(event.gameId)) {
            postTaskComplete(event.gameId)
            handler.complete(true)
            return
        }

        if (mGameEntity != null && mGameEntity?.id == event.gameId) {
            handleCheckTaskComplete(context, mGameEntity, event, handler)
        } else {
            RetrofitManager.getInstance()
                .api
                .getGameDigest(event.gameId)
                .map(ApkActiveUtils.filterMapper)
                .compose(observableToMain())
                .subscribe(object : Response<GameEntity>() {
                    override fun onResponse(gameEntity: GameEntity?) {
                        mGameEntity = gameEntity
                        handleCheckTaskComplete(context, gameEntity, event, handler)
                    }

                    override fun onApiFailure(e: ApiResponse<GameEntity>?) {
                        super.onApiFailure(e)
                        handler.complete(false)
                    }
                })
        }
    }

    private fun handleCheckTaskComplete(
        context: Context,
        gameEntity: GameEntity?,
        event: DefaultJsApi.GameActivityEvent,
        handler: CompletionHandler<Any>
    ) {
        if (gameEntity == null) {
            handler.complete(false)
        } else {
            val apk = getApk(gameEntity, event, false)
            if (apk == null) {
                handler.complete(false)
            } else {
                // 已安装
                if (PackageUtils.isInstalled(context, apk.packageName)) {
                    // 是否可更新
                    if (PackageUtils.isCanUpdate(apk, event.gameId)
                        || PackageUtils.isNonPluginUpdatable(apk, gameEntity)
                    ) {
                        handler.complete(false)
                    } else {
                        // 已安装且无更新
                        postTaskComplete(event.gameId)
                        handler.complete(true)
                    }
                } else {
                    handler.complete(false)
                }
            }
        }
    }

    fun postExposureEvent(event: DefaultJsApi.GameActivityEvent) {
        RetrofitManager.getInstance()
            .api
            .getGameDigest(event.gameId)
            .map(ApkActiveUtils.filterMapper)
            .compose(observableToMain())
            .subscribe(object : Response<GameEntity>() {
                override fun onResponse(gameEntity: GameEntity?) {
                    mGameEntity = gameEntity
                    gameEntity?.let {
                        val exposureSources = arrayListOf(
                            ExposureSource("游戏活动", "${event.activityTitle}+${event.activityId}")
                        )
                        mTraceEvent = ExposureEvent.createEvent(
                            gameEntity,
                            exposureSources,
                            null,
                            ExposureType.EXPOSURE
                        )
                        mTraceEvent?.run { ExposureManager.log(this) }
                    }
                }
            })
    }

    fun clear() {
        mTraceEvent = null
        mGameEntity = null
    }
}