import { Component } from '@angular/core';
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { <%= classify(name) %>, <%= classify(name) %>Item } from './<%= dasherize(name) %>';

@Component({
  imports: [<%= classify(name) %>, <%= classify(name) %>Item],
  template: `
    <ul
      <%= camelize(name) %>
      label="Account sections"
      [(activeId)]="activeId"
    >
      @for (item of items; track item.id) {
        <li
          <%= camelize(name) %>Item
          [value]="item.id"
          [disabled]="item.disabled"
          #section="<%= camelize(name) %>Item"
          [class.active]="section.active()"
        >
          <a [href]="item.href">{{ item.title }}</a>
        </li>
      }
    </ul>
  `,
})
class HostComponent {
  activeId = 'profile';
  readonly items = [
    { id: 'profile', title: 'Profile', href: '/profile', disabled: false },
    { id: 'security', title: 'Security', href: '/security', disabled: false },
    { id: 'billing', title: 'Billing', href: '/billing', disabled: true },
  ];
}

describe('<%= classify(name) %>', () => {
  let fixture: ComponentFixture<HostComponent>;
  let host: HTMLElement;

  beforeEach(async () => {
    await TestBed.configureTestingModule({
      imports: [HostComponent],
    }).compileComponents();

    fixture = TestBed.createComponent(HostComponent);
    fixture.detectChanges();
    host = fixture.nativeElement as HTMLElement;
  });

  it('decorates consumer-owned markup with list semantics and state', () => {
    const list = host.querySelector<HTMLUListElement>('ul');
    const items = Array.from(host.querySelectorAll<HTMLLIElement>('li'));

    expect(list?.getAttribute('aria-label')).toBe('Account sections');
    expect(list?.getAttribute('role')).toBe('list');
    expect(items.map((item) => item.textContent?.trim())).toEqual(['Profile', 'Security', 'Billing']);
    expect(items[0].getAttribute('aria-current')).toBe('true');
    expect(items[0].getAttribute('tabindex')).toBe('0');
    expect(items[2].getAttribute('aria-disabled')).toBe('true');
  });

  it('updates selected item when an enabled item is activated', () => {
    const items = Array.from(host.querySelectorAll<HTMLLIElement>('li'));

    items[1].click();
    fixture.detectChanges();

    expect(items[0].getAttribute('aria-current')).toBeNull();
    expect(items[1].getAttribute('aria-current')).toBe('true');

    items[2].click();
    fixture.detectChanges();

    expect(items[1].getAttribute('aria-current')).toBe('true');
    expect(items[2].getAttribute('aria-current')).toBeNull();
  });

  it('moves active state with keyboard without owning item content', () => {
    const list = host.querySelector<HTMLUListElement>('ul');
    const items = Array.from(host.querySelectorAll<HTMLLIElement>('li'));

    list?.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowDown', bubbles: true }));
    fixture.detectChanges();

    expect(items[1].getAttribute('aria-current')).toBe('true');
  });
});
