/*
 * Copyright (C) 2019 Robert Bosch GmbH Copyright (C) 2019 Robert Bosch Manufacturing Solutions GmbH, Germany. All rights reserved.
 */

import { AfterViewInit, Component, ElementRef, OnInit, QueryList, ViewChild, ViewChildren } from '@angular/core';
import { ColumnBrowserComponent, ColumnFilter, SelectionChange } from '@bci-web-core/core';
import { DynamicDataSource, FlatDataSource } from './column-browser-demo-datasource';
import { flatData, FlatModel, treeData } from './column-browser-demo-data';
import { Observable, Subject } from 'rxjs';
import { A, BACKSPACE, Z } from '@angular/cdk/keycodes';

@Component({
  selector: 'bci-column-browser-demo',
  templateUrl: './column-browser-demo.component.html',
  styleUrls: ['./column-browser-demo.component.scss'],
})
export class ColumnBrowserDemoComponent implements OnInit, AfterViewInit {
  @ViewChildren(ColumnBrowserComponent) components: QueryList<ColumnBrowserComponent>;

  @ViewChild('categoryField', { read: ElementRef }) categoryField: ElementRef;

  @ViewChild('descriptionField', { read: ElementRef }) descriptionField: ElementRef;

  @ViewChild('subField', { read: ElementRef }) subField: ElementRef;

  keyEvents = new Subject<{ index: number; keyEvent: KeyboardEvent }>();

  currentInputFilter: Observable<ColumnFilter>;

  dataSourceFlat: FlatDataSource;
  dataSourceDynamic: DynamicDataSource;

  activeColumnIndex = 0;

  columnBrowserSelection = '';

  private currentInputFilterSubject = new Subject<ColumnFilter>();

  private filters: string[] = [];

  ngOnInit(): void {
    this.currentInputFilter = this.currentInputFilterSubject.asObservable();
  }

  ngAfterViewInit(): void {
    setTimeout(() => {
      // simple data source example
      this.dataSourceFlat = new FlatDataSource();
      this.dataSourceFlat.columnBrowser = this.components.first;
      this.dataSourceFlat.totalData = flatData;
      this.dataSourceFlat.data = flatData
        .filter((item) => item.level === 0)
        .map((item) => {
          return {
            label: item.name,
            model: item,
            children: [],
          };
        });
      this.dataSourceFlat.selectionChange.subscribe(
        (data: { level: number; item: FlatModel; hasChildren: boolean }) => {
          this.activeColumnIndex = data.item && data.hasChildren ? data.level + 1 : data.level;
          this.setFocus();
        }
      );

      // dynamic data example
      this.dataSourceDynamic = new DynamicDataSource();
      this.dataSourceDynamic.columnBrowser = this.components.last;
      this.dataSourceDynamic.totalData = treeData.map((item) => {
        return {
          label: item.label,
          children: item.children,
          model: item,
        };
      });
      this.dataSourceDynamic.data = treeData.map((item) => {
        return {
          label: item.label,
          children: [],
          model: item,
        };
      });
    });
  }

  setResult(result: SelectionChange): void {
    this.columnBrowserSelection = result.item ? result.item.label : '';
  }

  onKeyDown(event: KeyboardEvent, fieldIndex: number): void {
    this.keyEvents.next({ index: fieldIndex, keyEvent: event });
  }

  onKeyUp(event: KeyboardEvent, fieldIndex: number, value: string): void {
    // tslint:disable-next-line:deprecation
    if ((event.keyCode >= A && event.keyCode <= Z) || event.keyCode === BACKSPACE) {
      this.filters = [];
      this.filters[fieldIndex] = value;
      this.currentInputFilterSubject.next({ columnIndex: fieldIndex, filter: this.filters });
    }
  }

  private setFocus() {
    switch (this.activeColumnIndex) {
      case 0:
        setTimeout(() => this.categoryField.nativeElement.focus());
        break;
      case 1:
        setTimeout(() => this.descriptionField.nativeElement.focus());
        break;
      case 2:
        setTimeout(() => this.subField.nativeElement.focus());
        break;
    }
  }
}
