import { Component, ElementRef, Injector, afterNextRender, computed, inject, input, signal, viewChild } from '@angular/core';

type <%= classify(name) %>Placement = 'top' | 'right' | 'bottom' | 'left';

let nextId = 0;

@Component({
  selector: '<%= selector %>',
  imports: [],
  templateUrl: './<%= dasherize(name) %>.html',
  styleUrl: './<%= dasherize(name) %>.css',
  host: {
    '(document:click)': 'closeOnOutsideClick($event)',
  },
})
export class <%= classify(name) %> {
  private readonly hostRef = inject<ElementRef<HTMLElement>>(ElementRef);
  private readonly injector = inject(Injector);
  private readonly popoverRef = viewChild<ElementRef<HTMLElement>>('popover');

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

  readonly triggerLabel = input('More information');
  readonly title = input('Helpful context');
  readonly content = input('Use popovers for short contextual help that needs a button, link, or richer text.');
  readonly closeLabel = input('Close popover');
  readonly placement = input<<%= classify(name) %>Placement>('bottom');

  protected readonly popoverClasses = computed(() => [
    '<%= dasherize(name) %>__panel',
    `<%= dasherize(name) %>__panel--${this.placement()}`,
  ].join(' '));

  protected toggle(): void {
    this.isOpen.update((value) => !value);
    if (!this.isOpen()) {
      return;
    }

    afterNextRender(() => this.popoverRef()?.nativeElement.focus(), { injector: this.injector });
  }

  protected close(): void {
    this.isOpen.set(false);
  }

  protected handleKeydown(event: KeyboardEvent): void {
    if (event.key === 'Escape') {
      event.preventDefault();
      this.close();
    }
  }

  protected closeOnOutsideClick(event: MouseEvent): void {
    if (!this.isOpen()) {
      return;
    }

    const target = event.target as Node;
    if (!this.hostRef.nativeElement.contains(target)) {
      this.close();
    }
  }
}
