import { Directive, ElementRef, forwardRef, HostBinding, HostListener, Input } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
import { UiFormControlDirective } from '@ui/form-control';
import { isBoolean } from '@utils/common';

@Directive({
  selector: 'input[uiInput][type="checkbox"]',
  providers: [
    {
      provide: NG_VALUE_ACCESSOR,
      useExisting: forwardRef(() => UiCheckboxInputDirective),
      multi: true,
    },
    {
      provide: UiFormControlDirective,
      useExisting: UiCheckboxInputDirective,
    },
  ],
  exportAs: 'uiInput',
})
export class UiCheckboxInputDirective extends UiFormControlDirective<any> implements ControlValueAccessor {
  readonly type = 'checkbox';

  @Input()
  value: any = true;

  private selectedValue: any;

  @HostBinding('checked')
  checked: boolean;

  @HostBinding('disabled')
  isDisabled: boolean;

  private onChange = (_: any) => {};
  private onTouched = () => {};

  constructor(private elementRef: ElementRef) {
    super();
  }

  get valueEmpty(): boolean {
    return false;
  }

  clear(): void {
    this.checked = false;
  }

  focus(): void {
    this.elementRef.nativeElement.focus();
  }

  writeValue(obj: any): void {
    this.selectedValue = obj;
    this.updateChecked();
  }

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

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

  setDisabledState?(isDisabled: boolean): void {
    this.isDisabled = isDisabled;
  }

  @HostListener('click')
  check() {
    if (isBoolean(this.selectedValue)) {
      this.selectedValue = !this.selectedValue;
    } else {
      if (this.selectedValue === this.value) {
        this.selectedValue = undefined;
      } else {
        this.selectedValue = this.value;
      }
    }

    this.updateChecked();

    this.onChange(this.selectedValue);
    this.onTouched();
  }

  updateChecked() {
    this.checked = isBoolean(this.selectedValue) ? this.selectedValue : this.value == this.selectedValue;
  }
}
