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

interface <%= classify(name) %>Step {
  id: string;
  label: string;
  description?: string;
  disabled?: boolean;
}

const DEFAULT_STEPS: readonly <%= classify(name) %>Step[] = [
  { id: 'discover', label: 'Descobrir', description: 'Entender a necessidade atual.' },
  { id: 'build', label: 'Construir', description: 'Criar a interface acessível.' },
  { id: 'ship', label: 'Entregar', description: 'Verificar e entregar.' },
];

let nextId = 0;

@Component({
  selector: '<%= selector %>',
  imports: [],
  templateUrl: './<%= dasherize(name) %>.html',
  styleUrl: './<%= dasherize(name) %>.css',
})
export class <%= classify(name) %> {
  private readonly stepButtons = viewChildren<ElementRef<HTMLButtonElement>>('stepButton');

  protected readonly instanceId = `<%= dasherize(name) %>-${nextId++}`;

  readonly label = input('Etapas do progresso');
  readonly interactive = input(false, { transform: booleanAttribute });
  readonly steps = input<readonly <%= classify(name) %>Step[]>(DEFAULT_STEPS);
  readonly currentId = input<string | null>(null);
  readonly stepChange = output<<%= classify(name) %>Step>();

  protected readonly selectedId = signal(DEFAULT_STEPS[0]?.id ?? null);
  protected readonly activeId = computed(() => this.currentId() ?? this.selectedId());

  protected isCurrent(step: <%= classify(name) %>Step): boolean {
    return this.activeId() === step.id;
  }

  protected select(step: <%= classify(name) %>Step): void {
    if (!this.interactive() || step.disabled) {
      return;
    }

    this.selectedId.set(step.id);
    this.stepChange.emit(step);
  }

  protected navigate(event: KeyboardEvent, index: number): void {
    if (!this.interactive()) {
      return;
    }

    const steps = this.steps();
    let nextIndex: number;

    switch (event.key) {
      case 'ArrowDown':
      case 'ArrowRight':
        nextIndex = this.findEnabledIndex(index, 1, steps);
        break;
      case 'ArrowUp':
      case 'ArrowLeft':
        nextIndex = this.findEnabledIndex(index, -1, steps);
        break;
      case 'Home':
        nextIndex = steps.findIndex((step) => !step.disabled);
        break;
      case 'End':
        nextIndex = -1;
        for (let i = steps.length - 1; i >= 0; i--) {
          if (!steps[i].disabled) {
            nextIndex = i;
            break;
          }
        }
        break;
      default:
        return;
    }

    if (nextIndex < 0) {
      return;
    }

    event.preventDefault();
    this.select(steps[nextIndex]);
    this.stepButtons()[nextIndex]?.nativeElement.focus();
  }

  private findEnabledIndex(index: number, direction: 1 | -1, steps: readonly <%= classify(name) %>Step[]): number {
    if (steps.length === 0) {
      return -1;
    }

    for (let offset = 1; offset <= steps.length; offset++) {
      const nextIndex = (index + offset * direction + steps.length) % steps.length;
      if (!steps[nextIndex].disabled) {
        return nextIndex;
      }
    }

    return -1;
  }
}
