import { TimePerTourMetric, TimePerTourMetricCategoryAmount } from '../../../core/data-access/graphql/generated/generated';
import { groupBy } from '../../../core/util/group-by';

export function mergeMetrics(
  metrics: TimePerTourMetric[][]
): TimePerTourMetric[] {
  return metrics.reduce(
    (metrics, metricsByLabel) => [
      ...metrics,
      {
        ...metricsByLabel.reduce(
          (metricSum, metric) => ({
            interval: metric.interval,
            availableTime: metricSum.availableTime + metric.availableTime,
            tourAmount: metricSum.tourAmount + metric.tourAmount,
            breakEven: metricSum.breakEven + metric.breakEven,
            revenue: metricSum.revenue + metric.revenue,
            averageRevenue: metric.averageRevenue, // (metricSum.averageRevenue * index + metric.averageRevenue) / (index +1),
            personnelCost: metricSum.personnelCost + metric.personnelCost,
            consumptionCost: metricSum.consumptionCost + metric.consumptionCost,
            forecast: metricSum.forecast + metric.forecast,
            forecastRevenue: metricSum.forecastRevenue + metric.forecastRevenue,
            categoryAmounts: metric.categoryAmounts,
          }),
          {
            interval: {
              start: new Date(),
              end: new Date(),
            },
            availableTime: 0,
            tourAmount: 0,
            breakEven: 0,
            revenue: 0,
            averageRevenue: 0,
            personnelCost: 0,
            consumptionCost: 0,
            forecast: 0,
            forecastRevenue: 0,
            categoryAmounts: [],
          } as TimePerTourMetric
        ),
        averageRevenue:
          metricsByLabel.reduce(
            (sum, { averageRevenue }) => (sum += averageRevenue),
            0
          ) /
            metricsByLabel.filter(({ averageRevenue }) => averageRevenue > 0)
              .length || 0,
        categoryAmounts: Object.entries(
          groupBy(
            metricsByLabel.flatMap(({ categoryAmounts }) => categoryAmounts),
            ({ category }) => category
          )
        ).reduce(
          (categoryAmounts, [category, amounts]) => [
            ...categoryAmounts,
            {
              category,
              amount: amounts.reduce((sum, { amount }) => (sum += amount), 0),
            },
          ],
          [] as TimePerTourMetricCategoryAmount[]
        ),
      },
    ],
    []
  );
}
