import axios from 'axios';
import fileDownload from 'js-file-download';
import { getStore, isExpired } from '@utils/store';
import { Notification } from 'element-ui';
import { encryptByMd5, uuid, sortByKey } from '@utils/util';
import router from '@/router';
import qs from 'qs';

axios.defaults.headers.post['Content-Type'] = 'application/json';

const api = {
  ajax: axios.create({
    baseURL: `${process.env.VUE_APP_API_PREFIX}`,
    timeout: 100000
  })
};

api.ajax.interceptors.request.use(
  (config) => {
    let isBasic = config.headers.isBasic || false;
    if (!isBasic) {
      let expired = isExpired('accessToken');
      if (expired) {
        router.push({ name: 'login' });
      }
      config.headers.Authorization = 'Bearer ' + getStore('accessToken');
    }
    return config;
  },
  (error) => {
    // 请求失败的处理
    return Promise.reject(error);
  }
);

api.ajax.interceptors.response.use(
  (res) => {
    return res;
  },
  (error) => {
    let data = error.response.data;
    switch (data.code) {
      case 403:
        Notification({
          title: '温馨提示',
          message: '您没有此权限',
          type: 'warning'
        });
        break;
      case 400:
        Notification({
          title: '温馨提示',
          message: data.msg,
          type: 'warning'
        });
        break;
      case 500:
        Notification({
          title: '温馨提示',
          message: '服务器错误。',
          type: 'error'
        });
        break;
      case 401:
        Notification({
          title: data.msg,
          message: data.data,
          type: 'warning',
          onClose: () => {
            router.push({
              name: 'login',
              replace: true
            });
          }
        });
        break;
      default:
        return Promise.reject(error.response);
    }
  }
);

export function fetch({ url = '', params = {}, headers = {} }) {
  headers['x-requestId'] = uuid();
  headers['x-timestamp'] = new Date().getTime();
  return new Promise((resolve, reject) => {
    api
      .ajax({
        method: 'GET',
        url: url,
        params: params,
        paramsSerializer: (params) => {
          return qs.stringify(params, { arrayFormat: 'indices' });
        },
        headers: headers
      })
      .then((response) => {
        if (response.data && response.data.code === 200) {
          resolve(response.data);
        }
        throw response;
      })
      .catch((error) => {
        reject(error);
      });
  });
}

export function post({ url = '', params = {}, headers = {} }) {
  let requestId = uuid();
  let timestamp = new Date().getTime();
  let data = JSON.stringify(sortByKey(params));
  let sign = encryptByMd5(data + requestId + timestamp);
  headers['x-requestId'] = requestId;
  headers['x-timestamp'] = timestamp;
  headers['x-sign'] = sign;
  return new Promise((resolve, reject) => {
    api
      .ajax({
        method: 'POST',
        url: url,
        data: data,
        headers: headers
      })
      .then((response) => {
        if (response.data && response.data.code === 200) {
          resolve(response.data);
        }
        throw response;
      })
      .catch((error) => {
        reject(error);
      });
  });
}

export function download({ url = '', params = {}, headers = {} }) {
  headers['x-requestId'] = uuid();
  headers['x-timestamp'] = new Date().getTime();
  headers['Content-Type'] = 'application/json';
  for (const propName of Object.keys(params)) {
    const value = params[propName];
    if (value instanceof Array && value.length > 0) {
      params[propName] = value.toString();
    }
  }
  return new Promise((resolve, reject) => {
    api
      .ajax({
        method: 'GET',
        url: url,
        params: params,
        headers: headers,
        responseType: 'arraybuffer'
      })
      .then((response) => {
        if (response.status === 200 && response.data) {
          let contentDisposition = response.headers['content-disposition'];
          let fileName;
          if (contentDisposition) {
            fileName = contentDisposition.split('filename=')[1];
          } else {
            fileName = url.substring(url.lastIndexOf('/') + 1);
          }
          fileDownload(response.data, decodeURI(fileName));
          resolve({});
        }
        throw response;
      })
      .catch((error) => {
        reject(error);
      });
  });
}

export function downloadPost({ url = '', params = {}, headers = {} }) {
  return new Promise((resolve, reject) => {
    api
      .ajax({
        method: 'post',
        url: url,
        data: params,
        headers: headers,
        responseType: 'arraybuffer'
      })
      .then((response) => {
        if (response.status === 200 && response.data) {
          let fileName = response.headers['content-disposition'].split('filename=')[1];
          fileDownload(response.data, decodeURI(fileName));
          resolve({});
        }
        throw response;
      })
      .catch((error) => {
        reject(error);
      });
  });
}
