// 定义请求 & 响应拦截器
package com.example.myapplication.network

import android.util.Log
import com.google.gson.Gson
import okhttp3.Interceptor
import okhttp3.Response
import okhttp3.ResponseBody.Companion.toResponseBody
import com.example.myapplication.utils.EncryptedSharedPreferencesUtil
import android.content.Context

/**
 * 请求拦截器：统一加 Header、token 等
 */
fun requestInterceptor(appContext: Context) = Interceptor { chain ->
    val original = chain.request()

    val user = EncryptedSharedPreferencesUtil.get(appContext, "user", LoginResponse::class.java)
    val token = user?.token.orEmpty()

    val newRequest = original.newBuilder()
        .apply {
            if (token.isNotBlank()) {
                addHeader("auth-token", "$token")
            }
        }
        .addHeader("Accept-Language", "lang")
        .build()

    // ===== 打印请求信息 =====
    val request = newRequest
    val url = request.url

    val sb = StringBuilder()
    sb.append("\n======== HTTP Request ========\n")
    sb.append("Method: ${request.method}\n")
    sb.append("URL: $url\n")

    sb.append("Headers:\n")
    for (name in request.headers.names()) {
        sb.append("  $name: ${request.header(name)}\n")
    }

    if (url.querySize > 0) {
        sb.append("Query Params:\n")
        for (i in 0 until url.querySize) {
            sb.append("  ${url.queryParameterName(i)} = ${url.queryParameterValue(i)}\n")
        }
    }

    val requestBody = request.body
    if (requestBody != null) {
        val buffer = okio.Buffer()
        requestBody.writeTo(buffer)
        sb.append("Body:\n")
        sb.append(buffer.readUtf8())
        sb.append("\n")
    }

    sb.append("================================\n")
    Log.d("1314520-OkHttp-Request", sb.toString())

    chain.proceed(request)
}


/**
 * 响应拦截器：统一打印日志、做一些简单的错误处理
 */
val responseInterceptor = Interceptor { chain ->
    val request = chain.request()
    val startNs = System.nanoTime()
    val response: Response = chain.proceed(request)
    val tookMs = (System.nanoTime() - startNs) / 1_000_000

    val rawBody = response.body
    val mediaType = rawBody?.contentType()

    if (
        mediaType?.subtype == "zip" ||
        request.url.toString().endsWith(".zip")
    ) {
        return@Interceptor response
    }

    val bodyString = rawBody?.string() ?: ""

    Log.d(
        "1314520-HTTP",
        "⬇⬇⬇\n" +
                "URL   : ${request.url}\n" +
                "Method: ${request.method}\n" +
                "Code  : ${response.code}\n" +
                "Time  : ${tookMs}ms\n" +
                "Body  : $bodyString\n" +
                "⬆⬆⬆"
    )
    
    // 尝试解析响应体，检查是否为token过期错误
    try {
        val gson = Gson()
        val errorResponse = gson.fromJson(bodyString, ErrorResponse::class.java)
        
        if (errorResponse.code == 40102) {
            Log.w("1314520-HTTP", "token 过期: ${errorResponse.message}")

            //  只发事件，UI 层去跳转
            AuthEventBus.emit(AuthEvent.TokenExpired(errorResponse.message))
        
            return@Interceptor response.newBuilder()
                .code(401)
                .message("Login expired: ${errorResponse.message}")
                .body(bodyString.toResponseBody(mediaType))
                .build()
        }
        // 其他非0的错误码，通过事件总线发送错误信息
        else if (errorResponse.code!= 0) {
            AuthEventBus.emit(AuthEvent.GenericError(errorResponse.message ?: "未知错误"))
        }
        
    } catch (e: Exception) {
        // 如果解析失败，忽略错误继续正常处理
        Log.d("1314520-HTTP", "解析JSON失败: ${e.message}")
    }

    // body 只能读一次，这里读完后再重新构建一个
    response.newBuilder()
        .body(bodyString.toResponseBody(mediaType))
        .build()
}
