import { Directive, HostListener, ElementRef, OnInit, Optional, AfterViewInit, OnDestroy, Input, LOCALE_ID, Inject } from '@angular/core';
import { formatNumber } from '@angular/common';
import { NgControl } from '@angular/forms';
import { Subscription } from 'rxjs';
import * as keycode from '@angular/cdk/keycodes';


@Directive({
  standalone: true,
  selector: '[henselDecimal]'
})
export class HenselMaskDecimalDirective implements OnInit, AfterViewInit, OnDestroy {
  private el: HTMLInputElement;
  private previousValue: any;
  private subscription: Subscription;
  private focused: boolean = false;
  private noOfDecimals: number = 2;
  private transformAnyway: boolean = false;S
  @Input()
  set henselDecimal(value: number) {
    // if (value || value === 0)
    this.noOfDecimals = value;
  }

  @Input() henselDecimalAllowEmpty: boolean = false;

  constructor(
    private elementRef: ElementRef,
    @Inject(LOCALE_ID) private localeId: string,
    @Optional() private control: NgControl) {
    this.el = this.elementRef.nativeElement;
  }

  useDirective(): boolean {
    return (this.noOfDecimals !== undefined && this.noOfDecimals !== null);
  }


  @HostListener('focus', ['$event.target.value'])
  onFocus() {
    if (!this.useDirective()) return;
    this.previousValue = this.control.value; //this.el.value;
    this.transform(0, this.noOfDecimals);
    this.focused = true;
    this.el.select();
  }

  @HostListener('keydown', ['$event'])
  onKeyDown(event: any) {
    if (this.useDirective()) {
      switch (event.which) {
        case keycode.ESCAPE: // ESC
          event.stopPropagation();
          // this.el.value = this.previousValue;
          this.transformAnyway = true;
          this.control.control.setValue(!this.previousValue && this.henselDecimalAllowEmpty ? this.previousValue : +(this.previousValue ?? 0));
          return false;
      }
    }
    return true;
  }


  @HostListener('blur', ['$event.target.value'])
  onBlur(value: any) {
    if (!this.useDirective()) return;
    this.focused = false;
    this.transform(this.noOfDecimals, this.noOfDecimals);
    if ((isNaN(this.control.value) || !this.control.value) && !this.henselDecimalAllowEmpty) this.control.control.setValue(0);
  }

  ngAfterViewInit(): void {
  }

  ngOnInit() {
    if (!this.useDirective()) return;
    this.subscription = this.control.valueChanges.subscribe(() => setTimeout(() => {
      this.transform(this.noOfDecimals, this.noOfDecimals);
    }, 0)
    );
  }

  ngOnDestroy(): void {
    this.subscription?.unsubscribe();
  }


  transform = (noOfDecimalsMin: number, noOfDecimalsMax: number) => {
    const controlValueIsNull = (this.control.value === null) || (this.control.value === undefined);
    if ((this.transformAnyway || !this.focused) && (!controlValueIsNull || this.el.value)) {
      if ((controlValueIsNull || this.control.value === '') && this.henselDecimalAllowEmpty) {
        this.el.value = null;
      } else this.el.value = formatNumber(+this.control.value, this.localeId, `1.${noOfDecimalsMin}-${noOfDecimalsMax}`);
      this.transformAnyway = false;
    }
  }

}
