import axios, { AxiosInstance, InternalAxiosRequestConfig } from "axios";
import { userStore } from "@/stores/user";
import BfApiMessage from "@/enums/bfApiMessage";
import { getErrorMessage } from "@/utils/httpStatus";
import { bfErrorMessage } from "@/utils/bfMessage";

// 定义用户类型
interface User {
  token: string | null;
}

// 获取消息函数，用于根据消息码获取具体的消息文本
const getBfMessage = (message: string) => {
  return BfApiMessage[message] || message;
};

// 用户退出登录
export const logoutUser = () => {
  userStore().logout();
};

// 处理特定错误情况，例如用户会话过期
const handleSpecialCases = (message: string) => {
  if (message === BfApiMessage.USER_EXPIRED) {
    logoutUser();
  }
};

// 扩展 Axios 请求配置，添加自定义属性 requireToken
interface CustomAxiosRequestConfig extends InternalAxiosRequestConfig {
  requireToken?: boolean; // 请求头是否需要Token
  Tenant?: string; // 店铺id
}

// 创建 Axios 实例
const createInstance = (baseURL: string): AxiosInstance => {
  // 创建 Axios 实例并设置基础 URL 和超时时间
  const instance: AxiosInstance = axios.create({
    baseURL,
    timeout: 100000,
  });

  // 请求拦截器
  instance.interceptors.request.use(
    async (config: CustomAxiosRequestConfig) => {
      const user: User = userStore();
      // 如果用户有 token 并且 requireToken 不为 false，则添加 Authorization 头
      if (user.token && config.requireToken !== false) {
        config.headers.set("Authorization", `Bearer ${user.token}`);
      }
      if (config.Tenant) {
        // TODO 添加店铺ID
        config.headers.set("Tenant", config.Tenant);
      }
      return config;
    },
    (error) => {
      // 处理请求错误
      return Promise.reject(error);
    }
  );

  // 响应拦截器
  instance.interceptors.response.use(
    async (response) => {
      const { code, message } = response.data;
      // 检查响应是否成功
      if (code === 0) {
        return response.data;
      }
      // 错误消息提示
      bfErrorMessage(getBfMessage(message));
      // 处理特定错误情况
      handleSpecialCases(message);
      return Promise.reject(response.data);
    },
    async (error) => {
      // 处理 HTTP 错误
      if (error && error.response) {
        error.message = getErrorMessage(error.response.status);
      } else {
        error.message = "连接服务器失败!";
      }
      // 退出登录
      logoutUser();
      // 如果错误是由于超时导致的，可以进行重试
      if (error.code === "ECONNABORTED" || error.response?.status === 504) {
        return retryRequest(error.config, error.message);
      }
      bfErrorMessage(error.message);
      return Promise.reject(error);
    }
  );

  return instance;
};

// 实现重试逻辑，最多重试两次
const retryRequest = async (config: any, errMessage: string) => {
  const maxRetries = 2;
  let retries = 0;
  while (retries < maxRetries) {
    try {
      // 等待 1 秒后再重试
      await new Promise((resolve) => setTimeout(resolve, 1000));
      const response = await axios.request(config);
      return response.data;
    } catch (error) {
      retries++;
      if (retries >= maxRetries) {
        bfErrorMessage(errMessage);
        throw error;
      }
    }
  }
};

// 导出封装的 Axios 实例
export const instanceReal: AxiosInstance = createInstance(
  import.meta.env.VITE_API_BASE_URL
);
// 导出封装的 Axios 实例
export const instanceDiy: AxiosInstance = createInstance(
    import.meta.env.VITE_API_DIY_BASE_URL
);

// 导出封装的 Axios 实例
export const instanceThreeReal: AxiosInstance = createInstance(
    import.meta.env.VITE_API_DIY_REAL_URL
);
