import {
  ChangeDetectionStrategy,
  Component,
  effect,
  input,
  model,
  output,
} from '@angular/core';

import {
  ValidatorFn,
  ReactiveFormsModule,
  AsyncValidatorFn,
  FormControl,
} from '@angular/forms';
import { ButtonComponent } from '@isa/ui/buttons';

export interface NumberInputValidation {
  /** The key to use for the validation error */
  errorKey: string;

  /** The validation function to apply */
  inputValidator: ValidatorFn | AsyncValidatorFn;

  /** Validation Error Message */
  errorText?: string;
}

import {
  InputControlDirective,
  TextFieldClearComponent,
  TextFieldComponent,
  TextFieldContainerComponent,
  TextFieldErrorsComponent,
} from '@isa/ui/input-controls';

@Component({
  selector: 'ui-number-input',
  templateUrl: './number-input.component.html',
  changeDetection: ChangeDetectionStrategy.OnPush,
  standalone: true,
  imports: [
    InputControlDirective,
    TextFieldClearComponent,
    TextFieldComponent,
    TextFieldContainerComponent,
    TextFieldErrorsComponent,
    ReactiveFormsModule,
    ButtonComponent,
  ],
  host: {
    class: 'ui-number-input flex flex-col gap-8',
  },
})
export class NumberInputComponent {
  message = input.required<string>();

  subMessage = input<string | undefined>(undefined);

  subMessageValue = input<string | undefined>(undefined);

  inputLabel = input<string | undefined>(undefined);

  inputValue = model<number | undefined>(undefined);

  inputDefaultValue = input<number | undefined>(undefined);

  inputValidation = input<NumberInputValidation[] | undefined>(undefined);

  closeText = input<string | undefined>(undefined);

  closed = output<void>();

  confirmText = input<string | undefined>(undefined);

  confirmed = output<number | undefined>();

  control = new FormControl<number | null>(null, {});

  controlValueEffect = effect(() => {
    const value = this.inputValue();
    const defaultValue = this.inputDefaultValue();

    if (typeof value !== 'number') {
      this.control.setValue(defaultValue ?? null);
      return;
    }

    if (value !== this.control.value) {
      this.control.setValue(value);
    }
  });

  controlValidationEffect = effect(() => {
    const validation = this.inputValidation();
    if (validation) {
      this.control.setValidators(validation.map((v) => v.inputValidator));
      this.control.updateValueAndValidity();
    } else {
      this.control.clearValidators();
      this.control.updateValueAndValidity();
    }
  });

  confirm() {
    if (this.control.valid) {
      this.confirmed.emit(this.control.value ?? undefined);
    }
  }
}
