import { Component, Input, Output, EventEmitter } from '@angular/core';
import { Required } from '../../decorators/required.decorator';
import { v4 as uuid } from 'uuid';
import { Subject, debounceTime, distinctUntilChanged } from 'rxjs';
import { UserService } from '../../services/user/user.service';

export type InputType = 'text' | 'password' | 'email' | 'date';

@Component({
  selector: 'app-input[type]',
  templateUrl: './input.component.html',
  styleUrls: ['./input.component.scss'],
})
export class InputComponent {
  @Input() @Required() type!: InputType;

  @Input() value: string | Date = '';
  @Input() placeholder?: string = '';
  @Input() errorMessage?: string = '';
  @Input() label?: string = '';
  @Input() identifier = uuid();
  @Input() maxLength?: number;
  @Input() isDisabled = false;
  @Input() regex?: RegExp[];
  @Input() debounceTime = 500;

  @Output() valueChange = new EventEmitter<string>();
  @Output() onError = new EventEmitter<string>();
  @Output() onValidityChange = new EventEmitter<boolean>();
  @Output() onDebounce = new EventEmitter<string>();

  isValid = true;
  debouncedValue = new Subject<string>();

  constructor(
    private readonly userService: UserService
  ) {
    this.debouncedValue
      .pipe(debounceTime(this.debounceTime), distinctUntilChanged())
      .subscribe((value) => this.onDebounce.emit(value));
  }

  onChanges(event: Event) {
    const input = event.target as HTMLInputElement;
    const newValue: string = input.value;

    if (this?.maxLength && newValue.length > this.maxLength) {
      input.value = this.value.toString();
      return;
    }

    this.value = newValue;
    this.debouncedValue.next(newValue);
    this.checkInputPattern();

    this.valueChange.emit(newValue);
  }

  checkInputPattern() {
    if (this.type == 'date') {
      const inputDate = new Date(this.value);
      const actualDate = new Date();
      const age = this.userService.calculateAge(inputDate);
      
      if (
        this.value == '' ||
        inputDate > actualDate || !age ||
        age > 100
      ) {
        this.isValid = false;
        this.errorMessage = 'Por favor, insira uma data válida.';
        this.onValidityChange.emit(this.isValid);
      } else {
        this.isValid = true;
        this.errorMessage = '';
        this.onValidityChange.emit(this.isValid);
      }
      return;
    }

    if (!this.regex) {
      this.onValidityChange.emit(true);
      return;
    }

    this.isValid = this.regex.some((r) => r.test(this.value.toString()));
    this.onValidityChange.emit(this.isValid);

    if (!this.isValid) {
      this.onError.emit('Por favor, insira um valor válido.');
    }
  }
}
