    import { defaultValue, isNull } from '../util'
    import { FetchMethod, TokenAttachType } from '../base/enum'

    const fetch = window.fetch

    const FetchRequest = {
      /**
       * 根据method调用不同类型的请求
       * @param {FetchMethod} method 请求类型，默认FetchMethod.get
       * @param {String} url 请求地址
       * @param {String | Object} body 要放入body里的内容
       * @param {Object} options 额外参数
       * @param {Object} [options.headers] 请求头信息
       * @param {Number} [options.requestTimeout = 45000] 请求超时时间，默认45000ms，即45s
       * */
      commit(method, url, body, options) {
        method = method ? method.toUpperCase() : method
        // 根据请求类型，发送请求
        switch (method) {
          case 'GET':
            return this._get(url, options)
          case 'POST':
            return this._post(url, body, options)
          case 'PUT':
            return this._put(url, body, options)
          case 'DELETE':
            return this._delete(url, body, options)
          default:
            return this._get(url, options)
        }
      },

      /**
       * get请求
       * @param {String} url 请求地址
       * @param {Object} options _fetch方法需要的额外参数
       * */
      _get(url, options) {
        options = defaultValue(options, {})

        return this._fetch(url, undefined, options, FetchMethod.get)
      },

      /**
       * delete请求
       * @param {String} url 请求地址
       * @param {String | Object} body 要放入body里的内容
       * @param {Object} options _fetch方法需要的额外参数
       * */
      _delete(url, body, options) {
        options = defaultValue(options, {})

        return this._fetch(url, body, options, FetchMethod.delete)
      },

      /**
       * post请求
       * @param {String} url 请求基地址，注意IGS2.0的基地址为http://ip:port/{igs上的请求及地址}?f=json
       * @param {String | Object} body 请求body，注意igs2.0的body必须为queryString格式，即&key1=value1&key2=value2
       * @param {Object} options _fetch方法的额外参数
       * */
      _post(url, body, options) {
        options = defaultValue(options, {})
        return this._fetch(url, body, options, FetchMethod.post)
      },

      /**
       * put请求
       * @param {String} url 请求地址
       * @param {String | Object} body 要放入body里的内容
       * @param {Object} options _fetch方法需要的额外参数
       * */
      _put(url, body, options) {
        options = defaultValue(options, {})

        return this._fetch(url, body, options, FetchMethod.put)
      },

      /**
       * 实际的请求发送方法
       * @param {String} url 请求基地址
       * @param {String | Object} body 请求body
       * @param {Object} options 额外参数
       * @param {Function} [options.headers] 请求头信息
       * @param {Boolean} [options.withCredentials = false] 是否携带cookies
       * @param {Number} [options.requestTimeout = 45000] 请求超时时间，默认45000ms，即45s
       * @param {FetchMethod} type 请求方式
       * */
      _fetch(url, body, options, type) {
        options = defaultValue(options, {})
        options.headers = defaultValue(options.headers, {})
        options.requestTimeout = defaultValue(options.requestTimeout, 45000)

        // 设置Content-Type默认值
        if (!options.headers['Content-Type']) {
          options.headers['Content-Type'] =
            'application/x-www-form-urlencoded;charset=UTF-8'
        }

        // 添加token
        if (!isNull(options.tokenKey) && !isNull(options.tokenValue)) {
          const tokenAttachType = defaultValue(
            options.tokenAttachType,
            TokenAttachType.url
          )
          // 根据tokenAttachType附加到不同地方
          switch (tokenAttachType) {
            case TokenAttachType.url:
              url += `&${options.tokenKey}=${options.tokenValue}`
              break
            case TokenAttachType.header:
              options.headers[options.tokenKey] = options.tokenValue
              break
            case TokenAttachType.body:
              if (typeof body === 'string') {
                body += `&${options.tokenKey}=${options.tokenValue}`
              } else if (body instanceof Object) {
                body[options.tokenKey] = options.tokenValue
              }
              break
            default:
              url += `&${options.tokenKey}=${options.tokenValue}`
          }
        }

        const _fetchOptions = {
          method: type,
          body,
          headers: options.headers,
          credentials: options.withCredentials ? 'include' : 'omit',
          mode: 'cors',
          timeout: options.requestTimeout
        }
        if (options.responseType) {
          _fetchOptions.responseType = options.responseType
        }
        return fetch(url, _fetchOptions)
          .then(function (response) {
            return response
          })
          .catch(function (error) {
            return error
          })
      }
    }
    export default FetchRequest