import axios from 'axios';
import crypto from 'crypto-js';
import _ from 'lodash';

const isMissing = (param) => {
    throw new Error(`Missing parameter "${param}"`);
};

class BFXRest {

  /**
   * constructor
   *
   * @param {object} required (API_KEY, API_SECRET)
   */
  constructor({
    API_KEY,
    API_SECRET
  }) {
    this.apiKey = API_KEY;
    this.apiSecret = API_SECRET;
    this.version = 'v1';
    this.baseUrl = 'https://api.bitfinex.com';
  }


  /**
   * _nonce - Nonce generator
   *
   * @return {number}  Incremented nonce
   */
  _nonce() {
    return new Date().getTime();
  }


  /**
   * _authReq - Make request params and headers
   *
   * @param  {string} path    Path to api endpoint
   * @param  {object} params  Params for post request
   * @return {promise}        Request promise
   */
  _authReq(path, params) {
    const url = `${this.baseUrl}/${this.version}/${path}`;

    const body = {
      request: `/${this.version}/${path}`,
      nonce: JSON.stringify(this._nonce())
    };

    if (!_.isEmpty(params)) {
      _.map(params, (paramVal, paramKey) => { body[paramKey] = paramVal; })
    }

    const payload = new Buffer(JSON.stringify(body)).toString('base64');

    const signature = crypto.HmacSHA384(payload, this.apiSecret).toString(crypto.enc.Hex);

    const headers = {
      'X-BFX-APIKEY': this.apiKey,
      'X-BFX-PAYLOAD': payload,
      'X-BFX-SIGNATURE': signature
    };

    return axios.post(url, {}, {
      headers
    })
    .then(({ data }) => {
      if (data.message) {
        throw new Error(data.message);
      }

      return data;
    });
  }


  /**
   * balance - Current balance of wallets
   *
   * @return {array}  Array of wallets
   */
  walletBalance() {
    return this._authReq('balances');
  }

  newOrder({
    symbol = isMissing('symbol'),
    amount = isMissing('amount'),
    price = isMissing('price'),
    exchange = isMissing('exchange'),
    side = isMissing('side'),
    type = isMissing('type'),
    post_only = false,
    is_hidden = false
  } = {}) {

    const params = {
      symbol,
      amount,
      price,
      exchange,
      side,
      type,
      post_only,
      is_hidden
    };

    // return this._authReq('order/new', params);

    console.log('params', params);
  }

  newMultipleOrders({
    orders = isMissing('orders')
  } = {}) {

    if (_.isEmpty(orders) || !_.isArray(orders)) {
      throw new Error('Orders is empty or is not array');
    }

    const params = {
      orders
    };

    return this._authReq('order/new/multi', params);
  }

  cancelOrder({
    order_id = isMissing('order_id')
  } = {}) {

    const params = {
      order_id
    };

    return this._authReq('order/cancel', params);
  }

  cancelMultipleOrders({
    orders = isMissing('orders')
  } = {}) {

    const params = {
      order_ids: _.map(orders, order => +order.id)
    };

    return this._authReq('order/cancel/multi', params);
  }

  cancelAllOrders() {
    return this._authReq('order/cancel/all');
  }

  activeOrders() {
    return this._authReq('orders');
  }

  ordersHistory() {
    return this._authReq('orders/hist');
  }
};

export default BFXRest;

@@ -1602,32 +1602,176 @@
 a;%0A    %7D);%0A  %7D%0A%0A
+  _pubReq(path, params = %7B%7D) %7B%0A    const url = %60$%7Bthis.baseUrl%7D/$%7Bthis.version%7D/$%7Bpath%7D%60;%0A%0A    return axios.get(url, %7B%0A      params%0A    %7D);%0A  %7D%0A
 %0A  /**%0A   * bala
@@ -2335,11 +2335,8 @@
 %0A   
- //
  ret
@@ -2378,44 +2378,8 @@
 ms);
-%0A%0A    console.log('params', params);
 %0A  %7D
@@ -3190,24 +3190,24 @@
 History() %7B%0A
-
     return t
@@ -3238,16 +3238,348 @@
 t');%0A  %7D
+%0A%0A  ticker(symbol) %7B%0A    return this._pubReq(%60pubticker/$%7Bsymbol%7D%60);%0A  %7D%0A%0A  symbols() %7B%0A    return this._pubReq(%60symbols%60);%0A  %7D%0A%0A  symbolDitails() %7B%0A    return this._pubReq(%60symbols_details%60);%0A  %7D%0A%0A  trades(symbol) %7B%0A    return this._pubReq(%60trades/$%7Bsymbol%7D%60);%0A  %7D%0A%0A  stats(symbol) %7B%0A    return this._pubReq(%60stats/$%7Bsymbol%7D%60);%0A  %7D
 %0A%7D;%0A%0Aexp

add few public methods