import axios from 'axios';
import uuid from 'uuid';

const baseURL =
  process.env.NODE_ENV === 'development' ? window.location.origin : '';
axios.defaults.withCredentials = true;

let pending = []; //声明一个数组用于存储每个ajax请求的取消函数和ajax标识
let cancelToken = axios.CancelToken;
class HttpRequest {
  constructor(props) {
    this.requestApi = axios.create({
      baseURL,
      timeout: 30000,
      headers: {
        'Content-Type': 'application/json;charset=UTF-8',
      },
    });
    this.requestApi.interceptors.request.use(
      config => {
        // if(config.params&&config.params.cancelAllRequest){
        //   removeAllPending()
        // }
        // ------------------------------------------------------------------------------------
        if (!config.ignoreSite && this.getSite()) {
          config.headers['civ-site'] = this.getSite();
        }
        this.removePending(config); //在一个ajax发送前执行一下取消操作
        config.cancelToken = new cancelToken(c => {
          let uid = uuid.v1();
          config.uuid = uid;
          pending.push({ uuid: uid, f: c });
        });
        // -----------------------------------------------------------------------------------------
        return config;
      },
      function(error) {
        return Promise.reject(error);
      },
    );

    this.requestApi.interceptors.response.use(
      response => {
        // ------------------------------------------------------------------------------------------
        this.removePending(response.config); //在一个ajax响应后再执行一下取消操作，把已经完成的请求从pending中移除
        // ------------------------------------------------------------------------------------------
        if (response.status == 200) {
          return response.data;
        }
        return response;
      },
      function(error) {
        console.log(error);
        if (error && error.response) {
          switch (error.response.status) {
            case 400:
              error.message = '错误请求';
              break;
            case 401:
              error.message = '未授权，请重新登录';
              break;
            case 403:
              error.message = '拒绝访问';
              break;
            case 404:
              error.message = '请求错误,未找到该资源';
              break;
            case 405:
              error.message = '请求方法未允许';
              break;
            case 408:
              error.message = '请求超时';
              break;
            case 500:
              error.message = '服务器端出错';
              break;
            case 501:
              error.message = '网络未实现';
              break;
            case 502:
              error.message = '网络错误';
              break;
            case 503:
              error.message = '服务不可用';
              break;
            case 504:
              error.message = '网络超时';
              break;
            case 505:
              error.message = 'http版本不支持该请求';
              break;
            default:
              error.message = `连接错误${err.response.status}`;
          }
        } else {
          error.message = '连接到服务器失败';
        }
        return Promise.reject(error);
      },
    );
  }
  removePending = ever => {
    for (let p in pending) {
      if (pending[p].uuid === ever.uuid) {
        //当当前请求在数组中存在时执行函数体
        pending[p].f(); //执行取消操作
        pending.splice(p, 1); //把这条记录从数组中移除
      }
    }
  };
  removeAllPending = () => {
    for (let p in pending) {
      pending[p].f(); //执行取消操作
      pending.splice(p, 1); //把这条记录从数组中移除
    }
  };
  getSite() {
    return (
      (window.globalConfig &&
        window.globalConfig.userInfo &&
        window.globalConfig.userInfo.site) ||
      ''
    );
  }
  get(url, params, config = {}) {
    params = this.getSite()
      ? Object.assign({}, params, {
          site: this.getSite(),
        })
      : params;
    return this.requestApi.get(url, { ...config, params });
  }

  post(url, data, config = {}) {
    data = this.getSite()
      ? Object.assign({}, data, {
          site: this.getSite(),
        })
      : data;
    return this.requestApi.post(url, { ...data, ...config });
  }

  delete(url, params, config = {}) {
    params = this.getSite()
      ? Object.assign({}, params, {
          site: this.getSite(),
        })
      : params;
    return this.requestApi.delete(url, { ...config, params });
  }

  put(url, params, config = {}) {
    params = this.getSite()
      ? Object.assign({}, params, {
          site: this.getSite(),
        })
      : params;
    return this.requestApi.delete(url, params, config);
  }
}

const http = new HttpRequest();

export default http;
