import { notification } from 'antd';
import { getLocale, history } from 'umi';
import config from '@/config';
import { clearLoginStatus, getLocaleText } from '@/utils';
import HttpRequest from './kim-request';
import store from 'store';

// const codeMessage = {
//   200: getLocaleText('kim.system.request.200'),
//   201: getLocaleText('kim.system.request.201'),
//   202: getLocaleText('kim.system.request.202'),
//   204: getLocaleText('kim.system.request.204'),
//   400: getLocaleText('kim.system.request.400'),
//   401: getLocaleText('kim.system.request.401'),
//   403: getLocaleText('kim.system.request.403'),
//   404: getLocaleText('kim.system.request.404'),
//   406: getLocaleText('kim.system.request.406'),
//   410: getLocaleText('kim.system.request.410'),
//   422: getLocaleText('kim.system.request.422'),
//   500: getLocaleText('kim.system.request.500'),
//   502: getLocaleText('kim.system.request.502'),
//   503: getLocaleText('kim.system.request.503'),
//   504: getLocaleText('kim.system.request.504'),
// };

const {
  request: {
    baseUrl,
    apiPrefix,
    resCodeKey,
    resMessageKey,
    successCode,
    isThrowError = true,
    authCodes = ['error.system.authc'],
  },
} = config;

/**
 * 组装url
 * @param {url} url
 * @param {{}} more
 */
const merge = (url: string, more: any) => {
  if (more && more.apiPrefix && typeof more.apiPrefix === 'string') {
    return `${config.apiPrefix}${url}`;
  }
  if (apiPrefix && typeof apiPrefix === 'string') {
    return `${config.apiPrefix}${url}`;
  }
  return url;
};

const headers = () => ({
  Authorization: store.get('token'),
  'X-Access-Lang': getLocale().replace(/-/, '_'),
});

const axios = new HttpRequest({
  baseUrl,
  headers: headers || {},
});

/**
 * 正常返回结果处理
 * @param {返回请求数据} response
 * @param {配置项} more
 */
const handleResponse = (response) => {
  const { data } = response;
  console.log('response', response);
  //
  if (`${data[resCodeKey]}` !== `${successCode}`) {
    if (isThrowError) {
      const errorMessage =
        data[resMessageKey] || getLocaleText('kim.system.request.default.message');
      let error = new Error();
      error = { ...error, ...data };
      error.code = data[resCodeKey];
      error.message = errorMessage;
      return Promise.reject(error);
    }
  }
  // success
  return data;
};

const handleError = (error, more) => {
  const codeMessage = {
    200: getLocaleText('kim.system.request.200'),
    201: getLocaleText('kim.system.request.201'),
    202: getLocaleText('kim.system.request.202'),
    204: getLocaleText('kim.system.request.204'),
    400: getLocaleText('kim.system.request.400'),
    401: getLocaleText('kim.system.request.401'),
    403: getLocaleText('kim.system.request.403'),
    404: getLocaleText('kim.system.request.404'),
    406: getLocaleText('kim.system.request.406'),
    410: getLocaleText('kim.system.request.410'),
    422: getLocaleText('kim.system.request.422'),
    500: getLocaleText('kim.system.request.500'),
    502: getLocaleText('kim.system.request.502'),
    503: getLocaleText('kim.system.request.503'),
    504: getLocaleText('kim.system.request.504'),
  };
  const { response } = error;
  const options = { isThrowError, ...more };
  // status
  if (response && response.status) {
    const errorText = codeMessage[response.status] || response.statusText;
    const {
      status,
      config: { url },
    } = response;
    notification.error({
      message: `${getLocaleText('kim.system.request.dialog.title')} ${status}`,
      description: `${url}${errorText}`,
    });
    // 跳转到404页面
    if (status >= 404 && status < 422) {
      history.push('/exception/404');
    }
    if (status <= 504 && status >= 500) {
      history.push('/exception/500');
    }
    // 跳转到登录页面 可能原因:token 失效
    if (status === 403 && status === 401) {
      clearLoginStatus();
      history.push('/user/login');
    }
  } else {
    // code
    const { code, message } = error;

    notification.error({
      key: `notification_${code ? message : code}`,
      message: getLocaleText('kim.system.request.dialog.title'),
      description: message,
    });
    // 跳转到登录页面 可能原因:token 失效
    if (authCodes && authCodes.includes(code)) {
      // 清空相关信息
      clearLoginStatus();
      history.push('/user/login');
    }
  }

  if (options.isThrowError) {
    throw error;
  } else {
    return error;
  }
};

