﻿import { TOKEN } from '@/utils/constant';
import type { RequestOptions } from '@@/plugin-request/request';
import type { RequestConfig} from '@umijs/max';
import { getLocale } from '@umijs/max';
import { OPERATION_SUCCESS } from '@/services/common/constant';
import { message } from 'antd';

let isLogout = false;

// 错误处理方案： 错误类型
enum ErrorShowType {
  // 请求数据格式错误
  INVALID_PARAM_FORMAT= 400,
  // 无权限
  INVALID_TOKEN = 401,
  // token 过期
  NO_ACCESS = 403,
  //未找到
  NOT_FOUND=404,
  // 请求方式错误
  INVALID_TYPE = 405,
  // 服务器错误
  SERVER_ERROR = 500,

}
// 与后端约定的响应数据格式
interface ResponseStructure {
  code: string;
  msg: string;
  data?: any;
  status:boolean;
}

//cookie中获取token，失败跳转到登录页面
const getToken = () => {
  return localStorage.getItem(TOKEN) ||
    (window.location.pathname.includes('/login') ? ''
      : window.location.replace('/login')
    );

};
// 获取菜单ID
const getMenuId = (menuTree?: [{
  privilegeUrl: string,
  id: string,
  children?: Array<{
    privilegeUrl: string,
    id: string
  }>
}] | undefined): string => {
  if (menuTree) {
    // console.log(menuTree, 'menuTree');
    const l = window.location.pathname.split('/');
    // console.log(l, 'l');
    if (l.length < 2||l[1]==='') {
      return '';
    }
    const pID = menuTree.find(({ privilegeUrl }) => privilegeUrl.includes(l[1].toString()));
    //  console.log(pID, 'pID');
    if (pID) {
      if (pID.children && pID.children.length > 0) {
        const cID = pID.children.find(({ privilegeUrl }) =>privilegeUrl.includes(l[2]));
        if (cID) {
          return cID.id;
        }
      }
      return pID.id;
    }
  }
  return '';
};

const headerConfig = (type?: string) => {

  const menuTree = JSON.parse(localStorage.getItem('currentMenu') || '[]');
  const menuId = getMenuId(menuTree || []);

  return {
    menuId,
    lang: getLocale(),
    Authorization: getToken() as string,
    'Content-Type': type || 'application/json',
  };

};
/**
 * @name 错误处理
 * pro 自带的错误处理， 可以在这里做自己的改动
 * @doc https://umijs.org/docs/max/request#配置
 */
export const errorConfig: RequestConfig = {
  // 错误处理： umi@3 的错误处理方案。
  errorConfig: {
    // 业务错误抛出
    errorThrower: (res) => {
      const { code, msg } = res as unknown as ResponseStructure;
      if (code.toString() !== OPERATION_SUCCESS) {
      
        const error: any = new Error(`${code}/${msg}`);
        error.name = 'BizError';
        error.info = { code, msg };
         try{
        throw error; 
        }catch(e){
          throw error.toString(); 
        };
      }
    },
    // 错误接收及处理
    errorHandler: (error: any, opts: any) => {
      
        const newError = typeof error === 'string'?{
          name: error.split(':')[0],
          info: {
            code: parseInt(error.split(':')[1].split('/')[0]),
            msg: error.split(':')[1].split('/')[1],
          },
        }:error;

     if (opts?.skipErrorHandler) throw newError;

      // 我们的业务抛出的错误。
      if (newError.name === 'BizError') {
        const errorInfo: ResponseStructure = newError.info;
        const { msg } = errorInfo;
        // console.log(msg, code, 'errorInfo');
        message.error(msg);
        // 返回错误
        throw errorInfo;
       
      } else if (newError.response) {
        // 请求成功发出且服务器也响应了状态码，但状态代码超出了 2xx 的范围
        // console.log('接口非200 返回');
        // console.log(newError.response, 'newError.response');
        const { statusText, status } = newError.response;
        switch (status) {
          case ErrorShowType.INVALID_TOKEN: {
            message.error(statusText);
            if (!isLogout) {
              isLogout = true;
              setTimeout(() => {
                isLogout = false;
              }, 1000);
              if (!window.location.pathname.includes('/login')) {
                window.location.replace('/login');              
              }
            }
            break;
          }
          case ErrorShowType.NO_ACCESS: {
            message.error(statusText);
            break;
          }
          case ErrorShowType.INVALID_TYPE: {
            message.error(statusText);
            break;
          }
          case ErrorShowType.NOT_FOUND: {
            message.error(statusText);
            break;
          }
          case ErrorShowType.SERVER_ERROR: {
            message.error(statusText);
            break;
          }
          default:
            message.error(statusText);
            break;
        }

      
        // message.error(`Response status:${error.response.statusText}`);
      } else if (newError.request) {
        // 请求已经成功发起，但没有收到响应
        // \`error.request\` 在浏览器中是 XMLHttpRequest 的实例，
        // 而在node.js中是 http.ClientRequest 的实例
        message.error('Request error, please retry.');
        console.log('请求已经成功发起，但没有收到响应');
      } else {
        // console.log(newError, 'error.request');
        // 发送请求时出了点问题
        // console.log(errorInfo, '接口错误');
        console.log('发送请求时出了点问题');
        message.error('Request error, please retry.');
      }
    },
  },

  // 请求拦截器
  requestInterceptors: [
    (config: RequestOptions) => {
      // 拦截请求配置，进行个性化处理。
      const url = config?.url;
      const headers = headerConfig(config?.type);
      return { ...config, url, headers };
    },
  ],

  // 响应拦截器
  responseInterceptors: [
    (response) => {
      // 拦截响应数据，进行个性化处理
      const { data } = response as unknown as ResponseStructure;
      data.success = data?.code === '0000';
      return response;
    },
  ],
};
