/**
 * KRA - Request Error Config
 * 请求错误处理配置
 */
import type { RequestOptions } from '@@/plugin-request/request';
import type { RequestConfig } from '@umijs/max';
import { history } from '@umijs/max';
import { message } from 'antd';
import { getToken, removeToken } from '@/utils/auth';

// API 响应结构
interface ApiResponse<T = any> {
  code: number;
  data?: T;
  msg?: string;
  message?: string;
}

// 错误码映射
const errorCodeMap: Record<number, string> = {
  400: '请求参数错误',
  401: '未授权，请重新登录',
  403: '拒绝访问',
  404: '请求地址不存在',
  408: '请求超时',
  500: '服务器内部错误',
  501: '服务未实现',
  502: '网关错误',
  503: '服务不可用',
  504: '网关超时',
  505: 'HTTP版本不受支持',
};

// 登录页路径
const loginPath = '/user/login';

// 请求配置
export const errorConfig: RequestConfig = {
  // 错误处理配置
  errorConfig: {
    // 错误抛出
    errorThrower: (res) => {
      const { code, msg, message: resMsg } = res as unknown as ApiResponse;
      if (code !== 0) {
        const error: any = new Error(msg || resMsg || '请求失败');
        error.name = 'BizError';
        error.info = { code, msg: msg || resMsg };
        throw error;
      }
    },

    // 错误处理
    errorHandler: (error: any, opts: any) => {
      // 跳过错误处理
      if (opts?.skipErrorHandler) throw error;

      // 业务错误
      if (error.name === 'BizError') {
        const errorInfo = error.info;
        if (errorInfo) {
          message.error(errorInfo.msg || '请求失败');
        }
        return;
      }

      // HTTP 错误
      if (error.response) {
        const { status, data } = error.response;

        // 401 未授权
        if (status === 401) {
          message.error('登录已过期，请重新登录');
          removeToken();
          history.push(loginPath);
          return;
        }

        // 其他 HTTP 错误
        const errorMsg = data?.msg || data?.message || errorCodeMap[status] || `请求错误 ${status}`;
        message.error(errorMsg);
        return;
      }

      // 请求错误（无响应）
      if (error.request) {
        message.error('网络异常，请检查网络连接');
        return;
      }

      // 其他错误
      message.error(error.message || '请求失败');
    },
  },

  // 请求拦截器
  requestInterceptors: [
    (config: RequestOptions) => {
      // 添加 token
      const token = getToken();
      if (token) {
        config.headers = {
          ...config.headers,
          'x-token': token,
        };
      }

      // 添加时间戳防止缓存
      if (config.method?.toUpperCase() === 'GET') {
        config.params = {
          ...config.params,
          _t: Date.now(),
        };
      }

      return config;
    },
  ],

  // 响应拦截器
  responseInterceptors: [
    (response) => {
      const { data } = response;

      // 检查业务状态码
      if (data && typeof data === 'object' && 'code' in data) {
        const { code, msg, message: resMsg } = data as ApiResponse;

        // 未登录或 token 过期
        if (code === 7 || code === 401) {
          message.error(msg || resMsg || '登录已过期，请重新登录');
          removeToken();
          // 延迟跳转，让用户看到提示
          setTimeout(() => {
            history.push(loginPath);
          }, 500);
        }
      }

      return response;
    },
  ],
};

export default errorConfig;
