import { Directive, forwardRef, Input } from '@angular/core';
import { AbstractControl, NG_VALIDATORS, Validator } from '@angular/forms';

@Directive({
  standalone: true,
  selector: '[hensel-validator]',
  providers: [
    { provide: NG_VALIDATORS, useExisting: forwardRef(() => HenselValidator), multi: true }
  ]
})

export class HenselValidator implements Validator {
  private valueFromExcl?: number;
  private valueFromIncl?: number;
  private valueToIncl?: number;
  private valueToExcl?: number;
  private valid: boolean = true;
  private control: AbstractControl;

  @Input()
  set greater(value: number) {
    this.valueFromExcl = value;
    this.control?.updateValueAndValidity();
  }


  @Input()
  set notless(value: number) {
    this.valueFromIncl = value;
    this.control?.updateValueAndValidity();
  }


  @Input()
  set notgreater(value: number) {
    this.valueToIncl = value;
    this.control?.updateValueAndValidity();
  }


  @Input()
  set less(value: number) {
    this.valueToExcl = value;
    this.control?.updateValueAndValidity();
  }

  @Input()
  set isValid(value: boolean) {
    this.valid = value;
    this.control?.updateValueAndValidity();
  }

  constructor(
    // @Attribute('greater') public valueFromExcl?: number,
    // @Attribute('notless') public valueFromIncl?: number,
    // @Attribute('notgreater') public valueToIncl?: number,
    // @Attribute('less') public valueToExcl?: number,
  ) { }

  validate(c: AbstractControl): { [key: string]: any } {
    // self value
    this.control = c;
    if (c.value === null || c.value === 'undefined' || c.value === '') return null;
    const val = +c.value;
    if (((this.valueFromExcl || this.valueFromExcl === 0) && val <= this.valueFromExcl)
      || ((this.valueFromIncl || this.valueFromIncl === 0) && val < this.valueFromIncl)
      || ((this.valueToIncl || this.valueToIncl === 0) && val > this.valueToIncl)
      || ((this.valueToExcl || this.valueToExcl === 0) && val >= this.valueToExcl)
      || !this.valid
    ) {
      return { validateEqual: false };
    }
    return null;
  }
}
