import axios from "axios";
import store from "/@/store";
import { isDev } from "/@/config/env";
import { href, storage } from "/@/cool/utils";
import NProgress from "nprogress";
import "nprogress/nprogress.css";
import { ElMessage } from "element-plus";

axios.defaults.timeout = 30000;
axios.defaults.withCredentials = true;

NProgress.configure({
  showSpinner: false
});

// 请求队列
let requests: Array<Function> = [];

// Token 是否刷新中
let isRefreshing = false;

// 忽略规则
const ignore = {
  NProgress: ["/sys/info/record"],
  token: ["/login", "/captcha"]
};

// Request
axios.interceptors.request.use(
  (config: any) => {
    const token = store.getters.token || "";

    if (config.url) {
      if (!ignore.token.some((e) => config.url.includes(e))) {
        config.headers["Authorization"] = token;
      }

      if (!ignore.NProgress.some((e) => config.url.includes(e))) {
        NProgress.start();
      }
    }

    // 请求信息
    if (isDev) {
      console.log("config:", config);
      console.group(config.url);
      console.log("method:", config.method);
      console.table("data:", config.method == "get" ? config.params : config.data);
      console.groupEnd();
    }

    // 验证 token
    if (token) {
      if (config.url.includes("refreshToken")) {
        return config;
      }

      // 判断 token 是否过期
      if (storage.isExpired("token")) {
        // 判断 refreshToken 是否过期
        if (storage.isExpired("refreshToken")) {
          store.dispatch("userRemove");
          return href("/login");
        }

        // 是否在刷新中
        if (!isRefreshing) {
          isRefreshing = true;

          store.dispatch("refreshToken").then((token: string) => {
            requests.forEach((cb) => cb(token));
            requests = [];
            isRefreshing = false;
          });
        }

        return new Promise((resolve) => {
          // 继续请求
          requests.push((token: string) => {
            // 重新设置 token
            config.headers["Authorization"] = token;
            resolve(config);
          });
        });
      }
    }

    return config;
  },
  (error) => {
    return Promise.reject(error);
  }
);

// Response
axios.interceptors.response.use(
  (res) => {
    NProgress.done();
    const { code, data, message } = res.data;

    if (!res.data) {
      return res;
    }

    switch (code) {
      case 1000:
        return data;
      default:
        return Promise.reject(message);
    }
  },
  async (error) => {
    NProgress.done();

    if (error.response) {
      const { status, config } = error.response;

      switch (status) {
        case 401:
          await store.dispatch("userRemove");
          href("/login");
          break;

        case 403:
          if (isDev) {
            ElMessage.error(`${config.url} 无权限访问！！`);
          } else {
            href("/403");
          }
          break;

        case 404:
          break;

        case 500:
          if (!isDev) {
            href("/500");
          }
          break;

        case 502:
          if (isDev) {
            ElMessage.error(`${config.url} 服务异常！！`);
          } else {
            href("/502");
          }
          break;

        default:
          console.error(status, config.url);
      }
    }

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

export default axios;
