import { Component, ChangeDetectionStrategy, Input, ChangeDetectorRef, OnInit, Output, OnChanges, EventEmitter } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { RangeFilter, SelectFilter } from '../../../models';
import { FilterGroup } from '../../filter-group';
import { maxValueRelativeTo, minValueRelativeTo } from './range-filter.validator';

@Component({
  selector: 'ui-range-filter',
  templateUrl: 'range-filter.component.html',
  styleUrls: ['range-filter.component.scss'],
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class UiRangeFilterComponent implements OnInit, OnChanges {
  @Output() category = new EventEmitter<SelectFilter | RangeFilter>();

  @Input()
  filter: RangeFilter;

  formGroup: FormGroup;

  get error() {
    let errors = this.formGroup?.get('start').errors;

    if (errors == null) {
      errors = this.formGroup?.get('stop').errors;
    }
    if (errors == null) {
      return null;
    }

    for (const key in errors) {
      switch (key) {
        case 'min':
          return `Der Wert darf nicht kleiner als ${errors[key].min} sein.`;
        case 'max':
          return `Der Wert darf nicht größer als ${errors[key].max} sein.`;
        case 'pattern':
          return `Es werden nur ganzzahlige Werte akzeptiert.`;
        default:
          return errors[key];
      }
    }
  }

  constructor(protected cdr: ChangeDetectorRef, public filterGroup: FilterGroup, private fb: FormBuilder) {}

  ngOnInit() {
    this.formGroup = this.fb.group({
      start: this.fb.control(this.filter.options[0].value, [
        Validators.min(0),
        Validators.max(99),
        Validators.pattern('^[0-9]+$'), // Only numbers
        maxValueRelativeTo((c) => c?.parent?.get('stop')),
      ]),
      stop: this.fb.control(this.filter.options[1].value, [
        Validators.min(0),
        Validators.max(99),
        Validators.pattern('^[0-9]+$'), // Only numbers
        minValueRelativeTo((c) => c?.parent?.get('start')),
      ]),
    });

    this.formGroup.valueChanges.subscribe(({ start, stop }) => {
      const filterStart = this.filter?.options[0]?.value;
      const filterStop = this.filter?.options[1]?.value;

      const filter = this.filter;

      let startChanged = false;
      let stopChanged = false;

      if (filterStart != start) {
        startChanged = true;
        filter.options[0].value = start;
        filter.options[0].selected = !!start;
        this.formGroup.get('stop').updateValueAndValidity();

        this.filterGroup.setRangeOption(filter, filter.options[0]);
      }
      if (filterStop != stop) {
        stopChanged = true;
        filter.options[1].value = stop;
        filter.options[1].selected = !!stop;
        this.formGroup.get('start').updateValueAndValidity();

        this.filterGroup.setRangeOption(filter, filter.options[1]);
      }

      if (startChanged || stopChanged) {
        this.category.emit(filter);
        this.cdr.markForCheck();
      }
    });
  }

  ngOnChanges(changes) {
    if (changes.filter) {
      this.updateFormControl();
    }
  }

  updateFormControl() {
    const startCtrl = this.formGroup?.get('start');
    const stopCtrl = this.formGroup?.get('stop');

    const start = this.filter?.options[0]?.value;
    const stop = this.filter?.options[1]?.value;

    if (startCtrl && startCtrl.value != start) {
      startCtrl.setValue(+start);
    }

    if (stopCtrl && stopCtrl?.value != stop) {
      stopCtrl.setValue(+stop);
    }
  }

  // Correctly Update Input Field Values on open Filter Overlay and on Filter Reset
  // updateControl() {
  //   const readingAgeFilter = this.filterGroup.value.find((filter) => filter.key === 'reading-age');
  //   if (isRangeFilter(readingAgeFilter)) {
  //     if (this.formGroup.get('start').hasError('valueRange') || this.formGroup.get('stop').hasError('valueRange')) {
  //       this.error = true;
  //     } else {
  //       this.error = false;
  //     }
  //     this.formGroup.get('start').setValue(readingAgeFilter.options[0].value);
  //     this.formGroup.get('stop').setValue(readingAgeFilter.options[1].value);
  //   }
  // }

  // private preSelectCategory = () => {
  //   this.category.emit(this.filter);
  // };
}
