/* eslint-disable */
import { deepMerge } from './tools';
// 自定义XHR请求
const XHR = function(config) {
  this.config = config;
  const that = this;
  // 默认配置项
  const defaultConfig = {
    options: {
      url: '', // 请求地址
      method: 'post', // get||post
      dataType: 'json', // 请求数据类型，json/formate，默认为json
      async: true, // 异步
      data: {}, // post请求数据
      timeout: 5000 // 超时时间
    },
    success: function() {},
    error: function() {}
  };
  // 合并配置项
  const mergeConfig = deepMerge(true, defaultConfig, this.config);
  mergeConfig.options.dataType =
        mergeConfig.options.dataType.toUpperCase() === 'FORMDATA' ? 'formData' : 'json';
  const xhr = this.createXhr();

  // 处理逻辑
  let postData = null;
  let url = mergeConfig.options.url;
  if (mergeConfig.options.method == 'post') {
    // post 用formate传值，省去加header
    if (mergeConfig.options.dataType === 'json') {
      postData = JSON.stringify(mergeConfig.options.data);
    } else {
      const formData = new FormData();
      Object.keys(mergeConfig.options.data).forEach(item => {
        formData.append(item, mergeConfig.options.data[item]);
      });
      postData = formData;
    }
  } else {
    // get方式用参数名和参数值用encodeURIComponent()编码
    url = this.dealUrl(url);
  }
  xhr.open(mergeConfig.options.method, url, mergeConfig.options.async);
  // post请求需要添加请求头
  if (mergeConfig.options.method == 'post' && mergeConfig.options.dataType === 'json') {
    xhr.setRequestHeader('content-type', 'application/json;charset=utf-8');
  }

  xhr.onreadystatechange = function() {
    // 监听状态 0=>为初始化 1=>启动 2=>发送 3=>接受 4=>完成
    if (xhr.readyState == 4) {
      if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) {
        that.config.success(xhr.responseText);
      } else {
        that.config.error() + xhr.status;
      }
    }
  };
  xhr.send(postData);

  // 超时报错
  xhr.ontimeout = function() {
    throw new Error('connect timeout');
  };
};

// 创建xhr
/** 支持XHR对象和ActiveX对象**/
XHR.prototype.createXhr = function() {
  if (typeof XMLHttpRequest !== 'undefined') {
    return new XMLHttpRequest();
  } else if (typeof ActiveXObject !== 'undefined') {
    // @ts-ignore
    if (typeof arguments.callee.activeXString !== 'string') {
      const versions = ['MSXML2.XMLHttp.6.0', 'MSXML2.XMLHttp.3.0', 'MSXML2.XMLHttp'];
      for (let i = 0, len = versions.length; i < len; i++) {
        try {
          // eslint-disable-next-line no-undef
          new ActiveXObject(versions[i]);
          // @ts-ignore
          arguments.callee.activeXString = versions[i];
          break;
        } catch (ex) {
          // 跳过
        }
      }
    }
    // eslint-disable-next-line no-undef
    // @ts-ignore
    return new ActiveXObject(arguments.callee.activeXString);
  } else {
    throw new Error('NO XHR object available');
  }
};

// 处理url
XHR.prototype.dealUrl = function(url) {
  const index = url.indexOf('?');
  if (index == -1) {
    return url;
  }
  const domain = url.substring(0, index);
  const pars = url.slice(index + 1);
  const arrs = pars.split('&');
  let newurl = domain;
  for (const item in arrs) {
    const arr = arrs[item].split('=');
    let split = '&';
    // @ts-ignore
    if (item == 0) {
      split = '?';
    }
    newurl += split + encodeURIComponent(arr[0]) + '=' + encodeURIComponent(arr[1]);
  }
  return newurl;
};

const ajax = {
  get: (url, data) => {
    return new Promise((resolve, reject) => {
      new XHR({
        options: {
          url, // 请求地址
          method: 'get', // get||post
          async: true, // 异步
          data // post请求数据
        },
        success: response => {
          resolve(response);
        },
        error: response => {
          reject(response);
        }
      });
    });
  },
  post: (url, data) => {
    return new Promise((resolve, reject) => {
      new XHR({
        options: {
          url, // 请求地址
          method: 'post', // get||post
          async: true, // 异步
          data // post请求数据
        },
        success: response => {
          resolve(response);
        },
        error: response => {
          reject(response);
        }
      });
    });
  }
};

export default ajax;
