package com.img.rabbit.provider.utils

import android.text.TextUtils
import android.util.Log
import com.img.rabbit.BuildConfig
import com.img.rabbit.config.Constants
import com.img.rabbit.config.Constants.LOG_REQUEST
import com.img.rabbit.provider.storage.PreferenceUtil
import com.img.rabbit.utils.StringUtils
import okhttp3.Interceptor
import okhttp3.Response
import okio.Buffer
import java.io.IOException
import java.nio.charset.StandardCharsets
import java.text.SimpleDateFormat
import java.util.Arrays
import java.util.Date
import java.util.Locale

/**
 * 加密数据
 */
class RequestInterceptor : Interceptor {
    private val TAG = "Encryption"
    private val dateFormat = SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS", Locale.getDefault())

    override fun intercept(chain: Interceptor.Chain): Response {
        val startTime = System.currentTimeMillis()
        val request = chain.request()

        // 记录请求信息
        logRequest(request)

        var modifiedRequest = request
        val method = request.method.lowercase(Locale.getDefault()).trim { it <= ' ' }
        val url = request.url
        val apiPath = String.format("%s", url)

        val baseUrl = if (BuildConfig.DEBUG) {
            Constants.DEBUG_BASE_URL
        } else {
            Constants.RELEASE_BASE_URL
        }

        // 如果请求的不是服务端的接口则不用加密
        if (!apiPath.startsWith(baseUrl)) {
            val response = chain.proceed(modifiedRequest)
            return response
        }

        /*
        L.d("TAG-->>url=$apiPath")
        //如果请求的不是服务端的接口则不用加密
        if (!apiPath.startsWith(Constants.BaseUrl)) {
            L.d("TAG-->>content-type=${request.headers["Content-Type"]}")
            val requestBody = request.body
            L.d("TAG-->>${requestBody.toString()}")
            return chain.proceed(request)
        }
         */

        var queryString = url.encodedQuery
        queryString = if (!TextUtils.isEmpty(queryString)) {
            (queryString + "&nonce=" + StringUtils.createUUID()) + "&timestamp=" + PreferenceUtil.serverTimeMillis() / 1000
        } else {
            ("nonce=" + StringUtils.createUUID()) + "&timestamp=" + PreferenceUtil.serverTimeMillis() / 1000
        }
        val sortQueryString = Arrays.stream(queryString.split("&".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray())
            .sorted { obj: String, anotherString: String? -> obj.compareTo(anotherString!!) }
            .reduce { x: String, y: String -> "$x&$y" }
            .get()
        //如果请求方式是get或者delete 则没有body
        var paramsStr = ""
        var bytes = ByteArray(0)
        var signature: String? = ""
        if (method == "put" || method == "post") {
            val requestBody = request.body
            Log.w(TAG, "TAG-->>${requestBody.toString()}")
            val buffer = Buffer()
            requestBody!!.writeTo(buffer)
            bytes = StringUtils.addByte(bytes, buffer.readByteArray())
            Log.w(TAG, "签名后bodyByte的长度为" + bytes.size)
            paramsStr = String(bytes, StandardCharsets.UTF_8)
            //            paramsStr = buffer.readUtf8();
            Log.w(TAG, "签名后body的长度为" + paramsStr.length)
        }
        signature = if (bytes.isNotEmpty()) {
            Log.w(TAG, "当前的数组长度为----" + bytes.size)
            StringUtils.getMD5Byte(
                StringUtils.addByte(
                    StringUtils.addByte("$sortQueryString&".toByteArray(), bytes),
                    ("&" + StringUtils.getMD5String(Constants.Signature)).toByteArray()
                )
            )
        } else {
            StringUtils.getMD5String(sortQueryString + "&" + StringUtils.getMD5String(Constants.Signature))
        }
        val newUrl = apiPath.split("\\?".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()[0] + "?" + queryString + "&signature=" + signature
        Log.w(TAG, "签名后的路径--->$newUrl")
        /*
        request = request.newBuilder().url(newUrl).build()
        return chain.proceed(request)
         */

        modifiedRequest = request.newBuilder().url(newUrl).build()
        val response = chain.proceed(modifiedRequest)
        logResponse(response, startTime)
        return response
    }

    //---------------------------------> 以下为格式化请求日志打印 <---------------------------------
    private fun logRequest(request: okhttp3.Request) {
        val timestamp = dateFormat.format(Date())
        val method = request.method
        val url = request.url.toString()

        Log.i(LOG_REQUEST,"┌─────────────────────────────────────────────────────────────────────────────")
        Log.i(LOG_REQUEST,"│ 📤 请求部分 [$timestamp]")
        Log.i(LOG_REQUEST,"├─────────────────────────────────────────────────────────────────────────────")
        Log.i(LOG_REQUEST,"│ -->方法: $method")
        Log.i(LOG_REQUEST,"│ -->URL: $url")

        // 记录请求体（如果有）
        val requestBody = request.body
        if (requestBody != null) {
            try {
                val buffer = Buffer()
                requestBody.writeTo(buffer)
                val bodyString = buffer.readUtf8()
                if (bodyString.isNotEmpty()) {
                    Log.i(LOG_REQUEST,"│ -->请求参数:")
                    Log.i(LOG_REQUEST,"│ -->  $bodyString")
                }
            } catch (e: IOException) {
                Log.e(LOG_REQUEST,"│ -->读取请求体失败: ${e.message}")
            }
        }else{
            Log.i(LOG_REQUEST,"│ -->无请求参数")
        }
        Log.i(LOG_REQUEST,"└─────────────────────────────────────────────────────────────────────────────")
    }

    private fun logResponse(response: Response, startTime: Long) {
        val timestamp = dateFormat.format(Date())
        val duration = System.currentTimeMillis() - startTime
        val code = response.code
        val message = response.message
        val url = response.request.url.toString()
        val apiPath = url.split("\\?".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()[0]

        Log.i(LOG_REQUEST,"┌─────────────────────────────────────────────────────────────────────────────")
        Log.i(LOG_REQUEST,"│ 📥 响应部分 [$timestamp]")
        Log.i(LOG_REQUEST,"├─────────────────────────────────────────────────────────────────────────────")
        Log.i(LOG_REQUEST,"│ URL: $url")
        Log.i(LOG_REQUEST,"│ API: $apiPath")
        Log.i(LOG_REQUEST,"│ 状态码: $code $message")
        Log.i(LOG_REQUEST,"│ 耗时: ${duration}ms")

        // 记录响应体
        try {
            val responseBody = response.peekBody(1024 * 1024L) // 最多读取1MB
            val bodyString = responseBody.string()
            if (bodyString.isNotEmpty()) {
                Log.i(LOG_REQUEST,"│ 响应内容： (前${minOf(bodyString.length, 2000)}字符):")
                val preview = if (bodyString.length > 2000) {
                    bodyString.take(2000) + "..."
                } else {
                    bodyString
                }
                Log.i(LOG_REQUEST,"│   $preview")
            }
        } catch (e: IOException) {
            Log.e(LOG_REQUEST,"│ 读取响应体失败: ${e.message}")
        }
        Log.i(LOG_REQUEST,"└─────────────────────────────────────────────────────────────────────────────")
    }
}