import { GET, DELETE, FORM } from './Constant';

/**
 * http请求封装类
 */
const Request = require('superagent');

function OfflineError() {
  const error = new Error('网络不给力，请重试');
  error.Type = 'offline';
  return error;
}

export default class {
  constructor() {
    this.path = `${__BASE_NAME__ === '/' ? '' : __BASE_NAME__}${__API_PATH__}`;
  }

  send(url, option) {
    /**
     * api底层接口
     */
    const paramList = url.match(/\{.*?\}/g);
    if (paramList && paramList.length > 0) {
      for (let i = 0; i < paramList.length; i += 1) {
        const key = paramList[i].substr(1, paramList[i].length - 2);
        const param = option.data[key];
        if (!param) return Promise.reject(new Error('参数错误'));
        url = url.replace(paramList[i], param);
        option.data[key] = null;
      }
    }
    const data = {};
    Object.keys(option.data).forEach(i => {
      if (option.data[i] || option.data[i] === 0 || option.data[i] === false) data[i] = option.data[i];
    });
    return new Promise((resolve, reject) => {
      const request = Request(option.method, `${this.path}${url}`).accept('application/json');
      if (option.method === GET || option.method === DELETE) {
        Object.keys(data).forEach(i => {
          if (data[i] instanceof Object && data[i].length > 0) {
            request.field(`${i}[]`, data[i]);
            data[`${i}[]`] = data[i];
            delete data[i];
          }
        });
        request.query(data);
      }
      if (option.method !== GET && option.type !== FORM) {
        request.send(data);
      }
      if (option.type === FORM) {
        Object.keys(data).forEach(i => {
          if (data[i] instanceof File) {
            request.attach(i, data[i], data[i].name);
          }
          request.field(i, data[i]);
        });
      }
      if (option.headers) {
        option.headers.forEach(header => {
          request.set(header.key, header.value);
        });
      }
      request.timeout(30 * 1000).end((error, response) => {
        if (error) {
          reject(new OfflineError());
        } else {
          resolve(response);
        }
      });
    });
  }

  request(url, option) {
    /**
     * api处理流程封装
     */
    return this.send(url, option).then(response => {
      if (response.ok && response.body) {
        return response.body;
      }
      throw new OfflineError();
    });
  }
}
