package com.narutohuo.xindazhou.common.network.exception

import com.narutohuo.xindazhou.core.log.ILog
import retrofit2.HttpException as RetrofitHttpException
import java.net.SocketTimeoutException
import java.net.UnknownHostException
import java.net.ConnectException
import javax.net.ssl.SSLException

/**
 * 统一异常处理类
 * 
 * 负责将各种异常转换为统一的 ApiException
 * 提供统一的错误处理逻辑，业务层只需要处理 ApiException
 * 
 * 使用方式：
 * ```kotlin
 * try {
 *     val result = api.call()
 * } catch (e: Throwable) {
 *     val apiException = ExceptionHandle.handle(e)
 *     // 统一处理 ApiException
 *     when (apiException) {
 *         is NetworkException -> { ... }
 *         is BusinessException -> { ... }
 *         is HttpException -> { ... }
 *     }
 * }
 * ```
 */
object ExceptionHandle {
    
    private const val TAG = "ExceptionHandle"
    
    /**
     * 处理异常，转换为统一的 ApiException
     * 
     * @param throwable 原始异常
     * @param defaultMessage 默认错误消息（可选）
     * @return ApiException 统一异常对象
     */
    fun handle(throwable: Throwable, defaultMessage: String = "操作失败"): ApiException {
        return when (throwable) {
            // 已经是 ApiException，直接返回
            is ApiException -> {
                ILog.d(TAG, "已经是 ApiException: ${throwable::class.simpleName}, message: ${throwable.message}")
                throwable
            }
            
            // Retrofit 的 HttpException（HTTP 状态码错误）
            is RetrofitHttpException -> {
                val code = throwable.code()
                val message = throwable.message()
                ILog.w(TAG, "HTTP 异常: code=$code, message=$message")
                HttpException(code, message, throwable)
            }
            
            // 网络超时
            is SocketTimeoutException -> {
                val message = "请求超时，请检查网络连接"
                ILog.e(TAG, message, throwable)
                NetworkException(message, throwable)
            }
            
            // 无法连接到服务器（DNS 解析失败、无网络等）
            is UnknownHostException -> {
                val message = "网络连接失败，请检查网络设置"
                ILog.e(TAG, message, throwable)
                NetworkException(message, throwable)
            }
            
            // 连接异常
            is ConnectException -> {
                val message = "无法连接到服务器，请检查网络"
                ILog.e(TAG, message, throwable)
                NetworkException(message, throwable)
            }
            
            // SSL 异常
            is SSLException -> {
                val message = "安全连接失败，请检查网络设置"
                ILog.e(TAG, message, throwable)
                NetworkException(message, throwable)
            }
            
            // 其他异常（兜底处理）
            else -> {
                val message = throwable.message ?: defaultMessage
                ILog.e(TAG, "未知异常: $message", throwable)
                UnknownApiException(message, throwable)
            }
        }
    }
    
    /**
     * 处理 HTTP 响应错误（非 2xx 状态码）
     * 
     * @param code HTTP 状态码
     * @param message 错误消息
     * @return HttpException
     */
    fun handleHttpError(code: Int, message: String? = null): HttpException {
        ILog.w(TAG, "HTTP 错误: code=$code, message=$message")
        return HttpException(code, message)
    }
    
    /**
     * 处理业务错误（业务状态码错误）
     * 
     * @param code 业务状态码
     * @param message 错误消息
     * @return BusinessException
     */
    fun handleBusinessError(code: Int, message: String? = null): BusinessException {
        ILog.w(TAG, "业务错误: code=$code, message=$message")
        return BusinessException(code, message)
    }
    
    /**
     * 处理数据解析错误
     * 
     * @param message 错误消息
     * @param cause 原始异常
     * @return ParseException
     */
    fun handleParseError(message: String = "数据解析失败", cause: Throwable? = null): ParseException {
        ILog.e(TAG, message, cause)
        return ParseException(message, cause)
    }
}

