import type { AxiosRequestConfig, AxiosError } from 'axios';
import axios, { AxiosResponse } from 'axios';
import type { ResponseBody } from '@/api/typing';
import ls, { localStorage } from '@/utils/local-storage';

import { STORAGE_TOKEN_KEY, STORAGE_LANG_KEY } from '@/store/mutation-type';
import { notification, message } from 'ant-design-vue';
import { createHttp, icpxTransform, icpxTransformConfig } from '@crami/http';
// import { LOGOUT } from '@/store/modules/user/actions';
// import store from '@/store';
import router from '@/router';
import { RouteContextProvider } from '@/components/base-layouts/route-context';
import { langMap } from '@/locales/index';

// import { message } from '@crami/ui';

// import { loginRoutePath } from '@/router/define-meta';

// 这里是用于设定请求后端时，所用的 Token KEY
// 可以根据自己的需要修改，常见的如 Access-Token，Authorization
// 需要注意的是，请尽量保证使用中横线`-` 来作为分隔符，
// 避免被 nginx 等负载均衡器丢弃了自定义的请求头
export const REQUEST_TOKEN_KEY = 'Authorization';

// 创建 axios 实例
const request = axios.create({
  // API 请求的默认前缀
  baseURL: process.env.VUE_APP_API_BASE_URL,
  timeout: 30 * 1000, // 请求超时时间
});

export const http = createHttp(request, {
  responseTransform: icpxTransform,
  requestTransform: icpxTransformConfig,
  urlParser: url => url.trim().replace(/^\/api/, ''),
});

export type RequestError = AxiosError<{
  message?: string;
  msg?: string;
  path?: string;
  result?: any;
  errorMessage?: string;
}>;
// 异常拦截处理器
const errorHandler = (error: RequestError): Promise<any> => {
  if (error.response) {
    const { data = {}, status, statusText } = error.response;
    // 403 无权限
    if (status === 403) {
      notification.error({
        message: 'Forbidden',
        description: (data && data.message) || statusText,
      });
    }
    //服务端出错了
    if (status === 500) {
      notification.destroy();
      notification.error({
        message: 'Internal Server Error',
        description: (data && data.message) || statusText,
      });
    }
    //服务不可用
    if (status === 503) {
      notification.destroy();
      notification.error({
        message: 'Service Unavailable',
        description: (data && data.path) || statusText,
      });
    }
    // 401 未登录/未授权
    if (status === 401 && data.result && data.result.isLogin) {
      handler401((data && data.message) || statusText);
    }
  }
  return Promise.reject(error);
};

// 请求拦截器
const requestHandler = (
  config: AxiosRequestConfig,
): AxiosRequestConfig | Promise<AxiosRequestConfig> => {
  const savedToken = localStorage.get(STORAGE_TOKEN_KEY);
  // 设置请求头多语言，默认是中文
  config.headers[`Accept-Language`] = localStorage.get(STORAGE_LANG_KEY)
    ? langMap[localStorage.get(STORAGE_LANG_KEY)]
    : 'zh-CN';
  // 如果 token 存在
  // 让每个请求携带自定义 token, 请根据实际情况修改
  if (savedToken) {
    config.headers[REQUEST_TOKEN_KEY] = 'Bearer ' + savedToken;
  }
  return config;
};

// Add a request interceptor
request.interceptors.request.use(requestHandler, errorHandler);

// 响应拦截器
const responseHandler = (
  response: AxiosResponse,
): ResponseBody<any> | AxiosResponse<any> | Promise<any> | any => {
  const { code, msg, message } = response.data;
  const description = msg || message;
  // notification.destroy();

  switch (code) {
    case 200:
      return response.data;
    case 401:
      handler401(description);
      return Promise.reject(response.data);
    case 403:
      notification.error({
        message: 'Forbidden',
        description,
      });
      return Promise.reject(response.data);
    case 500:
      notification.error({
        message: 'Internal Server Error',
        description,
      });
      return Promise.reject(response.data);
    case 503:
      notification.error({
        message: 'Service Unavailable',
        description,
      });
      return Promise.reject(response.data);
    case -1:
      notification.error({
        message: 'Rejected',
        description,
      });
      return Promise.reject(response.data);
    default:
      return Promise.reject(response.data);
  }
};

// Add a response interceptor
request.interceptors.response.use(responseHandler, errorHandler);

function handler401(description) {
  notification.destroy();
  notification.error({
    message: 'Unauthorized',
    description,
  });

  const savedToken = ls.get(STORAGE_TOKEN_KEY) || {};
  if (savedToken) {
    window.localStorage.clear();
    window.sessionStorage.clear();
  }
  if (router.currentRoute.value.path !== '/user/login') {
    // 携带上校验参数
    const query: any = { checkCode: GetQueryString('checkCode') };
    // 应用体验需要的用户名密码
    if (GetQueryString('username')) {
      query.username = GetQueryString('username');
    }
    if (GetQueryString('password')) {
      query.password = GetQueryString('password');
    }
    router.push({ path: '/user/login', query: query });
  }
}

function GetQueryString(name: string): string {
  const reg = new RegExp('(?<=(?:^|&|\\?)' + name + '=)([^&]*)(?=(&|$))', 'g');
  return window.location.search.match(reg)?.[0];
}
export { AxiosResponse };

export default request;
