import axios from "axios";
import type { AxiosInstance, AxiosRequestConfig, AxiosResponse, InternalAxiosRequestConfig } from "axios";
import { ElNotification } from 'element-plus';
import router from "@/router";
let bool = false;
function layout(text?: string) {
  !bool && ElNotification.error({
    title: "通知",
    message: text || "登录超时",
  });
  !bool && router.push("/login");
  bool = true
  const timout = setTimeout(() => {
    bool = false
    clearTimeout(timout);
  }, 4500)
}

const regex = /^2([0-9]{2})$/; //判断数字大于等于200，小于300

interface ISettings {
  prompt?: boolean; //报错是否全局提示
}

type jsonData = Record<string, any>;

class Config {
  private instance: AxiosInstance;
  private settings: ISettings;
  constructor(
    requeseConfig,
    settings = { prompt: true },
  ) {
    this.instance = axios.create(requeseConfig);
    this.settings = settings;
    // 全局请求拦截
    this.instance.interceptors.request.use(
      (config: InternalAxiosRequestConfig) => {
        if (config.baseURL === "/console/api") {
          config.headers["Authorization"] =  "Bearer " + sessionStorage.getItem("token");
        } else if (config.baseURL === "/api") {
          config.headers["Authorization"] =  "Bearer " + sessionStorage.getItem("console-token");
        }
        return config;
      },
      (error) => {
        return error;
      },
    );
    // 全局响应拦截
    this.instance.interceptors.response.use(
      (res) => {
        if (res.data.status === 401) {
          layout();
          return;
        }
        return res;
      },
      (error) => {
        if (error?.response) {
          switch (error.response.status) {
            case 400:
              this.settings?.prompt &&
                ElNotification.error({
                  title: "通知",
                  message: error.response.data.message,
                });
              break;
            case 401:
              layout(error.response.data.message);
              break;
            case 403:
              this.settings?.prompt &&
                ElNotification.error({
                  title: "通知",
                  message: error.response.data.message,
                });
              break;
            case 404:
              this.settings?.prompt &&
                ElNotification.error({
                  title: "通知",
                  message: error.response.data.message,
                });
              break;
            case 405:
              this.settings?.prompt &&
                ElNotification.error({
                  title: "通知",
                  message:
                    "请求方法未允许   " + error.response.data.message,
                });
              break;
            case 408:
              this.settings?.prompt &&
                ElNotification.error({
                  title: "通知",
                  message: error.response.data.message,
                });
              break;
            case 413:
              this.settings?.prompt &&
              ElNotification.error({
                title: "通知",
                message: error.response.data.message,
              });
              break;
            case 409:
              this.settings?.prompt &&
              ElNotification.error({
                title: "通知",
                message: error.response.data.message,
              });
              break;
            case 500:
              this.settings?.prompt &&
                ElNotification.error({
                  title: "通知",
                  message: error.response.data.message || error.response.data.statusText,
                });
              break;
            case 501:
              this.settings?.prompt &&
                ElNotification.error({
                  title: "通知",
                  message: "网络未实现",
                });
              break;
            case 502:
              this.settings?.prompt &&
                ElNotification.error({
                  title: "服务异常",
                  message: "服务重启中...",
                });
              break;
            case 503:
              this.settings?.prompt &&
                ElNotification.error({
                  title: "服务异常",
                  message: "服务重启中...",
                });
              break;
            case 504:
              this.settings?.prompt &&
                ElNotification.error({
                  title: "通知",
                  message: "网络超时",
                });
              break;
            case 505:
              this.settings?.prompt &&
                ElNotification.error({
                  title: "通知",
                  message: "http版本不支持该请求",
                });
              break;
            default:
              this.settings?.prompt &&
                ElNotification.error({
                  title: "通知",
                  message: `连接错误`,
                });
          }
        }
        return error?.response?.data || error;
      },
    );
  }
  get(url: string, params?: jsonData, headers?: jsonData) {
    return new Promise<any>((resolve, reject) => {
      this.instance
        .get(url, { params, headers })
        .then((res) => {
          if (regex.test(res.status as any as string)) {
            resolve(res.data);
          } else {
            reject(res)
          }
        })
        .catch((err) => {
          reject(err);
        });
    });
  }

  post(url: string, data?: any, params?: jsonData, headers?: jsonData) {
    return new Promise<any>((resolve, reject) => {
      this.instance
        .post(url, data, { params, headers })
        .then((res) => {
          if (regex.test(res.status as any as string)) {
            resolve(res.data);
          } else {
            reject(res)
          }
        })
        .catch((err) => {
          reject(err);
        });
    });
  }

  delete(url: string, config?: AxiosRequestConfig) {
    return new Promise<any>((resolve, reject) => {
      this.instance
        .delete(url, config)
        .then((res) => {
          if (regex.test(res.status as any as string)) {
            resolve(res.data);
          } else {
            reject(res)
          }
        })
        .catch((err) => {
          reject(err);
        });
    });
  }

  put(url: string, data: any, params?: jsonData, headers?: jsonData) {
    return new Promise<any>((resolve, reject) => {
      this.instance
        .put(url, data, { params, headers })
        .then((res) => {
          if (regex.test(res.status as any as string)) {
            resolve(res.data);
          } else {
            reject(res)
          }
        })
        .catch((err) => {
          reject(err);
        });
    });
  }

  patch(url: string, data?: any, params?: jsonData, headers?: jsonData) {
    return new Promise<any>((resolve, reject) => {
      this.instance
        .patch(url, data, { params, headers })
        .then((res) => {
          if (regex.test(res.status as any as string)) {
            resolve(res.data);
          } else {
            reject(res)
          }
        })
        .catch((err) => {
          reject(err);
        });
    });
  }

  requestConfig(config: AxiosRequestConfig) {
    return new Promise<any>((resolve, reject) => {
      this.instance
        .request(config)
        .then((res) => {
          if (regex.test(res.status as any as string)) {
            resolve(res.data);
          } else {
            reject(res)
          }
        })
        .catch((err) => {
          reject(err);
        });
    });
  }

  postForm(url: string, data: jsonData, params?: jsonData, headers?: jsonData) {
    return new Promise<any>((resolve, reject) => {
      this.instance
        .postForm(url, data, { params, headers })
        .then((res) => {
          if (regex.test(res.status as any as string)) {
            resolve(res.data);
          } else {
            reject(res)
          }
        })
        .catch((err) => {
          reject(err);
        });
    });
  }
}

export default Config;
