import axios, {
  AxiosError,
  type AxiosInstance,
  type AxiosRequestConfig,
  type AxiosResponse,
  type InternalAxiosRequestConfig,
} from 'axios'

export interface LegacyApiSuccess<T> {
  success: true
  msg?: string
  data?: T
}

export interface LegacyApiFailure {
  success: false
  error?: string
}

export type ApiResponse<T> = LegacyApiSuccess<T> | LegacyApiFailure
export interface JavaApiResponse<T> {
  success: boolean
  message: string
  data: T | null
}
export type RequestOptions<D = unknown> = AxiosRequestConfig<D>

function extractErrorMessage(error: unknown) {
  if (error instanceof AxiosError) {
    const data = error.response?.data

    if (data && typeof data === 'object') {
      if ('error' in data && data.error) {
        return String(data.error)
      }
      if ('message' in data && data.message) {
        return String(data.message)
      }
    }

    if (typeof data === 'string' && data.trim()) {
      return data
    }

    return error.message || '请求失败'
  }

  return error instanceof Error ? error.message : '请求失败'
}

function createHttpClient(): AxiosInstance {
  const instance = axios.create({
    withCredentials: true,
    timeout: 30000,
    headers: {
      'X-Requested-With': 'XMLHttpRequest',
    },
  })

  instance.interceptors.request.use((config: InternalAxiosRequestConfig) => {
    return config
  })

  instance.interceptors.response.use(
    (response: AxiosResponse) => response,
    (error: unknown) => Promise.reject(new Error(extractErrorMessage(error))),
  )

  return instance
}

export const http = createHttpClient()

export async function request<T = unknown, D = unknown>(config: RequestOptions<D>): Promise<T> {
  const response = await http.request<T, AxiosResponse<T>, D>(config)
  return response.data
}

export function get<T = unknown>(url: string, config?: RequestOptions) {
  return request<T>({
    url,
    method: 'GET',
    ...config,
  })
}

export function post<T = unknown, D = unknown>(url: string, data?: D, config?: RequestOptions<D>) {
  return request<T, D>({
    url,
    method: 'POST',
    data,
    ...config,
  })
}

export function put<T = unknown, D = unknown>(url: string, data?: D, config?: RequestOptions<D>) {
  return request<T, D>({
    url,
    method: 'PUT',
    data,
    ...config,
  })
}

export function del<T = unknown>(url: string, config?: RequestOptions) {
  return request<T>({
    url,
    method: 'DELETE',
    ...config,
  })
}

export const requestJson = request
export const requestGetJson = get
export const requestPostJson = post
export const requestPutJson = put
export const requestDeleteJson = del

export async function unwrapJavaResponse<T>(promise: Promise<JavaApiResponse<T>>) {
  const response = await promise
  if (!response.success) {
    throw new Error(response.message || '请求失败')
  }
  return response.data as T
}
