package com.gh.common.filter

import android.annotation.SuppressLint
import com.gh.gamecenter.R
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.retrofit.BiResponse
import com.gh.gamecenter.common.utils.debounceActionWithInterval
import com.gh.gamecenter.common.utils.toJson
import com.gh.gamecenter.common.utils.toObject
import com.gh.gamecenter.core.utils.SPUtils
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.feature.entity.IpInfo
import com.gh.gamecenter.feature.entity.SimpleGame
import com.gh.gamecenter.retrofit.RetrofitManager
import com.halo.assistant.HaloApp
import io.reactivex.functions.Function
import io.reactivex.schedulers.Schedulers

object RegionSettingHelper {

    // 是否是初始化调用
    private var mIsInit = true

    private var mChannelControl: RegionSetting.ChannelControl? = null
    private var mFilterGameIdSet: HashSet<String>? = hashSetOf()
    private var mDisplayMirrorGameIdSet: HashSet<String>? = hashSetOf()
    private var mDisplayMirrorGameIdSet2: HashSet<String>? = hashSetOf()
    private var mGameH5DownloadList: List<RegionSetting.GameH5Download>? = listOf()
    private var mGameSpecialDownloadInfoList: List<RegionSetting.GameSpecialDownloadInfo>? = listOf()
    private var mIpInfo: IpInfo? = null

    private const val SP_SETTING = "region_setting"
    const val SP_SETTING_FAILURE = "region_setting_failure"

    @JvmStatic
    fun shouldThisGameDisplayMirrorInfo(gameId: String): Boolean {
        return mDisplayMirrorGameIdSet?.contains(gameId) == true
                || mDisplayMirrorGameIdSet2?.contains(gameId) == true
    }

    /**
     * 获取镜像数据的位置，是归属镜像 1 还是镜像 2
     */
    fun getMirrorPosition(gameId: String): Int {
        return if (mDisplayMirrorGameIdSet?.contains(gameId) == true) {
            1
        } else if (mDisplayMirrorGameIdSet2?.contains(gameId) == true) {
            2
        } else {
            -1
        }
    }

    @JvmStatic
    fun shouldThisGameBeFiltered(gameId: String?): Boolean {
        return mFilterGameIdSet?.contains(gameId) ?: false
    }

    fun shouldThisGameShowSpecialDownload(gameId: String) =
        mGameSpecialDownloadInfoList?.any { it.gameId == gameId } ?: false

    @JvmStatic
    fun getGameSpecialDownloadInfo(gameId: String) = mGameSpecialDownloadInfoList?.find { it.gameId == gameId }

    fun getIpInfo(): IpInfo? = mIpInfo

    @JvmStatic
    fun filterGame(list: List<GameEntity>?): ArrayList<GameEntity> {
        if (list == null) return arrayListOf()

        if (mFilterGameIdSet?.isEmpty() == true) {
            if (list is ArrayList) return list
        }

        val listCopy: ArrayList<GameEntity> = if (list is ArrayList) list else ArrayList(list)
        listCopy.removeAll { mFilterGameIdSet?.contains(it.id) ?: false }
        return listCopy
    }

    @JvmStatic
    fun filterSimpleGame(list: List<SimpleGame>?): ArrayList<SimpleGame> {
        if (list == null) return arrayListOf()

        if (mFilterGameIdSet?.isEmpty() == true) {
            if (list is ArrayList) return list
        }

        val listCopy: ArrayList<SimpleGame> = if (list is ArrayList) list else ArrayList(list)
        listCopy.removeAll { mFilterGameIdSet?.contains(it.id) ?: false }
        return listCopy
    }

    @JvmField
    var filterGame = Function { list: List<GameEntity> ->
        filterGame(list)
        list
    }

    fun shouldGameOfThisCategoryUseMirrorInfo(category: String): Boolean {
        return if (mChannelControl == null || mChannelControl?.effect == false || !isUserUsedLessThan24Hours()) {
            false
        } else {
            mChannelControl?.gameCategory == category
        }
    }

    @JvmStatic
    fun getGameH5DownloadByGameId(gameId: String): RegionSetting.GameH5Download? {
        if (mGameH5DownloadList.isNullOrEmpty()) return null
        return mGameH5DownloadList!!.find { it.gameId == gameId }
    }

    @SuppressLint("CheckResult")
    @JvmStatic
    fun getRegionSetting() {
        debounceActionWithInterval(R.string.app_name, 5000) {

            // 初始启动时先使用历史数据
            if (mIsInit) {
                SPUtils.getString(SP_SETTING).toObject<RegionSetting>()?.let {
                    updateSettingsInMemory(it)
                }
                mIsInit = false
            }

            // 使用默认的 Schdulers.io() 可能会触发 OOM
            RetrofitManager.getInstance()
                .api
                .getRegionSetting(HaloApp.getInstance().channel)
                .subscribeOn(Schedulers.io())
                .subscribe(object : BiResponse<RegionSetting>() {
                    override fun onSuccess(data: RegionSetting) {
                        updateSettingsInMemory(data)
                        SPUtils.setString(SP_SETTING, data.toJson())
                    }

                    override fun onFailure(exception: Exception) {
                        SPUtils.getString(SP_SETTING).toObject<RegionSetting>()?.let {
                            updateSettingsInMemory(it)
                        }
                        SPUtils.setBoolean(SP_SETTING_FAILURE, true)
                    }
                })
        }
    }

    private fun updateSettingsInMemory(data: RegionSetting) {
        mFilterGameIdSet = data.filterGameIdSet
        mDisplayMirrorGameIdSet = data.mirrorGameIdSet
        mDisplayMirrorGameIdSet2 = data.mirrorGameIdSet2
        mChannelControl = data.channelControl
        mGameH5DownloadList = data.gameH5DownloadList
        mGameSpecialDownloadInfoList = data.gameSpecialDownloadInfoList
        mIpInfo = data.ipInfo
    }

    /**
     * 该用户是否是使用了不到 24 小时的新用户
     */
    private fun isUserUsedLessThan24Hours(): Boolean {
        val initialUsageTime = SPUtils.getLong(Constants.SP_INITIAL_USAGE_TIME, 0)
        return !(initialUsageTime == 0L || System.currentTimeMillis() - initialUsageTime > 86400000)
    }

}