import { CommonModule } from '@angular/common';
import { Component, Input, OnChanges } from '@angular/core';
import { format } from 'date-fns';
import { BarSeriesOption, EChartsOption, LegendComponentOption } 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-time-per-tour-metric',
    imports: [CommonModule, UtilNgxEchartsModule],
    templateUrl: './time-per-tour-metric.component.html',
    styleUrls: ['./time-per-tour-metric.component.css']
})
export class TimePerTourMetricComponent implements OnChanges {
  @Input() metrics: TimePerTourMetric[] = [];
  @Input() labelFormat!: string;
  @Input() showCategories!: boolean;
  @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 categories = [
      ...new Set(
        metrics
          .flatMap(({ categoryAmounts }) => categoryAmounts)
          .map(({ category }) =>
            category === 'null' ? 'Ohne Angabe' : category
          )
      ),
    ];
    const legendData = [
      ...(this.showCategories ? categories : ['Touren']),
      'Kapazität',
    ];
    const yAxisName = 'Kapazität pro Tour';

    const legendOptions: LegendComponentOption = {
      orient: 'horizontal',
      type: 'scroll',
      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: 'Kapazität',
          type: 'line',
          data: metrics.map(({ availableTime }) => availableTime),
          smooth: true,
          markPoint: {
            symbol: 'diamond',
            symbolSize: 10,
            data: [
              {
                name: 'Min',
                coord: ['13.5.23', 90],
              },
            ],
          },
        },
        ...(this.showCategories
          ? categories.map(
              (category): BarSeriesOption => ({
                name: category,
                type: 'bar',
                stack: 'tourAmount',
                data: metrics.map(
                  ({ categoryAmounts }) =>
                    categoryAmounts.find(({ category: c }) =>
                      category === 'Ohne Angabe' ? !c : c === category
                    )?.amount ?? 0
                ),
                barWidth: 8,
              })
            )
          : ([
              {
                name: 'Touren',
                type: 'bar',
                stack: 'tourAmount',
                data: metrics.map(({ tourAmount, forecast }) => ({
                  value: tourAmount,
                  itemStyle: {
                    ...(forecast > 0 &&
                    this.metricTimeScale === MetricTimeScale.Monthview
                      ? {
                          borderRadius: [0, 0, 0, 0],
                        }
                      : {}),
                  },
                })),
                itemStyle: {
                  borderRadius: [5, 5, 0, 0],
                },
                barWidth: 8,
              },
            ] as BarSeriesOption[])),
        // TODO: Add feature toggle for forecast
        // ...(this.metricTimeScale === MetricTimeScale.Monthview
        //   ? ([
        //       {
        //         name: 'Vorausschau',
        //         type: 'bar',
        //         stack: 'tourAmount',
        //         data: metrics.map(({ forecast }) => forecast.toFixed(2)),
        //         itemStyle: {
        //           borderRadius: [5, 5, 0, 0],
        //         },
        //         barWidth: 8,
        //       },
        //     ] as BarSeriesOption[])
        //   : []),
      ],
    };
  }
}
