import axios, { type AxiosRequestConfig, type AxiosResponse } from "axios";

/**
 * 创建默认 Axios 实例
 */
const axiosInstance = axios.create({
  //#vite.config.ts中的proxy配置;不需要修改
  baseURL: "/api",
  timeout: 30000,
});

/**
 * 响应拦截器 - 处理统一响应格式
 */
axiosInstance.interceptors.response.use(
  async (response) => {
    // console.error("请求响应-1:", response);
    const { data, config } = response;

    // 处理 Blob 响应（Orval 默认使用 blob）
    if (config?.responseType === "blob") {
      // 如果是 JSON 响应被当作 blob 处理，需要解析
      if (data instanceof Blob) {
        const text = await data.text();
        try {
          const jsonData = JSON.parse(text);
          // 处理标准响应格式 { code, message, data }
          if (
            typeof jsonData === "object" &&
            jsonData !== null &&
            "code" in jsonData
          ) {
            if (jsonData.code === 200 || jsonData.code === 0) {
              return jsonData.data;
            }
            // 业务错误码，抛出错误
            const error: any = new Error(jsonData.message || "请求失败");
            error.response = { data: jsonData, status: 200 };
            error.code = jsonData.code;
            return Promise.reject(error);
          }
          return jsonData;
        } catch {
          // 不是 JSON，返回原始 blob
          return data;
        }
      }
      return data;
    }

    // 处理标准响应格式 { code, message, data }
    if (typeof data === "object" && data !== null && "code" in data) {
      if (data.code === 200 || data.code === 0) {
        // 返回 data 字段
        return data.data;
      }
      // 业务错误码，抛出错误
      const error: any = new Error(data.message || "请求失败");
      error.response = { data, status: 200 };
      error.code = data.code;
      return Promise.reject(error);
    }

    return data;
  },
  async (error) => {
    const status = error.response?.status;
    // axios 在 responseType=blob 且非 2xx 时，error.response.data 往往是 Blob（即使实际是 JSON）
    const maybeBlob = error.response?.data;
    if (maybeBlob instanceof Blob) {
      try {
        const text = await maybeBlob.text();
        const jsonData = JSON.parse(text);
        if (jsonData && typeof jsonData === "object") {
          // 统一把解析后的 JSON 写回，便于业务侧 error.response.data.message 读取
          error.response.data = jsonData;
          // 同步 Error.message，便于直接用 error.message 展示
          if (
            typeof (jsonData as any).message === "string" &&
            (jsonData as any).message
          ) {
            error.message = (jsonData as any).message;
          }
        }
      } catch {
        // ignore: 不是 JSON 或解析失败
      }
    }

    const message = error.response?.data?.message || error.message;
    // console.error("请求失败-1:", error);
    switch (status) {
      case 401:
        localStorage.removeItem("token");
        localStorage.removeItem("user");
        window.location.href = "/login";
        break;
      case 403:
        console.error("没有权限访问该资源");
        break;
      case 404:
        console.error("请求的资源不存在");
        break;
      case 500:
        console.error("服务器内部错误");
        break;
      default:
        console.error("请求失败:", message);
    }

    return Promise.reject(error);
  },
);

/**
 * 自定义请求拦截器（Mutator）
 *
 * Orval 生成的 API 客户端会调用此函数来发送请求
 *
 * @param options - Axios 请求配置
 * @returns Promise<AxiosResponse>
 */
export const customMutator = async <T = any>(
  options: AxiosRequestConfig,
): Promise<AxiosResponse<T>> => {
  // 自动添加 JWT Token
  const token = localStorage.getItem("token");
  if (token) {
    options.headers = {
      ...options.headers,
      Authorization: `Bearer ${token}`,
    };
  }

  return axiosInstance(options);
};

/**
 * 导出 axios 实例供其他地方使用
 */
export { axiosInstance as axios };
