// src/utils/request.ts
import axios from 'axios'
import type {
  AxiosError,
  AxiosRequestConfig,
  AxiosResponse,
} from 'axios'
import type { EnvConfKey } from '@/config/env'
import { envConf } from '@/config/env'
import { safeLocalStorageClear, safeLocalStorageGetItem } from '@/lib/utils'

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) => {
    let token = ''
    try {
      // 使用安全函数获取 token，避免在第三方页面中访问 localStorage 被阻止
      const tokenStr = safeLocalStorageGetItem('__TOKEN__')
      if (tokenStr) {
        // useLocalStorageState 会将值序列化为 JSON，需要解析
        token = JSON.parse(tokenStr) || ''
      }
    }
    catch {
      // 如果解析失败，使用空字符串
      token = ''
    }
    config.headers = {
      'X-Token': token,
      'X-Request-Id': `${Date.now()}${Math.random().toString(36).substring(2)}`,
      'X-Request-By': config.url,
    }
    return config
  },
  (error: AxiosError) => {
    return Promise.reject(error)
  },
)

service.interceptors.response.use(
  (response: AxiosResponse<any, Response<ResponseData>>) => {
    const { code, message } = response.data

    // 处理 blob 响应类型
    if (response.config.responseType === 'blob') {
      return response
    }

    if (response.config.responseType === 'stream') {
      return response
    }

    if (code === '00000000') {
      return response.data
    }
    else if (code === '00000005') {
      // 处理登录失效（使用安全函数，避免在第三方页面中被阻止）
      safeLocalStorageClear()
    }
    else {
      return Promise.reject(new Error(message))
    }
  },
  (error: AxiosError) => {
    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
