import {
  Component,
  OnInit,
  forwardRef,
  Input,
  ChangeDetectionStrategy,
  ChangeDetectorRef,
  EventEmitter,
  Output,
  OnChanges,
  SimpleChanges,
  OnDestroy,
  ViewChild,
  ElementRef,
} from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
import { Filter } from '../../../models';
import { cloneFilter } from '../../../utils';
import { FilterGroup } from '../../filter-group';

@Component({
  selector: 'ui-filter-group',
  templateUrl: 'filter-group.component.html',
  styleUrls: ['filter-group.component.scss'],
  providers: [
    {
      provide: NG_VALUE_ACCESSOR,
      useExisting: forwardRef(() => UiFilterGroupComponent),
      multi: true,
    },
    {
      provide: FilterGroup,
      useExisting: forwardRef(() => UiFilterGroupComponent),
    },
  ],
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class UiFilterGroupComponent extends FilterGroup implements OnInit, ControlValueAccessor, OnChanges, OnDestroy {
  @Input()
  disabled: boolean;

  private _value: Filter[];

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

  @ViewChild('selectionContainer')
  selectionContainerRef: ElementRef;

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

  @Input()
  active: Filter;
  @Output()
  activeChange = new EventEmitter<Filter>();

  @Input() module: 'Customer' | 'Branch' = 'Branch';

  onChange: (value: Filter[]) => void;

  onTouch: (value: Filter[]) => void;

  trackByKeyOrName = (filter: Filter) => filter.key || filter.name;

  constructor(protected cdr: ChangeDetectorRef) {
    super();
  }

  ngOnChanges({ value }: SimpleChanges) {
    if (value && value.isFirstChange() && !this.active) {
      this.active = this.value[0];
    }
  }

  ngOnInit() {
    this.updateView.subscribe((_) => this.cdr.markForCheck());
  }

  ngOnDestroy() {
    this.updateView?.complete();
  }

  setActive(preSelectCategory: Filter) {
    this.active = preSelectCategory;
    this.activeChange.emit(this.active);
  }

  writeValue(obj: Filter[]): void {
    if (obj !== this.value) {
      this.value = obj.map(cloneFilter);
      this.cdr.markForCheck();
    }
  }

  registerOnChange(fn: any): void {
    this.onChange = fn;
  }

  registerOnTouched(fn: any): void {
    this.onTouch = fn;
  }

  setDisabledState?(isDisabled: boolean): void {
    this.disabled = isDisabled;
  }
}
