package com.narutohuo.xindazhou.common.network.response

import com.narutohuo.xindazhou.common.network.ApiCommonResult
import com.narutohuo.xindazhou.common.network.exception.ApiException
import com.narutohuo.xindazhou.common.network.exception.BusinessException

/**
 * API 响应封装（参考 Sandwich 设计）
 * 
 * 统一封装三种状态：Success（成功）、Error（业务错误）、Exception（网络异常）
 * 
 * 设计理念：
 * - Success: HTTP 200 且业务状态码 = 0，成功返回数据
 * - Error: HTTP 200 但业务状态码 != 0，业务层面的错误（如登录失败、参数错误等）
 * - Exception: HTTP 非 200 或网络异常，网络层面的错误（如超时、连接失败等）
 * 
 * 使用方式：
 * ```kotlin
 * val response: ApiResponse<LoginResponse> = api.login(request)
 * 
 * response.onSuccess { data ->
 *     // 处理成功
 * }.onError { code, message ->
 *     // 处理业务错误
 * }.onException { exception ->
 *     // 处理异常
 * }
 * 
 * // 或转换为 Result<T>（向后兼容）
 * val result: Result<LoginResponse> = response.toResult()
 * ```
 */
sealed class ApiResponse<out T> {
    
    /**
     * 成功响应
     * 
     * HTTP 200 且业务状态码 = 0，成功返回数据
     */
    data class Success<T>(val data: T) : ApiResponse<T>()
    
    /**
     * 业务错误响应
     * 
     * HTTP 200 但业务状态码 != 0，业务层面的错误
     * 
     * @param code 业务错误码
     * @param message 错误消息
     * @param body 原始响应体（可选，用于调试）
     */
    data class Error<T>(
        val code: Int,
        val message: String,
        val body: ApiCommonResult<*>? = null
    ) : ApiResponse<T>()
    
    /**
     * 异常响应
     * 
     * HTTP 非 200 或网络异常，网络层面的错误
     * 
     * @param exception API 异常对象
     */
    data class Exception<T>(val exception: ApiException) : ApiResponse<T>()
    
    /**
     * 转换为 Result<T>（向后兼容）
     * 
     * 将 ApiResponse 转换为标准的 Result 类型，方便与现有代码集成
     * 
     * @return Result<T> 成功返回 Success，失败返回 Failure
     */
    fun toResult(): Result<T> = when (this) {
        is Success -> Result.success(data)
        is Error -> Result.failure(BusinessException(code, message))
        is Exception -> Result.failure(exception)
    }
    
    /**
     * 判断是否为成功状态
     */
    val isSuccess: Boolean
        get() = this is Success
    
    /**
     * 判断是否为业务错误状态
     */
    val isError: Boolean
        get() = this is Error
    
    /**
     * 判断是否为异常状态
     */
    val isException: Boolean
        get() = this is Exception
    
    /**
     * 获取数据（如果成功）
     * 
     * @return 成功时返回数据，否则返回 null
     */
    fun getDataOrNull(): T? = when (this) {
        is Success -> data
        else -> null
    }
    
    /**
     * 获取数据（如果成功）或抛出异常
     * 
     * @return 成功时返回数据
     * @throws BusinessException 如果是业务错误
     * @throws ApiException 如果是异常
     */
    fun getDataOrThrow(): T = when (this) {
        is Success -> data
        is Error -> throw BusinessException(code, message)
        is Exception -> throw exception
    }
}
