/// <reference path="./definition.d.ts" />

import { urlEncode } from '../util/router';

function ajax(cfg: any): any {
  const method = (cfg.type || 'POST').toUpperCase(); //默认POST方法
  const data = cfg.contentType !== 'application/json' || method === 'GET' ? urlEncode(cfg.data) : JSON.stringify(cfg.data as any);
  const url = method === 'GET' && data ? cfg.url + '?' + data : cfg.url;
  const async = !cfg.sync; //同步否
  const dataType = cfg.dataType ? cfg.dataType : 'json';
	// this.formData = new FormData(document.getElementById(this.id)); //form数据
  const xhr = new XMLHttpRequest(); //当前请求对象
  xhr['url'] = url; //为xhr添加发送的url
	/**
	 * 超时事件
	 * 配置格式：
	 *   timeout : xxx,
	 *   onTimeout: function(event){}
	 */
  xhr.timeout = cfg.timeout ? cfg.timeout : 15000;
  if (cfg.onTimeout) {
    xhr.ontimeout = cfg.onTimeout;
  }
	/**
	 * 发送过程事件
	 * 配置格式:
	 * onProgress: function(loaded, total){}
	 */
  if (cfg.onProgress) { //发送数据过程
    this.xhr.upload.onprogress = function(e: any): void {
      if (e.lengthComputable) {
        cfg.onProgress(e.loaded, e.total);
      }
    };
  }
	/**
	 * 上传完成事件
	 */
  xhr.onreadystatechange = function(): void {
    if (xhr.readyState === 4 ) {
      const status = xhr.status;
      let xhrdata;
      if ((status >= 200 && status < 300) || status === 304) {
        switch (dataType.toLowerCase()) {
          case 'xml':
            xhrdata = xhr.responseXML;
            break;
          case 'json':
            xhrdata = JSON && JSON.parse ? JSON.parse(xhr.responseText) : eval('(' + xhr.responseText + ')');
            break;
          default:
            xhrdata = xhr.responseText;
        }
        if (cfg.success) {
          cfg.success(xhrdata, xhr);
        }
      } else {
        if (cfg.error) {
          cfg.error(xhr);
        }
      }
      if (cfg.complete) {
        cfg.complete(xhr);
      }
    }
  };
	/**
	 * 发出请求
	 */
  xhr.open(method, url, async);
  if (method === 'GET') {
    xhr.setRequestHeader('Content-type', 'text/plain; charset=UTF-8');
  } else {
    const header = cfg.contentType ? cfg.contentType : 'application/x-www-form-urlencoded; charset=UTF-8';

    if (cfg.customHeader) {
      Object.keys(cfg.customHeader).forEach((value) => {
        xhr.setRequestHeader(value, cfg.customHeader[value]);
      });
    }
    xhr.setRequestHeader('Content-type', header);
  }
  xhr.send(data);
  return xhr;
}

export default ajax;