import {
  Component,
  Input,
  ChangeDetectionStrategy,
  Output,
  EventEmitter,
  ChangeDetectorRef,
  OnChanges,
  SimpleChanges,
} from '@angular/core';
import { SelectFilterOption } from '../../../models';
import { cloneSelectFilterOption } from '../../../utils';

@Component({
  selector: 'app-select-filter-option',
  templateUrl: 'select-filter-option.component.html',
  styleUrls: ['select-filter-option.component.scss'],
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class SelectFilterOptionComponent implements OnChanges {
  @Input()
  option: SelectFilterOption;

  @Output()
  optionChanged = new EventEmitter<SelectFilterOption>();

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

  constructor(private cdr: ChangeDetectorRef) {}

  ngOnChanges({ option }: SimpleChanges): void {
    if (option) {
      this.option = cloneSelectFilterOption(this.option);
      this.cdr.markForCheck();
    }
  }

  toggle(
    val?: ConstrainBoolean,
    { emitChanges, updateChildren } = {
      emitChanges: true,
      updateChildren: true,
    }
  ) {
    this.option.selected = typeof val === 'boolean' ? val : !this.option.selected;

    if (updateChildren && Array.isArray(this.option.options)) {
      const selectFn = (option: SelectFilterOption): SelectFilterOption => {
        return {
          ...option,
          selected: this.option.selected,
          options: Array.isArray(option.options) ? option.options.map(selectFn) : option.options,
        };
      };
      this.option.options = this.option.options.map(selectFn);
    }

    // tslint:disable-next-line: no-unused-expression
    emitChanges && this.onChange();
    this.cdr.markForCheck();
  }

  onChange() {
    this.optionChanged.emit(this.option);
  }

  toggleExpanded() {
    this.option.expanded = !this.option.expanded;
    this.onChange();
    this.cdr.markForCheck();
  }

  childChanged(option: SelectFilterOption, index: number) {
    this.option.options[index] = option;

    const selectedTrueChilds = this.option.options.filter((child) => !!child.selected);
    const selected = selectedTrueChilds.length === this.option.options.length;

    if (this.option.selected !== selected) {
      this.option.selected = selected;
    }

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