import axios, { AxiosRequestConfig, AxiosInstance } from 'axios'

export const apiConfig: Partial<AxiosRequestConfig> = {
  timeout: 5000,
  withCredentials: true,
  headers: {},
}

// hack axios全局拦截器的response问题
type OverWriteResponse<T = any> = Promise<T> & any

export class Api {
  api: AxiosInstance

  constructor(config: AxiosRequestConfig = apiConfig) {
    this.api = axios.create(config)

    this.api.interceptors.request.use((param: AxiosRequestConfig) => ({
      ...param,
    }))

    this.api.interceptors.response.use(
      res => {
        // 成功处理
        const { code, msg } = res.data
        if (code === 0) {
          return res.data
        }
        return Promise.reject(msg)
      },
      rej => Promise.reject(rej),
    )
  }

  getUri(config?: AxiosRequestConfig): string {
    return this.api.getUri(config)
  }

  request<T, R = OverWriteResponse<T>>(config: AxiosRequestConfig): Promise<R> {
    return this.api.request(config)
  }

  get<T, R = OverWriteResponse<T>>(url: string, config?: AxiosRequestConfig): Promise<R> {
    return this.api.get(url, config)
  }

  delete<T, R = OverWriteResponse<T>>(url: string, config?: AxiosRequestConfig): Promise<R> {
    return this.api.delete(url, config)
  }

  head<T, R = OverWriteResponse<T>>(url: string, config?: AxiosRequestConfig): Promise<R> {
    return this.api.head(url, config)
  }

  post<T, R = OverWriteResponse<T>>(url: string, data?: any, config?: AxiosRequestConfig): Promise<R> {
    return this.api.post(url, data, config)
  }

  put<T, R = OverWriteResponse<T>>(url: string, data?: any, config?: AxiosRequestConfig): Promise<R> {
    return this.api.put(url, data, config)
  }

  patch<T, R = OverWriteResponse<T>>(url: string, data?: any, config?: AxiosRequestConfig): Promise<R> {
    return this.api.patch(url, data, config)
  }
}

export default new Api()
