'use strict';

import DomainClient from './domain.client';
import {Metrics, OpenTrade, Trade} from './metaStats.client.schemas';

export * from './metaStats.client.schemas';

/**
 * metaapi.cloud MetaStats MetaTrader API client
 */
export default class MetaStatsClient {
  
  private _domainClient: DomainClient;

  /**
   * Constructs MetaStats API client instance
   * @param {DomainClient} domainClient domain client
   */
  constructor(domainClient: DomainClient) {
    this._domainClient = domainClient;
  }

  /**
   * Returns metrics of MetaApi account. This API call is billable
   * https://metaapi.cloud/docs/metastats/restApi/api/calculateMetrics/
   * @param {String} accountId MetaApi account id
   * @param {Boolean} [includeOpenPositions] indicates whether open positions will be included
   * in the metrics, default false
   * @return {Metrics} account metrics
   */
  async getMetrics(accountId: string, includeOpenPositions = false): Promise<Metrics> {

    const getOpts = (host, id) => ({
      url: host + `/users/current/accounts/${id}/metrics`,
      method: 'GET',
      headers: {
        'auth-token': this._domainClient.token
      },
      params: {includeOpenPositions},
      json: true,
    });
  
    const {metrics} = await this._domainClient.requestMetastats(getOpts, accountId);
    return metrics;
  }

  /**
   * Returns historical trades of MetaApi account
   * https://metaapi.cloud/docs/metastats/restApi/api/getHistoricalTrades/
   * @param {String} accountId MetaApi account id
   * @param {String} startTime start of time range, inclusive
   * @param {String} endTime end of time range, exclusive
   * @param {Boolean} [updateHistory] update historical trades before returning results. 
   * If set to true, the API call will be counted towards billable MetaStats API calls. 
   * If set to false, the API call is not billable. Default is true
   * @param {Number} [limit] pagination limit
   * @param {Number} [offset] pagination offset
   * @param {Number} [marketValue ] trade market value
   * @return {Array<Trade>} account historical trades
   */
  async getAccountTrades(
    accountId: string, startTime: string, endTime: string, updateHistory = true, limit = 1000, offset = 0
  ): Promise<Array<Trade>> {

    const getOpts = (host, id) => ({
      url: host + `/users/current/accounts/${id}/historical-trades/${startTime}/${endTime}`,
      method: 'GET',
      headers: {
        'auth-token': this._domainClient.token
      },
      params: {updateHistory, limit, offset},
      json: true,
    });

    const {trades} = await this._domainClient.requestMetastats(getOpts, accountId);
    return trades;
  }

  /**
   * Returns open trades of MetaApi account. This API call is not billable
   * https://metaapi.cloud/docs/metastats/restApi/api/getOpenTrades/
   * @param {String} accountId MetaApi account id
   * @param {Number} [marketValue] trade market value
   * @return {Array<OpenTrade>} account historical trades
   */
  async getAccountOpenTrades(accountId: string): Promise<Array<OpenTrade>> {

    const getOpts = (host, id) => ({
      url: host + `/users/current/accounts/${id}/open-trades`,
      method: 'GET',
      headers: {
        'auth-token': this._domainClient.token
      },
      json: true,
    });

    const {openTrades} = await this._domainClient.requestMetastats(getOpts, accountId);
    return openTrades;
  }

  /**
   * Resets metrics and trade history for a trading account from MetaStats. The data will be downloaded from trading
   * account again when you calculate the MetaStats metrics next time. This API call is not billable
   * @param accountId MetaApi account id
   * @return promise resolving when removed
   */
  async resetMetrics(accountId: string): Promise<void> {

    const getOpts = (host: string, id: string) => ({
      url: host + `/users/current/accounts/${id}`,
      method: 'DELETE',
      headers: {
        'auth-token': this._domainClient.token
      },
      json: true
    });

    return this._domainClient.requestMetastats(getOpts, accountId);
  }
}
