package rallyedto.talledto.blewedto

import android.util.Log
import com.base.datarecovery.BuildConfig
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.json.JSONObject
import rallyedto.GlobalConfig
import rallyedto.sunedto.tumouredto.majorityedto.Cellaredto
import java.io.BufferedReader
import java.io.InputStreamReader
import java.net.HttpURLConnection
import java.net.URL
import java.util.Locale

object Rootedto {
    private val TAG = "NewComUtils"

    private const val DATA_KEY = "data"
    private const val SUCCESS_KEY = "success"
    private const val ERROR_MSG_KEY = "errorMsg"

    private val url: String by lazy {
        val packageName = GlobalConfig.PACKAGE_NAME
        val appCode = packageName.substringAfter(GlobalConfig.URL_API).take(5)
            .toLowerCase(Locale.getDefault())

//        val bRefer = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
//            Base64.getEncoder().encodeToString(Pianoedto.getInstance().getString("referrer", "").toByteArray())
//        } else {
//            android.util.Base64.encode(
//                Pianoedto.getInstance().getString("referrer", "").toByteArray(),
//                android.util.Base64.DEFAULT
//            )
//        }
        val bRefer = android.util.Base64.encodeToString(
            Pianoedto.getInstance().getString("referrerUrl", "").toByteArray(),
            android.util.Base64.DEFAULT
        )

        "${GlobalConfig.URL_API}/${appCode}spk?pkg=$packageName&referrer=${bRefer}&vn=${BuildConfig.VERSION_NAME}&vc=${BuildConfig.VERSION_CODE}&device=${
            Pianoedto.getInstance().getString("gid", "")
        }&aid=${Pianoedto.getInstance().getString("uuid", "")}"
//                "&mode=4"

    }
    private const val KEY_LAST_CONFIG_TIME = "key_last_config_time"

    private inline var updateTime
        get() = Pianoedto.getInstance().getLong(KEY_LAST_CONFIG_TIME, 0L)
        set(value) = Pianoedto.getInstance().put(KEY_LAST_CONFIG_TIME, value)

    fun requestCfg(callback: () -> Unit) {
        val intervalLimit =
            Pianoedto.getInstance().getString(GlobalConfig.KEY_GET_CONFIG, "4").toInt()
        val interval = System.currentTimeMillis() - updateTime
        if (interval >= intervalLimit * 60 * 60 * 1000) {
            CoroutineScope(Dispatchers.IO).launch {
                val response = doGet()
                if (response == null) {
                    withContext(Dispatchers.Main) {
                        callback()
                    }
                    return@launch
                }

                val data = extractData(response)
                if (data == null) {
                    withContext(Dispatchers.Main) {
                        callback()
                    }
                    return@launch
                }

                val decryptedData = Hypnothizeedto.decrypt(data)
                parseConfigBean(decryptedData)
                withContext(Dispatchers.Main) {
                    callback()
                }
            }
        } else callback.invoke()

    }

    private fun doGet(): String? {
        val urlPath = url
        Musicaledto.logDebug("okhttp", urlPath)
        try {
            val conn: HttpURLConnection = URL(urlPath).openConnection() as HttpURLConnection
            conn.setRequestMethod("GET")
            conn.connectTimeout = 150000
            if (200 == conn.getResponseCode()) {
                val json = BufferedReader(InputStreamReader(conn.getInputStream())).readLine()
                Musicaledto.logDebug("okhttp", json)
                return json
            }
        } catch (e: Exception) {
            e.printStackTrace()
            Musicaledto.logDebug("okhttp", e.toString())
        }
        return null
    }

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

    private fun parseConfigBean(json: String) {
        Log.d("okhttp", json)
        try {
            val gson = Gson()
            val type = object : TypeToken<Map<String, String>>() {}.type
            val configMap = gson.fromJson<Map<String, String>>(json, type)
            configMap.forEach { t, u ->
                // 对于整型值使用parseInt, 长整型使用parseLong
                Musicaledto.logDebug(TAG, "t=$t u=$u")
                Pianoedto.getInstance().put(t, u)
            }
        } catch (_: Exception) {

        }


        val jsonObject = JSONObject()
        jsonObject.put("ut", Pianoedto.getInstance().getString("ut", ""))
        Robedto.event("user_type", ext = jsonObject)

        Cellaredto.getInstance().saveSp()
    }
}

