import { ActiveDescendantKeyManager } from '@angular/cdk/a11y';
import {
  Component,
  ChangeDetectionStrategy,
  QueryList,
  ViewEncapsulation,
  ContentChildren,
  AfterContentInit,
  EventEmitter,
  Output,
  ChangeDetectorRef,
  OnDestroy,
} from '@angular/core';
import { Subscription } from 'rxjs';
import { UiAutocompleteItemComponent } from './autocomplete-item.component';

@Component({
  selector: 'ui-autocomplete',
  templateUrl: 'autocomplete.component.html',
  styleUrls: ['autocomplete.scss'],
  changeDetection: ChangeDetectionStrategy.OnPush,
  encapsulation: ViewEncapsulation.None,
  exportAs: 'uiAutocomplete',
})
export class UiAutocompleteComponent implements AfterContentInit, OnDestroy {
  @ContentChildren(UiAutocompleteItemComponent)
  items: QueryList<UiAutocompleteItemComponent>;

  @Output()
  selectItem = new EventEmitter<any>();

  get activeItem() {
    return this.listKeyManager?.activeItem;
  }

  opend = false;

  listKeyManager: ActiveDescendantKeyManager<UiAutocompleteItemComponent>;

  subscriptions = new Subscription();

  constructor(private cdr: ChangeDetectorRef) {}

  ngAfterContentInit() {
    this.listKeyManager = new ActiveDescendantKeyManager(this.items);
    this.listKeyManager.withWrap(true);
    this.registerItemOnClick();
    this.subscriptions.add(this.items.changes.subscribe(() => this.registerItemOnClick()));
  }

  ngOnDestroy() {
    this.subscriptions?.unsubscribe();
  }

  registerItemOnClick() {
    this.items.forEach((item) =>
      item.registerOnClick((aitem) => {
        this.selectItem.emit(aitem);
      })
    );
  }

  handleKeyboardEvent(event: KeyboardEvent) {
    if (this.opend) {
      switch (event.key) {
        case 'Enter':
          this.selectItem.emit(this.activeItem);
        case 'Escape':
          this.close();
          break;
        default:
          this.listKeyManager.onKeydown(event);
      }
    }
  }

  open() {
    this.opend = true;
    this.cdr.markForCheck();
  }

  close() {
    this.opend = false;
    this.listKeyManager.setActiveItem(undefined);
    this.cdr.markForCheck();
  }
}