export default function request(url, options = {}, more = {}, handle = false) {
  let newOptions = options;
  newOptions.url = url;
  if (more.headers) {
    newOptions = { ...options, headers: more.headers };
  }
  if (handle) {
    return axios.request(newOptions);
  }
  return axios
    .request(newOptions)
    .then((response) => handleResponse(response, more))
    .catch((error) => handleError(error, more));
}

/**
 * get请求
 * @param url
 * @param data
 * @param more
 * @returns {AxiosPromise<any>|Promise<Promise<never> | 返回请求数据.data | *>}
 */
const get = (url, data, more = {}) => {
  if (data?.current && !data?.pageNum) {
    // eslint-disable-next-line no-param-reassign
    data.pageNum = data.current;
  }
  return request(
    `${merge(url, more)}`,
    {
      method: 'get', // default
      params: data,
    },
    more,
  );
};

/**
 * post请求
 * @param url
 * @param data
 * @param more
 * @returns {AxiosPromise<any>|Promise<Promise<never> | 返回请求数据.data | *>}
 */
const post = (url, data, more = {}) =>
  request(
    `${merge(url, more)}`,
    {
      method: 'post', // default
      data,
    },
    more,
  );

/**
 * put请求
 * @param url
 * @param data
 * @param more
 * @returns {AxiosPromise<any>|Promise<Promise<never> | 返回请求数据.data | *>}
 */
const put = (url, data, more = {}) =>
  request(
    `${merge(url, more)}`,
    {
      method: 'put', // default
      data,
    },
    more,
  );

/**
 * delete请求
 * @param url
 * @param data
 * @param more
 * @returns {AxiosPromise<any>|Promise<Promise<never> | 返回请求数据.data | *>}
 */
const del = (url, data, more = {}) =>
  request(
    `${merge(url, more)}`,
    {
      method: 'delete', // default
      data,
    },
    more,
  );

/**
 * patch请求
 * @param url
 * @param data
 * @param more
 * @returns {AxiosPromise<any>|Promise<Promise<never> | 返回请求数据.data | *>}
 */
const patch = (url, data, more = {}) =>
  request(
    `${merge(url, more)}`,
    {
      method: 'patch', // default
      data,

      ...more,
    },
    more,
  );

const downloadFile = (url, data, more = {}) => {
  console.log('xiazai');
  return request(
    `${merge(url, more)}`,
    {
      method: 'get', // default
      params: data,
      responseType: 'blob',
    },
    more,
    true,
  ).then((response) => {
    return new Blob([response.data]);
  });
};

const formDataUpload = (url, options, more = {}) => {
  const formData = new FormData();
  if (options) {
    Object.keys(options).forEach((key) => {
      formData.append(key, options[key]);
    });
  }
  return post(`${merge(url, more)}`, formData, {
    headers: {
      'Content-Type': 'multipart/form-data',
      Authorization: store.get('token'),
    },
    ...more,
  }).then((res) => {
    const { code } = res;
    if (code === 'sys.success' && typeof options.onSuccess) {
      return options.onSuccess(res);
    }
    return res;
  });
};

/**
 * 上传文件
 * @param {url} url
 * @param {data} data
 * @param {type} type
 * @param {more} more
 */
const uploadFile = (url, data, type = 'formData', more = {}) => {
  if (type === 'formData') {
    return formDataUpload(url, data, more);
  }
  return null;
};

export { request, get, post, put, del, patch, uploadFile, downloadFile };
