import { Component, ChangeDetectionStrategy, Input, ChangeDetectorRef, ViewChild } from '@angular/core';
import { Subscription } from 'rxjs';
import { IOption, Option } from '../../../tree';
import { FormControl, FormGroup } from '@angular/forms';
import { DateValidator } from '@shared/forms';
import { UiDatepickerComponent } from '@ui/datepicker';
import moment from 'moment';

@Component({
  selector: 'shared-input-option-date-range',
  templateUrl: 'filter-input-option-date-range.component.html',
  styleUrls: ['filter-input-option-date-range.component.scss'],
  changeDetection: ChangeDetectionStrategy.OnPush,
  standalone: false,
})
export class FilterInputOptionDateRangeComponent {
  @ViewChild('dpStart', { static: true }) startDatepicker: UiDatepickerComponent;

  @ViewChild('dpStop', { static: true }) stopDatepicker: UiDatepickerComponent;

  private _options: Option[];

  formGroup = new FormGroup({
    start: new FormControl<Date>(undefined, DateValidator),
    stop: new FormControl<Date>(undefined, DateValidator),
  });

  get startControl(): FormControl<Date> {
    return this.formGroup.get('start') as FormControl<Date>;
  }

  get stopControl(): FormControl<Date> {
    return this.formGroup.get('stop') as FormControl<Date>;
  }

  @Input()
  set options(value: IOption[]) {
    this._options = value?.map((option) => (option instanceof Option ? option : Option.create(option)));

    this.subscribeChanges();
  }

  get uiOptions() {
    return this._options;
  }

  get uiStartOption() {
    return this.uiOptions?.find((o) => o.key === 'start');
  }

  get uiStopOption() {
    return this.uiOptions?.find((o) => o.key === 'stop');
  }

  optionChangeSubscription: Subscription;

  get startDate() {
    return this.uiStartOption?.value ? new Date(this.uiStartOption?.value) : undefined;
  }

  get stopDate() {
    return this.uiStopOption?.value ? new Date(this.uiStopOption?.value) : undefined;
  }

  get minDate() {
    return this.startDate ?? new Date(0);
  }

  get maxDate() {
    return this.stopDate ?? new Date('9999-12-31');
  }

  constructor(private cdr: ChangeDetectorRef) {}

  subscribeChanges() {
    this.unsubscribeChanges();
    if (this.uiStartOption) {
      this.formGroup.patchValue({ start: this.uiStartOption.value as any as Date });

      this.optionChangeSubscription.add(
        this.uiStartOption.changes.subscribe(({ target, keys }) => {
          if (keys.includes('value')) {
            if (new Date(target.value) !== this.formGroup.get('start').value) {
              this.formGroup.patchValue({ start: target.value as any });
              this.startDatepicker?.setDisplayed(new Date(target.value));
            }
          }

          this.cdr.markForCheck();
        }),
      );
    }
    if (this.uiStopOption) {
      this.formGroup.patchValue({ stop: this.uiStopOption.value as any as Date });

      this.optionChangeSubscription.add(
        this.uiStopOption.changes.subscribe(({ target, keys }) => {
          if (keys.includes('value')) {
            if (new Date(target.value) !== this.formGroup.get('start').value) {
              this.formGroup.patchValue({ stop: target.value as any });
              this.stopDatepicker?.setDisplayed(new Date(target.value));
            }
          }

          this.cdr.markForCheck();
        }),
      );
    }
  }

  unsubscribeChanges() {
    this.optionChangeSubscription?.unsubscribe();
    this.optionChangeSubscription = new Subscription();
  }

  setStratValue(date: Date) {
    // 06.09.2023 Nino Righi --- Code abgeändert, da nicht richtig funktioniert -> Bugticket #4255 HSC // Neue Filteroption - Erscheinungsdatum
    if (new Date(date)?.toString() === 'Invalid Date') {
      this.uiStartOption?.setValue(undefined);
      this.formGroup.patchValue({ start: undefined });
      this.startDatepicker?.setDisplayed(undefined);
      this.startDatepicker?.setSelected(undefined);
      return;
    }

    const startDate = moment(date, 'L').toDate();
    startDate.setHours(0, 0, 0, 0);

    if (this.startDate === date) {
      return;
    }

    this.uiStartOption?.setValue(startDate);
    this.formGroup.patchValue({ start: startDate });
    this.startDatepicker?.setDisplayed(startDate ?? new Date());
    this.startDatepicker?.setSelected(startDate);

    if (this.stopDate && startDate > this.stopDate) {
      this.setStopValue(startDate);
    }
  }

  setStopValue(date: Date) {
    // 06.09.2023 Nino Righi --- Code abgeändert, da nicht richtig funktioniert -> Bugticket #4255 HSC // Neue Filteroption - Erscheinungsdatum
    if (new Date(date)?.toString() === 'Invalid Date') {
      this.uiStopOption?.setValue(undefined);
      this.formGroup.patchValue({ stop: undefined });
      this.stopDatepicker?.setDisplayed(undefined);
      this.stopDatepicker?.setSelected(undefined);
      return;
    }

    const stopDate = moment(date, 'L').toDate();
    stopDate.setHours(23, 59, 59, 999);

    if (this.stopDate === date) {
      return;
    }

    this.uiStopOption?.setValue(stopDate);
    this.formGroup.patchValue({ stop: stopDate });
    this.stopDatepicker?.setDisplayed(stopDate ?? new Date());
    this.stopDatepicker?.setSelected(stopDate);

    if (this.startDate && stopDate < this.startDate) {
      this.setStratValue(stopDate);
    }
  }
}
