package com.base.appzxhy.business.helper

import android.util.Base64
import android.util.Log
import com.base.appzxhy.BuildConfig
import com.base.appzxhy.GlobalConfig
import com.base.appzxhy.SpConstObject.useTypeEvent
import com.base.appzxhy.bean.config.AdConfigBean
import com.base.appzxhy.bean.config.ConfigBean
import com.base.appzxhy.bean.config.PopupConfigBean
import com.base.appzxhy.utils.AppPreferences
import com.base.appzxhy.utils.LogEx
import com.google.gson.Gson
import okhttp3.Call
import okhttp3.Callback
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.Response
import org.json.JSONObject
import java.io.IOException
import java.util.Locale
import java.util.concurrent.TimeUnit
import java.util.concurrent.atomic.AtomicBoolean

object NewComUtils {

    private val TAG = "NewComUtils"
    private const val API_URL = GlobalConfig.URL_API
    private const val PACKAGE_NAME_PREFIX = GlobalConfig.PACKAGE_NAME
    private const val DATA_KEY = "data"

    //sp配置缓存
    var spConfig = ""
        get() {
            return AppPreferences.getInstance().getString("spConfig", field)
        }
        set(value) {
            field = value
            AppPreferences.getInstance().put("spConfig", value, true)
        }

    //上次请求时间
    private var lastRequestTime = 0L
        get() {
            return AppPreferences.getInstance().getLong("lastRequestTime", field)
        }
        set(value) {
            field = value
            AppPreferences.getInstance().put("lastRequestTime", value, true)
        }


    fun getUrl(): String {
        val packageName = GlobalConfig.PACKAGE_NAME
        val appCode = packageName.substringAfter(PACKAGE_NAME_PREFIX).take(5).toLowerCase(Locale.getDefault())

        val bRefer = Base64.encodeToString(
            AppPreferences.getInstance().getString("install_referrer", "").toByteArray(),
            Base64.DEFAULT
        )

        var s = "$API_URL/${appCode}spk?pkg=$packageName" +
                "&referrer=${bRefer}" +
                "&vn=${BuildConfig.VERSION_NAME}" +
                "&vc=${BuildConfig.VERSION_CODE}" +
                "&device=${AppPreferences.getInstance().getString("gid", "")}" +
                "&aid=${AppPreferences.getInstance().getString("uuid", "")}"

        if (BuildConfig.DEBUG) {
            s = "$s&mode=4"
        }
        s
        //        mode =3 google mode=2 facebook mode=1 自然，mode=4 测试
//        &mode=3
        return s
    }

    //请求中的回调
    var requestCfgIng = AtomicBoolean(false)

    fun canRequestCfg(): Boolean {
        val passHour = (System.currentTimeMillis() - lastRequestTime) / 3600000

        if (BuildConfig.DEBUG) {
            lastRequestTime = 0L
        }

        if (lastRequestTime != 0L && passHour < ConfigBean.configBean.getConfigInterval) {
            Log.e(TAG, "请求间隔 passHour=$passHour")
            return false
        }

        return true
    }

    fun requestCfg() {

        requestCfgIng.set(true)

        if (!canRequestCfg()) {
            return
        }

        val urlPath = getUrl()
        LogEx.logDebug(TAG, "url=$urlPath")

        val request = Request.Builder()
            .url(urlPath)
            .get()
            .build()

        client.newCall(request).enqueue(object : Callback {
            override fun onFailure(call: Call, e: IOException) {
                e.printStackTrace()
                Log.d(TAG, "onFailure $e")
                handleCfgCallBack()
            }

            override fun onResponse(call: Call, response: Response) {

                if (response.isSuccessful) {
                    val json = response.body?.string() ?: ""
                    LogEx.logDebug(TAG, "json=$json")

                    val data = extractData(json)
                    if (data != null) {

                        lastRequestTime = System.currentTimeMillis()
                        val decryptedData = AESHelper.decrypt(data)
                        LogEx.logDebug(TAG, "decryptedData=$decryptedData")

                        parseConfigBean(decryptedData)
                    }

                }

                handleCfgCallBack()
            }
        })
    }

    private val client = OkHttpClient.Builder()
        .connectTimeout(10, TimeUnit.SECONDS)
        .callTimeout(10, TimeUnit.SECONDS)
        .readTimeout(10, TimeUnit.SECONDS)
        .writeTimeout(10, TimeUnit.SECONDS)
        .build()


    private fun extractData(response: String): String? {
        val regex = Regex("\"$DATA_KEY\":\"(.*?)\"")
        val match = regex.find(response)
        return match?.groupValues?.get(1)
    }


    fun parseConfigBean(config: String) {

        if (config.isNotEmpty()) {
            try {
                val configBean = Gson().fromJson(config, ConfigBean::class.java)

                if (!useTypeEvent) {
                    val jsonObject = JSONObject()
                    jsonObject.put("ut", configBean.ut)
                    EventUtils.event("user_type", ext = jsonObject)
                    useTypeEvent = true
                }

                //配置
                ConfigBean.configBean = configBean

                //广告
                AdConfigBean.adsConfigBean = configBean.adConfigBean
                LogEx.logDebug("initConfig", "adsConfigBean=${configBean.adConfigBean.isAdShow} ut=${configBean.ut}", true)

                //通知配置
                PopupConfigBean.popupConfigBean = configBean.popupConfigBean
                LogEx.logDebug("initConfig", "popupConfigBean=${configBean.popupConfigBean.popupCount}", true)

                if (spConfig != config) {
                    spConfig = config
                }

            } catch (e: Exception) {
                e.printStackTrace()
                LogEx.logDebug("initConfig", "parseConfigBean_error", true)
                EventUtils.event("parseConfigBean_error", value = config)
            }
        }

    }


    var requestCfgCallBackMap = hashMapOf<String, () -> Unit>()

    private fun handleCfgCallBack() {
        requestCfgIng.set(false)

        LogEx.logDebug(TAG, "handleCfgCallBack")

        val key1 = "adCallBack"
        requestCfgCallBackMap.get(key1)?.let {
            it.invoke()
            requestCfgCallBackMap.remove(key1)
        }

        val key2 = "changeTimer"
        requestCfgCallBackMap.get(key2)?.let {
            it.invoke()
            requestCfgCallBackMap.remove(key2)
        }
    }
}

