import type { AxiosResponse, RequestOptions } from '@@/plugin-request/request';
import type { RequestConfig } from '@umijs/max';
import { message } from 'antd';

import { RESPONSE_ERROR_CODE, RESPONSE_ERROR_MESSAGE } from '@/constants/http';
import { clearToken, getToken, gotoLogin } from '@/utils/login';

import { IRequestResponse } from './types/http';

/**
 * @name 全局请求配置
 * @doc https://umijs.org/docs/max/request#配置
 */
export const requestConfig: RequestConfig = {
  baseURL: 'https://neighbourhood.cn',
  // baseURL: 'http://192.168.60.120:8082',

  // 错误处理： umi@3 的错误处理方案。
  errorConfig: {
    // 错误抛出
    errorThrower: res => {
      const { code, msg, traceId } = res as IRequestResponse;
      if (code) {
        const error: any = new Error(msg);
        error.name = 'BizError';
        error.info = { code, msg, traceId };
        throw error; // 抛出自制的错误
      }
    },
    // 错误接收及处理
    errorHandler: (error: any, opts: any) => {
      if (opts?.skipErrorHandler) throw error;
      // 我们的 errorThrower 抛出的错误。
      if (error.name === 'BizError') {
        const errorInfo: IRequestResponse | undefined = error.info;
        if (!errorInfo) {
          return;
        }
        const { code, msg, traceId } = errorInfo;
        switch (code) {
          case RESPONSE_ERROR_CODE.INVALID_PARAMETER:
          default:
            message.error(`Request error, msg: ${msg}, traceId: ${traceId}`);
        }
      } else if (error.response) {
        // Axios 的错误
        // 请求成功发出且服务器也响应了状态码，但状态代码超出了 2xx 的范围
        const { data, status } = error.response as AxiosResponse<IRequestResponse>;
        const code = data?.code as RESPONSE_ERROR_CODE;
        switch (code) {
          case RESPONSE_ERROR_CODE.NEED_LOGIN:
            clearToken();
            gotoLogin();
            return;
          default:
            message.error(`${RESPONSE_ERROR_MESSAGE[code] || '请求错误'}, 错误码:${status}`);
            return;
        }
      } else if (error.request) {
        // 请求已经成功发起，但没有收到响应
        // \`error.request\` 在浏览器中是 XMLHttpRequest 的实例，
        // 而在node.js中是 http.ClientRequest 的实例
        message.error('None response! Please retry.');
      } else {
        // 发送请求时出了点问题
        message.error('Request error, please retry.');
      }
    },
  },

  // 请求拦截器
  requestInterceptors: [
    (config: RequestOptions) => {
      const token = getToken();
      if (token) {
        config.headers = {
          ...(config.headers || {}),
          Authorization: 'Bearer ' + token,
        };
      }
      return config;
    },
  ],
};
