const _ = require('lodash');
const moment = require('moment');

const stats = require('../../core/stats');
const util = require('../../core/util');
const ENV = util.gekkoEnv();

const config = util.getConfig();
const perfConfig = config.performanceAnalyzer;
const watchConfig = config.watch;

// Load the proper module that handles the results
var Handler;
if(ENV === 'child-process')
  Handler = require('./cpRelay');
else
  Handler = require('./logger');

const PerformanceAnalyzer = function() {
  _.bindAll(this);

  this.dates = {
    start: false,
    end: false
  }

  this.startPrice = 0;
  this.endPrice = 0;

  this.currency = watchConfig.currency;
  this.asset = watchConfig.asset;

  this.handler = new Handler(watchConfig);

  this.trades = 0;

  this.sharpe = 0;

  this.roundTrips = [];
  this.roundTrip = {
    entry: false,
    exit: false
  }
}

PerformanceAnalyzer.prototype.processCandle = function(candle, done) {
  this.price = candle.close;
  this.dates.end = candle.start;

  if(!this.dates.start) {
    this.dates.start = candle.start;
    this.startPrice = candle.close;
  }

  this.endPrice = candle.close;

  done();
}

PerformanceAnalyzer.prototype.processPortfolioUpdate = function(portfolio) {
  this.start = portfolio;
  this.current = _.clone(portfolio);
}

PerformanceAnalyzer.prototype.processTrade = function(trade) {
  this.trades++;
  this.current = trade.portfolio;

  const report = this.calculateReportStatistics();
  this.handler.handleTrade(trade, report);

  this.logRoundtripPart(trade);
}

PerformanceAnalyzer.prototype.logRoundtripPart = function(trade) {
  // this is not part of a valid roundtrip
  if(this.trades === 1 && trade.action === 'sell') {
    return;
  }

  if(trade.action === 'buy') {
    this.roundTrip.entry = {
      date: trade.date,
      price: trade.price,
      total: trade.portfolio.asset * trade.price,
    }
  } else if(trade.action === 'sell') {
    this.roundTrip.exit = {
      date: trade.date,
      price: trade.price,
      total: trade.portfolio.currency
    }

    this.handleRoundtrip();
  }
}

PerformanceAnalyzer.prototype.round = function(amount) {
  return amount.toFixed(8);
}

PerformanceAnalyzer.prototype.handleRoundtrip = function() {
  var roundtrip = {
    entryAt: this.roundTrip.entry.date,
    entryPrice: this.roundTrip.entry.price,
    entryBalance: this.roundTrip.entry.total,

    exitAt: this.roundTrip.exit.date,
    exitPrice: this.roundTrip.exit.price,
    exitBalance: this.roundTrip.exit.total,

    duration: this.roundTrip.exit.date.diff(this.roundTrip.entry.date)
  }

  roundtrip.pnl = roundtrip.exitBalance - roundtrip.entryBalance;
  roundtrip.profit = (100 * roundtrip.exitBalance / roundtrip.entryBalance) - 100;

  this.roundTrips.push(roundtrip);
  this.handler.handleRoundtrip(roundtrip);

  // we need a cache for sharpe

  // every time we have a new roundtrip
  // update the cached sharpe ratio
  this.sharpe = stats.sharpe(
    this.roundTrips.map(r => r.profit),
    perfConfig.riskFreeReturn
  );
}

PerformanceAnalyzer.prototype.calculateReportStatistics = function() {
  // the portfolio's balance is measured in {currency}
  let balance = this.current.currency + this.price * this.current.asset;
  let profit = balance - this.start.balance;

  let timespan = moment.duration(
    this.dates.end.diff(this.dates.start)
  );
  let relativeProfit = balance / this.start.balance * 100 - 100

  let report = {
    currency: this.currency,
    asset: this.asset,

    startTime: this.dates.start.utc().format('YYYY-MM-DD HH:mm:ss'),
    endTime: this.dates.end.utc().format('YYYY-MM-DD HH:mm:ss'),
    timespan: timespan.humanize(),
    market: this.endPrice * 100 / this.startPrice - 100,

    balance: balance,
    profit: profit,
    relativeProfit: relativeProfit,

    yearlyProfit: this.round(profit / timespan.asYears()),
    relativeYearlyProfit: this.round(relativeProfit / timespan.asYears()),

    startPrice: this.startPrice,
    endPrice: this.endPrice,
    trades: this.trades,
    startBalance: this.start.balance,
    sharpe: this.sharpe
  }

  report.alpha = report.profit - report.market;

  return report;
}

PerformanceAnalyzer.prototype.finalize = function(done) {
  const report = this.calculateReportStatistics();
  this.handler.finalize(report);
  done();
}


module.exports = PerformanceAnalyzer;

@@ -808,32 +808,43 @@
 s.roundTrip = %7B%0A
+    id: 0,%0A
     entry: false
@@ -1659,25 +1659,29 @@
  if(
+!
 this.
-trades === 1
+roundTrip.entry
  && 
@@ -1751,24 +1751,123 @@
 == 'buy') %7B%0A
+    if (this.roundTrip.exit) %7B%0A      this.roundTrip.id++;%0A      this.roundTrip.exit = false%0A    %7D%0A%0A
     this.rou
@@ -1938,32 +1938,60 @@
 e,%0A      total: 
+trade.portfolio.currency + (
 trade.portfolio.
@@ -2005,24 +2005,25 @@
  trade.price
+)
 ,%0A    %7D%0A  %7D 
@@ -2172,16 +2172,57 @@
 currency
+ + (trade.portfolio.asset * trade.price),
 %0A    %7D%0A%0A
@@ -2421,24 +2421,52 @@
 undtrip = %7B%0A
+    id: this.roundTrip.id,%0A%0A
     entryAt:
@@ -2956,25 +2956,127 @@
 rips
-.push(roundtrip);
+%5Bthis.roundTrip.id%5D = roundtrip;%0A%0A  // this will keep resending roundtrips, that is not ideal.. what do we do about it?
 %0A  t

Fix roundtrip calaculations