import config from './config';

let loginTimeout: NodeJS.Timeout | undefined;
/**
 * 请求封装
 * @param url 请求url
 * @param method 请求方法类型
 * @param data 请求的参数
 * @param options 额外参数
 * @returns Promise<Response>
 */
export default function request(
  url: string,
  method: String = 'get',
  data?: any,
  options: any & { hideError?: boolean; headers?: { token?: string } } = {},
): Promise<Response<any>> {
  let token = localStorage.getItem('token') || '';

  switch (method.toLowerCase()) {
    case 'get':
      let params = new URLSearchParams();
      if (data) {
        Object.keys(data).forEach((key) => {
          params.append(key, data[key]);
        });

        url += '?' + params;
      }
      break;

    case 'post':
      options = {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify(data),
        ...options,
      };
      break;
  }

  if (options.headers) {
    options.headers.token = token;
  } else {
    options.headers = {
      token,
    };
  }

  /**
   * 错误消息
   * @param msg
   */
  function errMsg(msg: string) {
    if (!options.hideError) {
      window.messageApi.error(msg);
    }
  }

  /**
   * 未登录消息展示,1.5秒内限制只展示一次
   * @returns
   */
  function loginErrorMsg() {
    console.log('loginTimeout', loginTimeout);
    if (loginTimeout) {
      return;
    }
    loginTimeout = setTimeout(() => {
      errMsg('请先登录');
      loginTimeout = undefined;
    }, 1500);
  }

  return fetch(config.baseUrl + url, options)
    .then((r) => {
      try {
        return r.json();
      } catch (e) {
        console.error(e);
      }
      return {
        code: '-1',
        message: '请求失败',
        result: null,
      };
    })
    .then((data) => {
      if (data.errors) {
        //全局消息提示
        errMsg('请求出错');

        if (Array.isArray(data.errors)) {
          data.errors.forEach((item: any) => {
            if (item.defaultMessage) {
              errMsg(item.defaultMessage);
            }
          });
        }

        return {
          code: '-1',
          message: '请求失败',
          result: null,
        };
      }

      if (data.code !== '200') {
        //未登录判断
        if (data.code === '5008' || data.code === '2014') {
          loginErrorMsg();
          window.logout();
        } else {
          errMsg(data.message || '请求出错');
        }
      }

      return data;
    })
    .catch((error) => {
      if (error.name === 'AbortError') {
        console.log('请求已中断');
        console.log(error);
      } else {
        console.error('请求出错', error);
      }
      return {
        code: '-1',
        message: '请求失败',
        result: null,
      };
    });
}

//准备响应结构
export interface Response<T> {
  code: string;
  message: string;
  result?: T | null;
}
