import { Component, ChangeDetectionStrategy, Input, EventEmitter, Output, ChangeDetectorRef } from '@angular/core';
import { Filter, FilterOption, RangeFilterOption, SelectFilterOption } from '../../models';
import { isRangeFilter, isRangeFilterOption, isSelectFilter } from '../../type-guards';
import { isSelectFilterOption } from '../../type-guards/select-filter-option.type-guard';
import { cloneFilter } from '../../utils';

@Component({
  selector: 'ui-selected-filter-options',
  templateUrl: './selected-filter-options.component.html',
  styleUrls: ['./selected-filter-options.component.scss'],
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class UiSelectedFilterOptionsComponent {
  private _value: Filter[];

  @Input()
  get value() {
    return this._value;
  }
  set value(val) {
    this._value = val.map(cloneFilter);

    this.selectedOptions = this.value.reduce((aggr, filter) => {
      if (isSelectFilter(filter)) {
        const selected = filter.options.filter((f) => f.selected);
        return [...aggr, ...selected];
      }
      if (isRangeFilter(filter)) {
        const range = filter.options.filter((f) => f.selected);
        return [...aggr, ...range];
      }

      return [...aggr];
    }, []);

    this.cdr.markForCheck();
  }

  @Input()
  initialFilter: Filter[];

  @Output()
  valueChange = new EventEmitter<Filter[]>();

  selectedOptions: FilterOption[] = [];

  collapsed = true;

  collapseAtIndex = 3;

  constructor(private cdr: ChangeDetectorRef) {}

  resetFilter() {
    this.value = this.initialFilter;
    this.valueChange.emit(this.value);
  }

  compareFilter(): boolean {
    let result = false;

    this.value.forEach((val) => {
      const filter = this.initialFilter.find((f) => f.name === val.name);

      if (isSelectFilter(filter)) {
        if (isSelectFilter(val)) {
          val.options.forEach((option) => {
            result = result || filter.options.find((o) => o.id === option.id).selected !== option.selected;
          });
        }
      }

      if (isRangeFilter(filter)) {
        if (isRangeFilter(val)) {
          val.options.forEach((option) => {
            result = result || filter.options.find((o) => o.id === option.id).selected !== option.selected;
          });
        }
      }
    });

    return result;
  }

  unselectOption(option: FilterOption) {
    function unselectOptions(options: FilterOption[]) {
      options?.forEach((o) => {
        if (isSelectFilterOption(o)) {
          if (o.id === option.id) {
            o.selected = false;
          }
          if (isSelectFilterOption(o)) {
            unselectOptions(o.options);
          }
        }

        if (isRangeFilterOption(o)) {
          if (o.id === option.id) {
            o.selected = false;
          }
        }
      });
    }

    this.value.forEach((filter) => unselectOptions(filter.options));
    this.valueChange.emit(this.value);
    this.cdr.markForCheck();
  }
}
