import axios from 'axios'
import type {
  AxiosError,
  AxiosRequestConfig,
  AxiosResponse,
} from 'axios'
import type { EnvConfKey } from '@/config/env'
import { envConf } from '@/config/env'

export interface Response<T> {
  data: T
  config: AxiosRequestConfig
}

export interface ResponseData<T = any> {
  code: string
  message: string
  data: T
  ok: boolean
}

const mode = import.meta.env.MODE as EnvConfKey

const service = axios.create({
  timeout: 300000,
  baseURL: envConf[mode].apiUrl,
})

service.interceptors.request.use(
  (config: any) => {
    config.headers = {
      'X-Token': JSON.parse(window.localStorage.getItem('__TOKEN__') || ''),
      'X-Request-Id': `${Date.now()}${Math.random().toString(36).substring(2)}`,
      'X-Request-By': config.url,
      // 'X-App-Type': getAppType() || '',
      // 'X-Channel-Code': getChannelCode() || '',
    }
    return config
  },
  (error: AxiosError) => {
    // showToast(error.message)
    return Promise.reject(error)
  },
)

service.interceptors.response.use(
  (response: AxiosResponse<any, Response<ResponseData>>) => {
    const { code, message } = response.data
    if (response.config.responseType === 'stream')
      return response

    if (code === '00000000') {
      return response.data
    }
    else if (code === '00000005') {
      // 处理登录失效
    }
    else {
      // showToast(message)
      return Promise.reject(new Error(message))
    }
  },
  (error: AxiosError) => {
    // showToast('网络请求异常')
    return Promise.reject(error)
  },
)

/* 导出封装的请求方法 */
export const http = {
  get<T = any>(url: string, config?: AxiosRequestConfig): Promise<T> {
    return service.get(url, config)
  },

  post<T = any>(
    url: string,
    data?: object,
    config?: AxiosRequestConfig,
  ): Promise<T> {
    return service.post(url, data, config)
  },

  put<T = any>(
    url: string,
    data?: object,
    config?: AxiosRequestConfig,
  ): Promise<T> {
    return service.put(url, data, config)
  },

  delete<T = any>(url: string, config?: AxiosRequestConfig): Promise<T> {
    return service.delete(url, config)
  },
  stream<T = any>(url: string, data: T) {
    return service.post(url, data, {
      responseType: 'stream',
    })
  },
}

/* 导出 axios 实例 */
export default service
