package com.narutohuo.xindazhou.common.network

import com.narutohuo.xindazhou.common.network.exception.BusinessException
import com.narutohuo.xindazhou.common.network.exception.ExceptionHandle
import com.narutohuo.xindazhou.common.network.exception.HttpException
import com.narutohuo.xindazhou.common.network.exception.ParseException
import com.narutohuo.xindazhou.common.network.response.ApiResponse
import com.narutohuo.xindazhou.core.log.ILog
import retrofit2.Response

/**
 * API 通用响应结果
 * 对应后端 CommonResult<T>
 * 
 * 所有API响应的统一包装格式
 */
data class ApiCommonResult<T>(
    val code: Int,
    val msg: String?,
    val data: T?
)

/**
 * API响应解析器
 * 
 * 统一处理 Retrofit Response，将 Response<ApiCommonResult<T>> 转换为 ApiResponse<T>
 * 参考 Sandwich 设计，提供清晰的响应封装
 */
object ApiResponseParser {
    
    /**
     * 业务成功码
     */
    @PublishedApi
    internal const val SUCCESS_CODE = 0
    
    /**
     * 解析响应为 ApiResponse（新 API）
     * 
     * 使用 reified 泛型自动推断类型，无需手动传 Class
     * 
     * @param response Retrofit Response
     * @param tag 日志标签（用于日志记录）
     * @return ApiResponse<T> 成功返回 Success，业务错误返回 Error，网络异常返回 Exception
     * 
     * 使用方式：
     * ```kotlin
     * val response: ApiResponse<LoginResponse> = ApiResponseParser.parseResponse(
     *     response = retrofitResponse,
     *     tag = "Auth"
     * )
     * 
     * response.onSuccess { data -> ... }
     *         .onError { code, message -> ... }
     *         .onException { exception -> ... }
     * ```
     */
    inline fun <reified T> parseResponse(
        response: Response<ApiCommonResult<T>>,
        tag: String = "ApiResponseParser"
    ): ApiResponse<T> {
        return try {
            // 1. 检查 HTTP 状态码
            if (!response.isSuccessful) {
                val httpException = ExceptionHandle.handleHttpError(response.code(), response.message())
                ILog.w(tag, "HTTP 请求失败: ${httpException.getUserMessage()}")
                return ApiResponse.Exception(httpException)
            }
            
            // 2. 获取响应体
            val commonResult = response.body() ?: run {
                // 尝试读取原始响应体以便调试
                val errorBody = response.errorBody()?.string() ?: "null"
                ILog.e(tag, "响应体为空，errorBody=$errorBody")
                val parseException = ExceptionHandle.handleParseError("服务器返回数据格式错误", null)
                return ApiResponse.Exception(parseException)
            }
            
            ILog.d(tag, "响应体解析成功: code=${commonResult.code}, msg=${commonResult.msg}, data类型=${T::class.simpleName}")
            
            // 3. 检查业务状态码
            if (commonResult.code != SUCCESS_CODE) {
                val message = commonResult.msg?.takeIf { it.isNotBlank() }
                    ?: "操作失败（错误码：${commonResult.code}）"
                ILog.w(tag, "业务失败: $message")
                return ApiResponse.Error(
                    code = commonResult.code,
                    message = message,
                    body = commonResult
                )
            }
            
            // 4. 提取业务数据
            val data = commonResult.data
            if (data == null) {
                ILog.e(tag, "服务器返回数据为空: code=${commonResult.code}, msg=${commonResult.msg}")
                val parseException = ExceptionHandle.handleParseError("服务器返回数据为空", null)
                return ApiResponse.Exception(parseException)
            }
            
            ILog.d(tag, "请求成功: data类型=${data.javaClass.simpleName}")
            ApiResponse.Success(data)
            
        } catch (e: Throwable) {
            // 使用 ExceptionHandle 统一处理异常
            val apiException = ExceptionHandle.handle(e)
            ILog.e(tag, "处理响应异常: ${apiException.getUserMessage()}", e)
            ApiResponse.Exception(apiException)
        }
    }
    
    /**
     * 解析响应为 ApiResponse（支持可空数据）
     * 
     * @param response Retrofit Response
     * @param tag 日志标签
     * @return ApiResponse<T?> 成功返回数据（可能为 null），失败返回 Error 或 Exception
     */
    inline fun <reified T> parseNullableResponse(
        response: Response<ApiCommonResult<T>>,
        tag: String = "ApiResponseParser"
    ): ApiResponse<T?> {
        return try {
            if (!response.isSuccessful) {
                val httpException = ExceptionHandle.handleHttpError(response.code(), response.message())
                ILog.w(tag, "HTTP 请求失败: ${httpException.getUserMessage()}")
                return ApiResponse.Exception(httpException)
            }
            
            val commonResult = response.body() ?: run {
                val parseException = ExceptionHandle.handleParseError("服务器返回数据格式错误", null)
                return ApiResponse.Exception(parseException)
            }
            
            if (commonResult.code != SUCCESS_CODE) {
                val message = commonResult.msg?.takeIf { it.isNotBlank() }
                    ?: "操作失败（错误码：${commonResult.code}）"
                ILog.w(tag, "业务失败: $message")
                return ApiResponse.Error(
                    code = commonResult.code,
                    message = message,
                    body = commonResult
                )
            }
            
            // 允许 data 为 null
            ILog.d(tag, "请求成功（数据可能为 null）")
            ApiResponse.Success(commonResult.data)
            
        } catch (e: Throwable) {
            val apiException = ExceptionHandle.handle(e)
            ILog.e(tag, "处理响应异常: ${apiException.getUserMessage()}", e)
            ApiResponse.Exception(apiException)
        }
    }
    
}

