/**
 * Created by baoyinghai on 10/18/16.
 */
/* eslint-disable */
var self = {};
/* eslint-disable */
(function() {
  'use strict';

  function headers(xhr) {
    var head = new Headers();
    var pairs = xhr.getAllResponseHeaders().trim().split('\n');
    pairs.forEach(function(header) {
      var split = header.trim().split(':')
      var key = split.shift().trim();
      var value = split.join(':').trim();
      key && value && head.append(key, value);
    });
    return head;
  }

  var support = {
    blob: typeof FileReader === 'function' && typeof Blob === 'function' && (function() {
      try {
        new Blob();
        return true;
      } catch (e) {
        return false;
      }
    })(),
    formData: typeof FormData === 'function',
    arrayBuffer: typeof ArrayBuffer === 'function'
  };

  self.fetch = function(input, init, timeout) {
    var request;
    var timeoutTimer
    if (Request.prototype.isPrototypeOf(input) && !init) {
      request = input;
    } else {
      request = new Request(input, init);
    }

    return new Promise(function(resolve, reject) {
      var xhr = new XMLHttpRequest();

      function responseURL() {
        if ('responseURL' in xhr) {
          return xhr.responseURL;
        }

        // Avoid security warnings on getResponseHeader when not allowed by CORS
        if (/^X-Request-URL:/m.test(xhr.getAllResponseHeaders())) {
          return xhr.getResponseHeader('X-Request-URL');
        }

        return;
      }

      function cleanTimeoutTimer() {
        timeoutTimer && window.clearTimeout( timeoutTimer );
      }

      xhr.onload = function() {
        cleanTimeoutTimer();
        var status = (xhr.status === 1223) ? 204 : xhr.status;
        if (status < 100 || status > 599 || status === 500) {
          reject(new TypeError('Network request failed, errorCode: ' + status));
          return;
        }
        var options = {
          status: status,
          statusText: xhr.statusText,
          headers: headers(xhr),
          url: responseURL()
        }
        var body = 'response' in xhr ? xhr.response : xhr.responseText;
        resolve(new Response(body, options));
      };

      xhr.onerror = function(err) {
        cleanTimeoutTimer();
        reject(new TypeError('Network request failed'));
      };

      xhr.open(request.method, request.url, true);

      if (request.credentials === 'include') {
        xhr.withCredentials = true;
      }

      if ('responseType' in xhr && support.blob) {
        xhr.responseType = 'blob';
      }

      request.headers.forEach(function(value, name) {
        xhr.setRequestHeader(name, value);
      });

      // Object.getOwnPropertyNames(init.headers).forEach(function(name) {
      //   xhr.setRequestHeader(name, init.headers[name]);
      // })

      // xhr.setRequestHeader('Accept', 'application/json');
      // xhr.setRequestHeader('Content-Type', 'application/json');

      xhr.send(init.body === 'undefined' ? null : init.body);

      timeoutTimer = timeout && setTimeout(() => {
        xhr.abort();
        reject(new TypeError('连接超时'));
      }, timeout);

    });
  };
  self.fetch.polyfill = true;

  function getError(option, xhr) {
    var msg = 'cannot post ' + option.action + ' ' + xhr.status + '\'';
    var err = new Error(msg);
    err.status = xhr.status;
    err.method = 'post';
    err.url = option.action;
    return err;
  }

  function getBody(xhr) {
    var text = xhr.responseText || xhr.response;
    if (!text) {
      return text;
    }

    try {
      return JSON.parse(text);
    } catch (e) {
      return text;
    }
  }

// option {
//  onProgress: (event: { percent: number }): void,
//  onError: (event: Error, body?: Object): void,
//  onSuccess: (body: Object): void,
//  data: Object,
//  filename: String,
//  file: File,
//  withCredentials: Boolean,
//  action: String,
//  headers: Object,
// }
  self.upload = function (option) {
    return new Promise(function(resolve, reject) {
      var xhr = new XMLHttpRequest();
      if (xhr.upload) {
        xhr.upload.onprogress = function progress(e) {
          if (e.total > 0) {
            e.percent = e.loaded / e.total * 100;
          }
          option.onProgress(e);
        };
      }

      var formData = new FormData();

      if (option.data) {
        Object.keys(option.data).map(function (key) {
          formData.append(key, option.data[key]);
        });
      }

      formData.append(option.filename, option.file);

      xhr.onerror = function error(e) {
        option.onError(e);
        reject(new TypeError('Network request failed'));
      };

      xhr.onload = function onload() {
        // allow success when 2xx status
        // see https://github.com/react-component/upload/issues/34
        if (xhr.status < 200 || xhr.status >= 300) {
          return option.onError(getError(option, xhr), getBody(xhr));
        }
        var body = 'response' in xhr ? xhr.response : xhr.responseText;
        option.onSuccess(body);
        resolve(new Response(body, option));
      };

      xhr.open('post', option.action, true);

      // Has to be after `.open()`. See https://github.com/enyo/dropzone/issues/179
      if (option.withCredentials && 'withCredentials' in xhr) {
        xhr.withCredentials = true;
      }

      var headers = option.headers || {};

      // when set headers['X-Requested-With'] = null , can close default XHR header
      // see https://github.com/react-component/upload/issues/33
      if (headers['X-Requested-With'] !== null) {
        xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
      }

      for (var h in headers) {
        if (headers.hasOwnProperty(h) && headers[h] !== null) {
          xhr.setRequestHeader(h, headers[h]);
        }
      }
      xhr.send(formData);

      return {
        abort: function abort() {
          xhr.abort();
        }
      };
    })
  }
  // self.fetch.polyfill = true;
})();

export default self;
