/**
 * API 辅助函数
 * 提供类型安全的请求包装和通用错误处理
 */

import type { AxiosRequestConfig } from 'axios'
import type { ApiResponse } from '@/shared/types/types'
import { apiClient } from './client'

/**
 * 包装 API 请求，自动解包响应数据
 */
export async function request<T>(config: AxiosRequestConfig): Promise<T> {
  const response = await apiClient.request<ApiResponse<T>>(config)
  return response.data.data
}

/**
 * GET 请求
 */
export async function get<T>(url: string, config?: AxiosRequestConfig): Promise<T> {
  return request<T>({ ...config, method: 'GET', url })
}

/**
 * POST 请求
 */
export async function post<T>(
  url: string,
  data?: unknown,
  config?: AxiosRequestConfig
): Promise<T> {
  return request<T>({ ...config, method: 'POST', url, data })
}

/**
 * PUT 请求
 */
export async function put<T>(
  url: string,
  data?: unknown,
  config?: AxiosRequestConfig
): Promise<T> {
  return request<T>({ ...config, method: 'PUT', url, data })
}

/**
 * DELETE 请求
 */
export async function del<T>(url: string, config?: AxiosRequestConfig): Promise<T> {
  return request<T>({ ...config, method: 'DELETE', url })
}

/**
 * PATCH 请求
 */
export async function patch<T>(
  url: string,
  data?: unknown,
  config?: AxiosRequestConfig
): Promise<T> {
  return request<T>({ ...config, method: 'PATCH', url, data })
}

/**
 * 静默请求 (不显示错误提示)
 */
export async function silentRequest<T>(config: AxiosRequestConfig): Promise<T> {
  return request<T>({ ...config, silent: true })
}

/**
 * 带重试的请求
 */
export async function requestWithRetry<T>(
  config: AxiosRequestConfig,
  maxRetries = 3,
  retryDelay = 1000
): Promise<T> {
  let lastError: Error | null = null

  for (let attempt = 0; attempt <= maxRetries; attempt++) {
    try {
      return await request<T>(config)
    } catch (error) {
      lastError = error as Error

      // 最后一次尝试，不再重试
      if (attempt === maxRetries) {
        throw error
      }

      // 等待后重试
      await new Promise((resolve) => setTimeout(resolve, retryDelay * (attempt + 1)))
    }
  }

  throw lastError
}

/**
 * 并发请求
 */
export async function concurrent<T extends readonly unknown[]>(
  requests: readonly [...{ [K in keyof T]: Promise<T[K]> }]
): Promise<T> {
  return Promise.all(requests) as Promise<T>
}

/**
 * 串行请求 (按顺序执行)
 */
export async function sequential<T>(
  requestFns: Array<() => Promise<T>>
): Promise<T[]> {
  const results: T[] = []

  for (const requestFn of requestFns) {
    const result = await requestFn()
    results.push(result)
  }

  return results
}

/**
 * 导出所有辅助函数
 */
export const api = {
  request,
  get,
  post,
  put,
  delete: del,
  patch,
  silent: silentRequest,
  retry: requestWithRetry,
  concurrent,
  sequential,
}

export default api
