import { CommonModule } from '@angular/common';
import { Component, Input, OnChanges } from '@angular/core';
import { format } from 'date-fns';
import {
  EChartsOption,
  LegendComponentOption,
  LineSeriesOption,
} from 'echarts';
import { BarChart, LineChart } from 'echarts/charts';
import {
  GridComponent,
  LegendComponent,
  TooltipComponent,
} from 'echarts/components';
import { BehaviorSubject } from 'rxjs';
import { UtilNgxEchartsModule } from '../../../../core/components/ngx-echarts/util-ngx-echarts.module';
import { TimePerTourMetric } from '../../../../core/data-access/graphql/generated/generated';
import { MetricTimeScale } from '../../types';

@Component({
    selector: 'dks-breakeven-metric',
    imports: [CommonModule, UtilNgxEchartsModule],
    templateUrl: './breakeven-metric.component.html',
    styleUrls: ['./breakeven-metric.component.css']
})
export class BreakevenMetricComponent implements OnChanges {
  @Input() metrics: TimePerTourMetric[] = [];
  @Input() labelFormat!: string;
  @Input() metricTimeScale!: MetricTimeScale;

  echartsExtensions = [
    BarChart,
    LineChart,
    TooltipComponent,
    GridComponent,
    LegendComponent,
  ];

  echartsOptions$: BehaviorSubject<EChartsOption> = new BehaviorSubject(
    this.generateEChartsOptions(this.metrics)
  );

  ngOnChanges(): void {
    this.echartsOptions$.next(this.generateEChartsOptions(this.metrics));
  }

  private generateEChartsOptions(metrics: TimePerTourMetric[]): EChartsOption {
    const legendData = ['Deckungsbeitrag', 'Umsatz', 'Personal', 'Verbrauch'];
    const yAxisName = 'Betrag (EUR)';

    const legendOptions: LegendComponentOption = {
      orient: 'horizontal',
      data: legendData,
    };

    return {
      tooltip: {
        trigger: 'axis',
        axisPointer: {
          type: 'shadow',
        },
      },
      grid: {
        left: '15%',
        width: '80%',
        bottom: 50,
      },
      legend: legendOptions,
      xAxis: [
        {
          type: 'category',
          axisTick: {
            show: true,
            alignWithLabel: true,
          },
          axisLabel: {
            rotate: 30,
            interval: 1,
            fontSize: 10,
          },
          data: metrics.map(({ interval: { start } }) =>
            format(new Date(start), this.labelFormat)
          ),
        },
      ],
      yAxis: [
        {
          type: 'value',
          name: yAxisName,
          position: 'left',
          alignTicks: true,
          axisLine: {
            show: true,
          },
          minInterval: 1,
          axisLabel: {
            fontSize: 10,
          },
        },
      ],
      series: [
        {
          name: 'Deckungsbeitrag',
          type: 'line',
          data: metrics.map(({ breakEven }) => {
            return {
              value: breakEven.toFixed(2),
              itemStyle: {
                borderWidth: 10,
              },
            };
          }),
          symbol: 'circle',
          symbolSize: 7,
          smooth: true,
        },
        {
          name: 'Umsatz',
          type: 'bar',
          data: metrics.map(({ revenue }) => revenue.toFixed(2)),
          itemStyle: {
            borderRadius: [5, 5, 0, 0],
          },
          barWidth: 8,
        },
        {
          name: 'Personal',
          type: 'bar',
          data: metrics.map(({ personnelCost }) => personnelCost.toFixed(2)),
          itemStyle: {
            borderRadius: [5, 5, 0, 0],
          },
          barWidth: 8,
        },
        {
          name: 'Verbrauch',
          type: 'bar',
          data: metrics.map(({ consumptionCost }) =>
            consumptionCost.toFixed(2)
          ),
          itemStyle: {
            borderRadius: [2.5, 2.5, 0, 0],
          },
          barWidth: 8,
        },
        ...(this.metricTimeScale === MetricTimeScale.Monthview
          ? ([
              {
                name: 'Vorausschau Deckungsbeitrag',
                type: 'line',
                data: metrics.map(({ breakEven, forecastRevenue }) =>
                  forecastRevenue > 0
                    ? (breakEven + forecastRevenue).toFixed(2)
                    : undefined
                ),
                symbol: 'diamond',
                symbolSize: 7,
                smooth: true,
              },
            ] as LineSeriesOption[])
          : []),
      ],
    };
  }
}
