import { Component } from '@angular/core';
import { FormControl } from '@angular/forms';
import { MatChipListboxChange } from '@angular/material/chips';
import { addDays, addHours, format, isSunday } from 'date-fns';
import {
  BehaviorSubject,
  combineLatest,
  map,
  startWith,
  switchMap,
} from 'rxjs';
import { groupBy } from '../../../core/util/group-by';
import { ManagerDashboardService } from '../manager-dashboard.service';
import {
  DashboardViewType,
  DiagrammType,
  MetricTimeScale,
  OrdinanceTypes,
} from '../types';
import { mergeMetrics } from '../util/merge-metric';

@Component({
    selector: 'dks-dayview',
    templateUrl: './dayview.component.html',
    styleUrls: ['./dayview.component.css'],
    standalone: false
})
export class DayviewComponent {
  OrdinanceTypes = OrdinanceTypes;
  DiagrammType = DiagrammType;
  DashboardViewType = DashboardViewType;
  minSelectableDate = new Date('2023-01-01');
  metricTimeScale = MetricTimeScale.Dayview;
  selectedDate = new FormControl<Date>(new Date());
  selectedDate$ = this.selectedDate.valueChanges.pipe(
    startWith(this.selectedDate.value),
    map((date) => (date?.getHours() === 0 ? addHours(date, 12) : date))
  );
  selectedMetric$ = new BehaviorSubject<DiagrammType>(DiagrammType.Revenue);
  selectedViewType$ = new BehaviorSubject<DashboardViewType>(
    DashboardViewType.Gesamt
  );

  vm$;

  constructor(
    private readonly managerDashboardService: ManagerDashboardService
  ) {
    this.vm$ = combineLatest([
      this.selectedDate$.pipe(
        switchMap((selectedDate) =>
          this.managerDashboardService.getTimePerTourMetricByOrdinanceTypeForDay(
            OrdinanceTypes.BTW,
            selectedDate ?? new Date()
          )
        )
      ),
      this.selectedDate$.pipe(
        switchMap((selectedDate) =>
          this.managerDashboardService.getTimePerTourMetricByOrdinanceTypeForDay(
            OrdinanceTypes.TSW,
            selectedDate ?? new Date()
          )
        )
      ),
      this.selectedDate$.pipe(
        switchMap((selectedDate) =>
          this.managerDashboardService.getTimePerTourMetricByOrdinanceTypeForDay(
            OrdinanceTypes.KTW,
            selectedDate ?? new Date()
          )
        )
      ),
      this.selectedMetric$,
      this.selectedDate$,
      this.managerDashboardService.isLoadingDayview$,
      this.selectedViewType$,
    ]).pipe(
      map(
        ([
          btwMetrics,
          tswMetrics,
          ktwMetrics,
          selectedMetric,
          selectedDate,
          isLoading,
          selectedViewType,
        ]) => ({
          btwMetrics,
          tswMetrics,
          ktwMetrics,
          selectedMetric,
          selectedDate,
          isLoading,
          selectedViewType,
          combinedMetrics: mergeMetrics(
            Object.values(
              groupBy(
                [...btwMetrics, ...tswMetrics, ...ktwMetrics],
                ({ interval: { start } }) => format(new Date(start), 'HH:mm')
              )
            )
          ),
        })
      )
    );
  }

  notSunday = (date: Date | null): boolean => {
    return !isSunday(date ?? new Date());
  };

  addDayToSelectedDate(days: number): void {
    const nextSelectedDate = addDays(
      this.selectedDate.value ?? new Date(),
      days
    );
    if (isSunday(nextSelectedDate)) {
      this.selectedDate.setValue(addDays(nextSelectedDate, days));
    } else {
      this.selectedDate.setValue(nextSelectedDate);
    }
  }

  changeSelectedType(event: MatChipListboxChange) {
    this.selectedMetric$.next(event.value);
  }

  setSelectedViewType(viewType: DashboardViewType) {
    this.selectedViewType$.next(viewType);
  }
}
