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

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

const DEFAULT_ITEMS: readonly <%= classify(name) %>Item[] = [
  { id: 1, label: 'Maçã' },
  { id: 2, label: 'Banana' },
  { id: 3, label: 'Cereja' },
];

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 query = signal('');
  protected readonly isOpen = signal(false);
  protected readonly activeIndex = signal(-1);

  readonly label = input('Escolha uma fruta');
  readonly items = input<readonly <%= classify(name) %>Item[]>(DEFAULT_ITEMS);

  protected readonly filteredItems = computed(() =>
    this.items().filter((item) => item.label.toLowerCase().includes(this.query().toLowerCase()))
  );

  protected readonly activeDescendantId = computed(() => {
    const active = this.filteredItems()[this.activeIndex()];
    return active ? `${this.instanceId}-option-${active.id}` : null;
  });

  protected openList(): void {
    this.isOpen.set(true);
  }

  protected onInput(event: Event): void {
    const value = (event.target as HTMLInputElement).value;
    this.query.set(value);
    this.isOpen.set(true);
    this.activeIndex.set(-1);
  }

  protected select(item: <%= classify(name) %>Item): void {
    this.query.set(item.label);
    this.isOpen.set(false);
    this.activeIndex.set(-1);
  }

  protected handleInputKeydown(event: KeyboardEvent): void {
    const options = this.filteredItems();

    switch (event.key) {
      case 'ArrowDown':
        event.preventDefault();
        this.isOpen.set(true);
        this.activeIndex.update((index) => Math.min(index + 1, options.length - 1));
        break;
      case 'ArrowUp':
        event.preventDefault();
        this.activeIndex.update((index) => Math.max(index - 1, 0));
        break;
      case 'Home':
        if (this.isOpen()) {
          event.preventDefault();
          this.activeIndex.set(0);
        }
        break;
      case 'End':
        if (this.isOpen()) {
          event.preventDefault();
          this.activeIndex.set(options.length - 1);
        }
        break;
      case 'Enter': {
        const active = options[this.activeIndex()];
        if (active) {
          event.preventDefault();
          this.select(active);
        }
        break;
      }
      case 'Escape':
        this.isOpen.set(false);
        this.activeIndex.set(-1);
        break;
    }
  }
}
