import { Directive, ElementRef, computed, contentChildren, inject, input, model } from '@angular/core';

type <%= classify(name) %>Id = string;

@Directive({
  selector: '[<%= camelize(name) %>]',
  exportAs: '<%= camelize(name) %>',
  host: {
    role: 'toolbar',
    '[attr.aria-label]': 'label() || null',
  },
})
export class <%= classify(name) %> {
  private readonly items = contentChildren(<%= classify(name) %>Item, { descendants: true });

  readonly label = input('');
  readonly activeId = model<<%= classify(name) %>Id | null>(null);

  private readonly resolvedActiveId = computed<<%= classify(name) %>Id | null>(() => {
    const activeId = this.activeId();
    const items = this.items();
    if (activeId !== null && items.some((item) => item.value() === activeId)) {
      return activeId;
    }

    return items[0]?.value() ?? null;
  });

  isActive(value: <%= classify(name) %>Id): boolean {
    return this.resolvedActiveId() === value;
  }

  setActive(item: <%= classify(name) %>Item): void {
    this.activeId.set(item.value());
  }

  // Left/Right/Home/End move focus across toolbar buttons with roving tabindex (APG toolbar pattern).
  navigate(current: <%= classify(name) %>Item, event: KeyboardEvent): void {
    const items = this.items();
    const index = items.indexOf(current);
    if (index === -1) {
      return;
    }

    let nextIndex: number;
    switch (event.key) {
      case 'ArrowRight':
        nextIndex = (index + 1) % items.length;
        break;
      case 'ArrowLeft':
        nextIndex = (index - 1 + items.length) % items.length;
        break;
      case 'Home':
        nextIndex = 0;
        break;
      case 'End':
        nextIndex = items.length - 1;
        break;
      default:
        return;
    }

    event.preventDefault();
    const next = items[nextIndex];
    this.activeId.set(next.value());
    next.focus();
  }
}

@Directive({
  selector: '[<%= camelize(name) %>Item]',
  exportAs: '<%= camelize(name) %>Item',
  host: {
    '[attr.aria-pressed]': 'pressed()',
    '[attr.tabindex]': 'active() ? 0 : -1',
    '(click)': 'toggle()',
    '(keydown)': 'root.navigate(this, $event)',
  },
})
export class <%= classify(name) %>Item {
  protected readonly root = inject(<%= classify(name) %>);
  private readonly elementRef = inject<ElementRef<HTMLElement>>(ElementRef);

  readonly value = input.required<<%= classify(name) %>Id>();
  readonly pressed = model(false);
  readonly active = computed(() => this.root.isActive(this.value()));

  toggle(): void {
    this.root.setActive(this);
    this.pressed.update((value) => !value);
  }

  focus(): void {
    this.elementRef.nativeElement.focus();
  }
}
