// 统一的API客户端
import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios'
import type { ApiResponse, ApiError } from '@/types/api'

// 根据环境配置 API 基础地址
// Mock 模式下使用相对路径，这样 MSW 才能拦截请求
const getBaseUrl = () => {
  if (import.meta.env.DEV && import.meta.env.VITE_USE_MOCK === 'true') {
    // Mock 模式下使用相对路径
    return '/api/v1'
  }
  // 生产或非 Mock 模式下使用环境变量配置
  return import.meta.env.VITE_API_BASE_URL || '/api/v1'
}

class ApiClient {
  private instance: AxiosInstance
  
  constructor() {
    this.instance = axios.create({
      baseURL: getBaseUrl(),
      timeout: 30000,
      headers: {
        'Content-Type': 'application/json',
      },
    })
    
    this.setupInterceptors()
  }
  
  // 设置请求和响应拦截器
  private setupInterceptors() {
    // 请求拦截器
    this.instance.interceptors.request.use(
      (config) => {
        // 添加认证token
        const token = this.getAuthToken()
        if (token) {
          config.headers.Authorization = `Bearer ${token}`
        }
        
        // 添加请求ID用于追踪
        config.headers['X-Request-ID'] = this.generateRequestId()
        
        // 添加时间戳防止缓存
        if (config.method?.toLowerCase() === 'get') {
          config.params = {
            ...config.params,
            _t: Date.now(),
          }
        }
        
        // 开发环境打印请求
        if (import.meta.env.DEV) {
          console.log('🚀 API Request:', config.method?.toUpperCase(), config.url, config.params || config.data)
        }
        
        return config
      },
      (error) => {
        return Promise.reject(this.handleRequestError(error))
      }
    )
    
    // 响应拦截器
    this.instance.interceptors.response.use(
      (response) => {
        // 开发环境打印响应
        if (import.meta.env.DEV) {
          console.log('✅ API Response:', response.config.method?.toUpperCase(), response.config.url, response.data)
        }
        
        return this.handleResponse(response)
      },
      (error) => {
        return Promise.reject(this.handleResponseError(error))
      }
    )
  }
  
  // 获取认证token
  private getAuthToken(): string | null {
    return localStorage.getItem('auth_token')
  }
  
  // 生成请求ID
  private generateRequestId(): string {
    return `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`
  }
  
  // 处理响应数据
  private handleResponse(response: AxiosResponse): any {
    const { data, status } = response
    
    // 处理后端返回的统一格式
    if (data && typeof data === 'object') {
      // 如果是业务错误，抛出异常
      if (data.code && data.code !== 0 && data.code !== 200) {
        const error: ApiError = {
          code: data.code,
          message: data.message || '请求失败',
          details: data.data,
        }
        throw error
      }
      
      // 返回数据部分
      return data.data !== undefined ? data.data : data
    }
    
    return data
  }
  
  // 处理请求错误
  private handleRequestError(error: any): ApiError {
    console.error('❌ Request Error:', error)
    return {
      code: -1,
      message: '网络请求失败，请检查网络连接',
      details: error.message,
    }
  }
  
  // 处理响应错误
  private handleResponseError(error: any): ApiError {
    console.error('❌ Response Error:', error)
    
    if (error.response) {
      const { status, data } = error.response
      
      switch (status) {
        case 400:
          return {
            code: data?.code || 400,
            message: data?.message || '请求参数错误',
            details: data,
          }
        case 401:
          // 清除token并跳转登录
          localStorage.removeItem('auth_token')
          window.location.href = '/login'
          return {
            code: 401,
            message: '登录已过期，请重新登录',
            details: data,
          }
        case 403:
          return {
            code: 403,
            message: '权限不足',
            details: data,
          }
        case 404:
          return {
            code: 404,
            message: '接口不存在',
            details: data,
          }
        case 409:
          return {
            code: 409,
            message: data?.message || '资源冲突',
            details: data,
          }
        case 500:
          return {
            code: 500,
            message: '服务器内部错误',
            details: data,
          }
        default:
          return {
            code: status,
            message: data?.message || `请求失败 (${status})`,
            details: data,
          }
      }
    } else if (error.request) {
      return {
        code: -1,
        message: '网络连接失败，请检查网络设置',
        details: error.message,
      }
    } else {
      return {
        code: -1,
        message: error.message || '未知错误',
        details: error,
      }
    }
  }
  
  // 通用请求方法
  public async request<T = any>(config: AxiosRequestConfig): Promise<T> {
    return this.instance.request(config)
  }
  
  // GET请求
  public async get<T = any>(url: string, params?: any, config?: AxiosRequestConfig): Promise<T> {
    return this.instance.get(url, { params, ...config })
  }
  
  // POST请求
  public async post<T = any>(url: string, data?: any): Promise<T> {
    return this.instance.post(url, data)
  }
  
  // PUT请求
  public async put<T = any>(url: string, data?: any): Promise<T> {
    return this.instance.put(url, data)
  }
  
  // DELETE请求
  public async delete<T = any>(url: string): Promise<T> {
    return this.instance.delete(url)
  }
  
  // PATCH请求
  public async patch<T = any>(url: string, data?: any): Promise<T> {
    return this.instance.patch(url, data)
  }
}

// 导出单例实例
export const apiClient = new ApiClient()

// 导出类用于测试
export { ApiClient }
