import { Component } from '@angular/core';
import { FormControl } from '@angular/forms';
import { MatChipListboxChange } from '@angular/material/chips';
import { MatDatepicker } from '@angular/material/datepicker';
import { addDays, addMonths, format, isSunday, startOfMonth } 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-monthview',
  templateUrl: './monthview.component.html',
  styleUrls: ['./monthview.component.css'],
  standalone: false,
})
export class MonthviewComponent {
  OrdinanceTypes = OrdinanceTypes;
  DiagrammType = DiagrammType;
  DashboardViewType = DashboardViewType;
  minSelectableDate = new Date('2022-08-01');
  metricTimeScale = MetricTimeScale.Monthview;
  selectedDate = new FormControl<Date>(addDays(startOfMonth(new Date()), 1));
  selectedDate$ = this.selectedDate.valueChanges.pipe(
    startWith(this.selectedDate.value)
  );
  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.getTimePerTourMetricByOrdinanceTypeForMonth(
            OrdinanceTypes.BTW,
            selectedDate ?? new Date()
          )
        )
      ),
      this.selectedDate$.pipe(
        switchMap((selectedDate) =>
          this.managerDashboardService.getTimePerTourMetricByOrdinanceTypeForMonth(
            OrdinanceTypes.TSW,
            selectedDate ?? new Date()
          )
        )
      ),
      this.selectedDate$.pipe(
        switchMap((selectedDate) =>
          this.managerDashboardService.getTimePerTourMetricByOrdinanceTypeForMonth(
            OrdinanceTypes.KTW,
            selectedDate ?? new Date()
          )
        )
      ),
      this.selectedMetric$,
      this.selectedDate$,
      this.managerDashboardService.isLoadingMonthview$,
      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), 'd.M.yy')
              )
            )
          ),
        })
      )
    );
  }

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

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

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

  setMonthAndYear(
    normalizedMonthAndYear: Date,
    datepicker: MatDatepicker<Date>
  ) {
    this.selectedDate.setValue(addDays(normalizedMonthAndYear, 1));
    datepicker.close();
  }

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