import { Component, computed, input, output, signal } from '@angular/core';

export interface <%= classify(name) %>AccountOption {
  id: string;
  label: string;
}

export interface <%= classify(name) %>Value {
  fromAccount: string;
  recipient: string;
  amount: string;
  description: string;
}

const DEFAULT_ACCOUNTS: readonly <%= classify(name) %>AccountOption[] = [
  { id: 'checking', label: 'Conta corrente' },
  { id: 'savings', label: 'Conta poupança' },
];

let nextId = 0;

@Component({
  selector: '<%= selector %>',
  imports: [],
  templateUrl: './<%= dasherize(name) %>.html',
  styleUrl: './<%= dasherize(name) %>.css',
})
export class <%= classify(name) %> {
  protected readonly instanceId = `<%= dasherize(name) %>-${nextId++}`;
  protected readonly submitted = signal(false);
  protected readonly statusMessage = signal('');
  protected readonly form = signal<<%= classify(name) %>Value>({
    fromAccount: DEFAULT_ACCOUNTS[0]?.id ?? '',
    recipient: '',
    amount: '',
    description: '',
  });

  readonly title = input('Transferir dinheiro');
  readonly accounts = input<readonly <%= classify(name) %>AccountOption[]>(DEFAULT_ACCOUNTS);
  readonly fromAccountLabel = input('Conta de origem');
  readonly recipientLabel = input('Destinatário');
  readonly amountLabel = input('Valor');
  readonly amountHint = input('Informe o valor da transferência antes de taxas ou impostos.');
  readonly descriptionLabel = input('Descrição');
  readonly descriptionHint = input('Referência opcional para esta transferência.');
  readonly submitLabel = input('Revisar transferência');
  readonly fromAccountRequiredMessage = input('Escolha a conta de origem.');
  readonly recipientRequiredMessage = input('Informe um destinatário.');
  readonly amountRequiredMessage = input('Informe um valor.');
  readonly amountInvalidMessage = input('Informe um valor maior que zero.');
  readonly invalidStatusMessage = input('Verifique os detalhes destacados da transferência e tente novamente.');
  readonly validStatusMessage = input('Os detalhes da transferência são válidos e estão prontos para revisão.');
  readonly transferSubmit = output<<%= classify(name) %>Value>();

  protected readonly titleId = computed(() => `${this.instanceId}-title`);
  protected readonly fromAccountId = computed(() => `${this.instanceId}-from-account`);
  protected readonly fromAccountErrorId = computed(() => `${this.instanceId}-from-account-error`);
  protected readonly recipientId = computed(() => `${this.instanceId}-recipient`);
  protected readonly recipientErrorId = computed(() => `${this.instanceId}-recipient-error`);
  protected readonly amountId = computed(() => `${this.instanceId}-amount`);
  protected readonly amountHintId = computed(() => `${this.instanceId}-amount-hint`);
  protected readonly amountErrorId = computed(() => `${this.instanceId}-amount-error`);
  protected readonly descriptionId = computed(() => `${this.instanceId}-description`);
  protected readonly descriptionHintId = computed(() => `${this.instanceId}-description-hint`);

  protected readonly fromAccountError = computed(() => {
    if (!this.submitted() || this.form().fromAccount) {
      return '';
    }

    return this.fromAccountRequiredMessage();
  });

  protected readonly recipientError = computed(() => {
    if (!this.submitted() || this.form().recipient.trim()) {
      return '';
    }

    return this.recipientRequiredMessage();
  });

  protected readonly amountError = computed(() => {
    if (!this.submitted()) {
      return '';
    }

    const rawAmount = this.form().amount.trim();
    if (!rawAmount) {
      return this.amountRequiredMessage();
    }

    const amount = Number(rawAmount.replace(',', '.'));
    return Number.isFinite(amount) && amount > 0 ? '' : this.amountInvalidMessage();
  });

  protected readonly isInvalid = computed(() => Boolean(this.fromAccountError() || this.recipientError() || this.amountError()));

  protected readonly fromAccountDescribedBy = computed(() => this.fromAccountError() ? this.fromAccountErrorId() : null);
  protected readonly recipientDescribedBy = computed(() => this.recipientError() ? this.recipientErrorId() : null);
  protected readonly amountDescribedBy = computed(() => {
    const ids = [this.amountHintId()];

    if (this.amountError()) {
      ids.push(this.amountErrorId());
    }

    return ids.join(' ');
  });
  protected readonly descriptionDescribedBy = computed(() => this.descriptionHintId());

  protected updateField(field: keyof <%= classify(name) %>Value, event: Event): void {
    const value = (event.target as HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement).value;
    this.form.update((current) => ({ ...current, [field]: value }));
  }

  protected submit(event: SubmitEvent): void {
    event.preventDefault();
    this.submitted.set(true);

    if (this.isInvalid()) {
      this.statusMessage.set(this.invalidStatusMessage());
      return;
    }

    this.statusMessage.set(this.validStatusMessage());
    this.transferSubmit.emit(this.form());
  }
}
