package com.kaixed.kchat.network

import com.google.gson.Gson
import com.google.gson.JsonObject
import com.google.gson.JsonParser
import com.kaixed.kchat.model.request.UserRequest
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.Request
import okhttp3.RequestBody.Companion.toRequestBody
import okio.Buffer
import java.io.IOException
import java.security.MessageDigest

object SignUtil {

    // 生成签名
    fun generateSign(request: Request, timestamp: String): String {
        val secretKey = "your_secret_key"
        val stringBuilder = StringBuilder("timestamp=$timestamp")

        // 根据请求类型处理 GET 或 POST 请求
        when (request.method) {
            "GET" -> appendUrlParams(request, stringBuilder)
            "POST" -> appendPostParams(request, stringBuilder)
        }

        // 拼接密钥并生成签名
        stringBuilder.append(secretKey)
        println(stringBuilder.toString())
        return md5(stringBuilder.toString())
    }

    // 处理 GET 请求 URL 参数
    private fun appendUrlParams(request: Request, stringBuilder: StringBuilder) {
        val url = request.url
        url.queryParameterNames.forEach { name ->
            val value = url.queryParameter(name)
            stringBuilder.append("&$name=$value")
        }
    }

    // 处理 POST 请求参数，包括表单数据和 JSON 数据
    private fun appendPostParams(request: Request, stringBuilder: StringBuilder) {
        val body = request.body
        body?.let {
            when (body.contentType()?.subtype) {
                "x-www-form-urlencoded" -> appendFormParams(it, stringBuilder)
                "json" -> appendJsonBody(it, stringBuilder)
            }
        }
    }

    // 处理表单数据
    private fun appendFormParams(body: okhttp3.RequestBody, stringBuilder: StringBuilder) {
        val formBody = body as okhttp3.FormBody
        val sortedParams = (0 until formBody.size)
            .map { Pair(formBody.name(it), formBody.value(it)) }
            .sortedBy { it.first }

        sortedParams.forEach { (name, value) ->
            stringBuilder.append("&$name=$value")
        }
    }

    // 处理 JSON 数据并排序
    private fun appendJsonBody(body: okhttp3.RequestBody, stringBuilder: StringBuilder) {
        val jsonBody = getRequestBodyAsJsonObject(body)
        jsonBody?.let {
            val sortedJson = sortJson(it)
            stringBuilder.append("&body=$sortedJson")
        }
    }

    // 读取 RequestBody 并解析为 JsonObject
    private fun getRequestBodyAsJsonObject(body: okhttp3.RequestBody): JsonObject? {
        val buffer = Buffer()
        try {
            body.writeTo(buffer)
            val bodyString = buffer.readUtf8()
            return JsonParser.parseString(bodyString).asJsonObject
        } catch (e: IOException) {
            e.printStackTrace()
            return null
        }
    }

    // 排序 JSON 对象
    private fun sortJson(jsonObject: JsonObject): String {
        return jsonObject.keySet()
            .sorted()
            .joinToString(",", "{", "}") { key -> "\"$key\":${jsonObject[key]}" }
    }

    // MD5 加密函数
    private fun md5(input: String): String {
        val digest = MessageDigest.getInstance("MD5")
        val bytes = digest.digest(input.toByteArray())
        return bytes.joinToString("") { "%02x".format(it) }
    }

    @JvmStatic
    fun main(args: Array<String>) {
        val request = Request.Builder()
            .url("https://app.kaixed.com/kchat/users/login/username")
            .post(
                Gson().toJson(UserRequest("username", "password"))
                    .toRequestBody("application/json".toMediaType())
            )
            .build()

        val timestamp = System.currentTimeMillis().toString()
        val sign = generateSign(request, timestamp)
        println("sign: $sign")
    }
}
