import { Component, Input, OnInit, OnDestroy, Output, EventEmitter, ChangeDetectionStrategy, ViewChild, ElementRef } from '@angular/core';
import { Subject, Observable } from 'rxjs';
import { isNullOrUndefined } from 'util';
import { FormControl } from '@angular/forms';

@Component({
  selector: 'app-shelf-searchbar',
  templateUrl: './searchbar.component.html',
  styleUrls: ['./searchbar.component.scss'],
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class ShelfSearchbarComponent implements OnInit, OnDestroy {
  searchForm: FormControl;
  searchQuery$: Observable<string>;

  @ViewChild('submitButton') submitButton: ElementRef<HTMLButtonElement>;
  @ViewChild('searchbar') searchbar: ElementRef<HTMLInputElement>;

  @Input() isIPad = false;
  @Input() isFetchingData = false;
  @Input() mode: 'standalone' | 'autocomplete' = 'standalone';
  @Input() errorMessage = '';
  @Input() placeholder = 'Kundenname, Abholfach, Abholschein, Kundenkartennummer';
  @Output() change = new EventEmitter<string>();
  @Output() reset = new EventEmitter<void>();
  @Output() search = new EventEmitter<{
    value: string;
    type: 'search' | 'scan';
  }>();
  @Output() scan = new EventEmitter<void>();

  destroy$ = new Subject();

  constructor() {}

  ngOnInit() {
    this.initForm();
  }

  ngOnDestroy() {
    this.destroy$.next();
  }

  initForm() {
    this.searchForm = new FormControl(null);
    this.searchQuery$ = this.searchForm.valueChanges;
  }

  resetForm() {
    this.searchForm.reset();
    this.reset.emit();
  }

  setError(message: string) {
    this.errorMessage = message;
  }

  handleBtnClick(targetEl: HTMLButtonElement) {
    this.triggerSearch(this.getSearchType(targetEl));
  }

  triggerSearch(type: 'search' | 'scan') {
    if (type === 'scan') {
      return this.triggerScan();
    }

    const isValidInput = this.validateSearchInputBeforeSubmit(this.searchForm.value);

    if (!isValidInput) {
      return;
    }

    this.search.emit({
      value: this.searchForm.value,
      type,
    });
  }

  triggerScan() {
    this.scan.emit();
  }

  onInput(event: KeyboardEvent) {
    if (!this.isNumberOrLetter(event.key)) {
      this.change.emit(this.searchForm.value);
    }
  }

  setFocus(target: 'input' | 'button') {
    if (target === 'button') {
      if (this.submitButton && this.submitButton.nativeElement) {
        return this.submitButton.nativeElement.focus();
      }
    }
    if (target === 'input') {
      if (this.searchbar && this.searchbar.nativeElement) {
        setTimeout(() => this.searchbar.nativeElement.focus(), 1000);
      }
    }
  }

  setInputValue(queryString: string) {
    if (this.searchForm) {
      this.searchForm.setValue(queryString);
    }
  }

  private validateSearchInputBeforeSubmit(searchInput: string): boolean {
    return !isNullOrUndefined(searchInput) && searchInput.length >= 1;
  }

  private getSearchType(target: HTMLButtonElement): 'search' | 'scan' {
    if (!target) {
      return 'search';
    }
    return target.classList.contains('scan') ? 'scan' : 'search';
  }

  private isNumberOrLetter(key: string): boolean {
    return key.includes('Digit') || key.includes('Key');
  }
}
