package com.narutohuo.xindazhou.common.network

import com.narutohuo.xindazhou.common.network.exception.ApiException
import com.narutohuo.xindazhou.common.network.exception.ExceptionHandle
import com.narutohuo.xindazhou.common.network.operator.GlobalApiOperator
import com.narutohuo.xindazhou.common.network.operator.retryRequest
import com.narutohuo.xindazhou.common.network.response.ApiResponse
import com.narutohuo.xindazhou.core.log.ILog
import retrofit2.Response
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext

/**
 * API 基础远程数据源
 * 
 * 封装通用网络请求逻辑，统一处理：
 * - 错误处理和异常捕获
 * - 日志记录
 * - 线程切换（自动切换到 IO 线程）
 * - 网络异常友好提示
 * - 全局处理器（GlobalApiOperator）
 * - 自动重试（可选）
 * 
 * 使用方式：
 * ```kotlin
 * class AuthRemoteDataSource : ApiBaseRemoteDataSource() {
 *     private val authApi: AuthApi = ApiManager.create()
 *     
 *     suspend fun login(request: LoginRequest): ApiResponse<LoginResponse> {
 *         return executeRequestResponse(
 *             request = { authApi.login(request) },
 *             enableRetry = true,
 *             retryTimes = 3
 *         ).onSuccess { data ->
 *             ILog.d("Auth", "登录成功")
 *         }.onError { code, message ->
 *             ILog.w("Auth", "登录失败: $code - $message")
 *         }.onException { exception ->
 *             ILog.e("Auth", "登录异常: ${exception.message}")
 *         }
 *     }
 *     
 *     // 如果需要 Result<T>，使用 toResult() 转换
 *     suspend fun loginAsResult(request: LoginRequest): Result<LoginResponse> {
 *         return executeRequestResponse(
 *             request = { authApi.login(request) }
 *         ).toResult()
 *     }
 * }
 * ```
 */
abstract class ApiBaseRemoteDataSource {
    
    /**
     * 获取日志标签（子类可重写）
     * 
     * 注意：必须使用 public，因为内联函数需要访问此属性
     * 内联函数会将代码复制到调用处，如果使用 protected/private 会导致访问权限错误
     */
    open val tag: String
        get() = this::class.simpleName ?: "ApiBaseRemoteDataSource"
    
    /**
     * 执行请求（新 API，返回 ApiResponse<T>）
     * 
     * 参考 Sandwich 设计，返回统一的 ApiResponse 封装
     * 支持全局处理、自动重试等高级功能
     * 
     * 自动处理：
     * - HTTP 错误码 → Exception
     * - 业务错误码 → Error
     * - 网络异常 → Exception
     * - 全局处理器（GlobalApiOperator）
     * - 自动重试（如果启用）
     * 
     * @param request 网络请求的 suspend 函数
     * @param enableRetry 是否启用自动重试（默认 false）
     * @param retryTimes 重试次数（默认 3 次，仅在 enableRetry = true 时生效）
     * @return ApiResponse<T> 成功返回 Success，业务错误返回 Error，网络异常返回 Exception
     * 
     * 示例：
     * ```kotlin
     * val response = executeRequestResponse(
     *     request = { api.getData() },
     *     enableRetry = true,
     *     retryTimes = 3
     * )
     * 
     * response.onSuccess { data -> ... }
     *         .onError { code, message -> ... }
     *         .onException { exception -> ... }
     * ```
     */
    protected suspend inline fun <reified T> executeRequestResponse(
        crossinline request: suspend () -> Response<ApiCommonResult<T>>,
        enableRetry: Boolean = false,
        retryTimes: Int = 3
    ): ApiResponse<T> = withContext(Dispatchers.IO) {
        val apiResponse = try {
            ILog.d(tag, "开始请求: ${T::class.simpleName}")
            val response = request()
            
            // 解析响应为 ApiResponse（使用新 API）
            ApiResponseParser.parseResponse<T>(response, tag)
        } catch (e: Throwable) {
            // 使用 ExceptionHandle 统一处理异常
            val apiException = ExceptionHandle.handle(e)
            ILog.e(tag, "请求异常: ${apiException.getUserMessage()}", e)
            ApiResponse.Exception(apiException)
        }
        
        // 应用全局处理器
        val processedResponse = GlobalApiOperator.apply(apiResponse)
        
        // 如果需要重试且响应为异常
        if (enableRetry && processedResponse is ApiResponse.Exception) {
            ILog.d(tag, "启用自动重试，重试次数: $retryTimes")
            retryRequest(times = retryTimes) {
                try {
                    val retryResponse = request()
                    ApiResponseParser.parseResponse<T>(retryResponse, tag)
                } catch (e: Throwable) {
                    val apiException = ExceptionHandle.handle(e)
                    ApiResponse.Exception(apiException)
                }
            }
        } else {
            processedResponse
        }
    }
    
    /**
     * 执行可空数据请求（返回 ApiResponse<T?>）
     * 
     * 用于处理服务器可能返回 null 的情况
     * 
     * @param request 网络请求的 suspend 函数
     * @param enableRetry 是否启用自动重试（默认 false）
     * @param retryTimes 重试次数（默认 3 次，仅在 enableRetry = true 时生效）
     * @return ApiResponse<T?> 成功返回数据（可能为 null），失败返回 Error 或 Exception
     */
    protected suspend inline fun <reified T> executeNullableRequestResponse(
        crossinline request: suspend () -> Response<ApiCommonResult<T>>,
        enableRetry: Boolean = false,
        retryTimes: Int = 3
    ): ApiResponse<T?> = withContext(Dispatchers.IO) {
        val apiResponse = try {
            ILog.d(tag, "开始请求（可空）: ${T::class.simpleName}")
            val response = request()
            
            // 解析响应为 ApiResponse（使用新 API，支持可空）
            ApiResponseParser.parseNullableResponse<T>(response, tag)
        } catch (e: Throwable) {
            val apiException = ExceptionHandle.handle(e)
            ILog.e(tag, "请求异常: ${apiException.getUserMessage()}", e)
            ApiResponse.Exception(apiException)
        }
        
        // 应用全局处理器
        val processedResponse = GlobalApiOperator.apply(apiResponse)
        
        // 如果需要重试且响应为异常
        if (enableRetry && processedResponse is ApiResponse.Exception) {
            retryRequest(times = retryTimes) {
                try {
                    val retryResponse = request()
                    ApiResponseParser.parseNullableResponse<T>(retryResponse, tag)
                } catch (e: Throwable) {
                    val apiException = ExceptionHandle.handle(e)
                    ApiResponse.Exception(apiException)
                }
            }
        } else {
            processedResponse
        }
    }
}

