package com.narutohuo.xindazhou.common.network.adapter

import com.narutohuo.xindazhou.common.network.ApiCommonResult
import com.narutohuo.xindazhou.common.network.ApiResponseParser
import com.narutohuo.xindazhou.common.network.response.ApiResponse
import retrofit2.Call
import retrofit2.CallAdapter
import retrofit2.Response
import retrofit2.Retrofit
import java.lang.reflect.ParameterizedType
import java.lang.reflect.Type

/**
 * Retrofit CallAdapter Factory for ApiResponse
 * 
 * 自动将 Retrofit 接口的返回类型从 `Response<ApiCommonResult<T>>` 转换为 `ApiResponse<T>`
 * 
 * 使用方式：
 * ```kotlin
 * // Retrofit 接口定义
 * interface AuthApi {
 *     @POST("auth/login")
 *     suspend fun login(@Body request: LoginRequest): ApiResponse<LoginResponse>
 * }
 * 
 * // Retrofit 配置（在 NetworkManager 中自动配置）
 * Retrofit.Builder()
 *     .baseUrl("https://api.example.com")
 *     .addCallAdapterFactory(ApiResponseCallAdapterFactory.create())
 *     .addConverterFactory(GsonConverterFactory.create())
 *     .build()
 * ```
 * 
 * 参考 Sandwich 的 ApiResponseCallAdapterFactory 设计
 */
object ApiResponseCallAdapterFactory : CallAdapter.Factory() {
    
    /**
     * 创建 CallAdapter 实例
     * 
     * 在 Retrofit 配置时调用：
     * ```kotlin
     * Retrofit.Builder()
     *     .addCallAdapterFactory(ApiResponseCallAdapterFactory.create())
     *     .build()
     * ```
     */
    fun create(): CallAdapter.Factory {
        return ApiResponseCallAdapterFactory
    }
    
    override fun get(
        returnType: Type,
        annotations: Array<Annotation>,
        retrofit: Retrofit
    ): CallAdapter<*, *>? {
        // 检查返回类型是否是 ApiResponse
        val rawType = getRawType(returnType)
        if (rawType != ApiResponse::class.java) {
            return null
        }
        
        // 检查是否是 ParameterizedType（必须有泛型参数）
        if (returnType !is ParameterizedType) {
            throw IllegalStateException("ApiResponse 必须指定泛型参数，例如：ApiResponse<LoginResponse>")
        }
        
        // 提取泛型参数类型（ApiResponse<T> 中的 T）
        val responseType = getParameterUpperBound(0, returnType)
        
        return ApiResponseCallAdapter(responseType)
    }
    
    /**
     * ApiResponse CallAdapter 实现
     * 
     * 将 Retrofit 的 Call<Response<ApiCommonResult<T>>> 适配为 suspend 函数返回 ApiResponse<T>
     * 
     * 注意：对于 suspend 函数，Retrofit 会自动处理 Call 的执行，我们只需要在这里进行类型转换
     */
    private class ApiResponseCallAdapter(
        private val responseType: Type
    ) : CallAdapter<Response<ApiCommonResult<*>>, ApiResponse<*>> {
        
        override fun responseType(): Type {
            // 创建 ParameterizedType: Response<ApiCommonResult<responseType>>
            return object : ParameterizedType {
                override fun getRawType(): Type = Response::class.java
                override fun getOwnerType(): Type? = null
                override fun getActualTypeArguments(): Array<Type> = arrayOf(
                    object : ParameterizedType {
                        override fun getRawType(): Type = ApiCommonResult::class.java
                        override fun getOwnerType(): Type? = null
                        override fun getActualTypeArguments(): Array<Type> = arrayOf(responseType)
                    }
                )
            }
        }
        
        override fun adapt(call: Call<Response<ApiCommonResult<*>>>): ApiResponse<*> {
            // 执行网络请求（对于 suspend 函数，Retrofit 会自动在协程中执行）
            val response = call.execute()
            
            // 使用 ApiResponseParser 解析 Response<ApiCommonResult<*>> 为 ApiResponse<*>
            // 这里需要将 ApiResponse<*> 转换为正确的类型，但由于类型擦除，我们无法在运行时确定
            // 所以使用 @Suppress("UNCHECKED_CAST")
            @Suppress("UNCHECKED_CAST")
            return ApiResponseParser.parseResponse(response as Response<ApiCommonResult<Any>>, "ApiResponseCallAdapter") as ApiResponse<*>
        }
    }
}