import { Directive, ElementRef, EventEmitter, forwardRef, HostListener, Input, Output, Renderer2 } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';

@Directive({
  selector: 'input[uiSearchboxInput]',
  exportAs: 'uiSearchboxInput',
  providers: [
    {
      provide: NG_VALUE_ACCESSOR,
      multi: true,
      useExisting: forwardRef(() => UiSearchboxInputDirective),
    },
  ],
})
export class UiSearchboxInputDirective implements ControlValueAccessor {
  focused = false;

  @Input()
  value: string;

  @Output()
  inputChange = new EventEmitter<string>();

  @Output()
  select = new EventEmitter<string>();

  onChange = (value: string) => {};

  onTouched = () => {};

  get nativeElement(): HTMLInputElement {
    return this.elementRef.nativeElement;
  }

  constructor(private elementRef: ElementRef, private renderer: Renderer2) {}

  writeValue(obj: any): void {
    this.setValue(obj, { inputType: 'init' });
  }

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

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

  @HostListener('focus')
  onFocus() {
    this.focused = true;
  }

  @HostListener('blur')
  onBlur() {
    this.focused = false;
  }

  @HostListener('input', ['$event.target.value'])
  onInput(value: string) {
    this.setValue(value, { inputType: 'input' });
  }

  setValue(value: string, { inputType }: { inputType?: 'input' | 'autocomplete' | 'init' }) {
    if (this.value !== value) {
      this.value = value;

      if (inputType !== 'init') {
        this.onChange(value);
        this.onTouched();
      }

      if (inputType === 'input') {
        this.inputChange.emit(value);
      } else if (inputType === 'autocomplete') {
        this.select.emit(value);
      }
    }
    this.renderer.setProperty(this.elementRef.nativeElement, 'value', this.value);
  }
}
