import axios from 'axios'
import { getToken } from '@/utils/auth'

const BASE_URL = import.meta.env.VITE_API_BASE_URL || '/api'
const TIMEOUT = 30000
const SUCCESS_CODES = [0, 200, 20000]

function normalizeError(error) {
  if (error?.response) {
    const status = error.response.status
    const data = error.response.data || {}
    return new Error(data.message || `请求失败，状态码：${status}`)
  }
  if (error?.request) {
    return new Error('请求未响应，请检查网络或服务是否可用。')
  }
  return new Error(error.message || '未知请求错误')
}

const service = axios.create({
  baseURL: BASE_URL,
  timeout: TIMEOUT,
  headers: {
    'Content-Type': 'application/json;charset=utf-8'
  }
})

service.interceptors.request.use(
  (config) => {
    const token = getToken()
    if (token && config.headers?.isToken !== false) {
      config.headers.token = `${token}`
    }

    if (config.data instanceof FormData) {
      delete config.headers['Content-Type']
    }

    return config
  },
  (error) => Promise.reject(normalizeError(error))
)

service.interceptors.response.use(
  (response) => {
    const { data, config } = response
    if (config.responseType === 'blob' || config.responseType === 'arraybuffer') {
      return data
    }
    if (data && typeof data === 'object' && 'code' in data) {
      if (SUCCESS_CODES.includes(data.code)) {
        return data
      }
      return Promise.reject(new Error(data.message || `接口返回异常，code=${data.code}`))
    }
    return data
  },
  (error) => Promise.reject(normalizeError(error))
)

export function request({ url, method = 'get', params = {}, data = {}, headers = {}, ...config }) {
  return service({ url, method, params, data, headers, ...config })
}

export function get(url, params = {}, config = {}) {
  return service.get(url, { params, ...config })
}

export function post(url, data = {}, config = {}) {
  return service.post(url, data, config)
}

export function put(url, data = {}, config = {}) {
  return service.put(url, data, config)
}

export function remove(url, params = {}, config = {}) {
  return service.delete(url, { params, ...config })
}

export function upload(url, formData, config = {}) {
  return service.post(url, formData, {
    headers: {
      'Content-Type': 'multipart/form-data',
      ...config.headers
    },
    ...config
  })
}

export async function download(url, params = {}, filename = 'download.bin') {
  const response = await service.get(url, {
    params,
    responseType: 'blob'
  })
  const blob = new Blob([response], { type: response.type })
  const link = document.createElement('a')
  link.href = window.URL.createObjectURL(blob)
  link.download = filename
  document.body.appendChild(link)
  link.click()
  link.remove()
  window.URL.revokeObjectURL(link.href)
}

export default service
