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

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

@Component({
  imports: [<%= classify(name) %>, <%= classify(name) %>Header, <%= classify(name) %>Panel],
  template: `
    <div <%= camelize(name) %>>
      @for (item of items; track item.id) {
        <h3>
          <button type="button" <%= camelize(name) %>Header [value]="item.id" [expanded]="item.expanded" [disabled]="item.disabled">
            {{ item.title }}
          </button>
        </h3>
        <div <%= camelize(name) %>Panel [value]="item.id">{{ item.title }} content</div>
      }
    </div>
  `,
})
class HostComponent {
  readonly items = [
    { id: 'profile', title: 'Profile', expanded: true, disabled: false },
    { id: 'settings', title: 'Settings', expanded: false, disabled: false },
    { id: 'billing', title: 'Billing', expanded: false, 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;
  });

  function headers(): HTMLButtonElement[] {
    return Array.from(host.querySelectorAll('button'));
  }

  function panels(): HTMLElement[] {
    return Array.from(host.querySelectorAll('[role="region"]'));
  }

  it('decorates consumer-owned markup with header/region ARIA relationships', () => {
    const [profileHeader, settingsHeader] = headers();
    const [profilePanel, settingsPanel] = panels();

    expect(profileHeader.getAttribute('aria-expanded')).toBe('true');
    expect(profileHeader.getAttribute('aria-controls')).toBe(profilePanel.id);
    expect(profilePanel.getAttribute('aria-labelledby')).toBe(profileHeader.id);
    expect(profilePanel.hidden).toBe(false);

    expect(settingsHeader.getAttribute('aria-expanded')).toBe('false');
    expect(settingsPanel.hidden).toBe(true);
  });

  it('toggles an enabled header with click and keeps panel content mounted', () => {
    const [, settingsHeader] = headers();
    const [, settingsPanel] = panels();

    settingsHeader.click();
    fixture.detectChanges();

    expect(settingsHeader.getAttribute('aria-expanded')).toBe('true');
    expect(settingsPanel.hidden).toBe(false);
    expect(settingsPanel.textContent).toContain('Settings content');

    settingsHeader.click();
    fixture.detectChanges();

    expect(settingsHeader.getAttribute('aria-expanded')).toBe('false');
    expect(settingsPanel.hidden).toBe(true);
    expect(settingsPanel.textContent).toContain('Settings content');
  });

  it('does not toggle disabled headers', () => {
    const disabledHeader = headers()[2];
    const disabledPanel = panels()[2];

    disabledHeader.click();
    fixture.detectChanges();

    expect(disabledHeader.getAttribute('aria-disabled')).toBe('true');
    expect(disabledHeader.getAttribute('aria-expanded')).toBe('false');
    expect(disabledPanel.hidden).toBe(true);
  });

  it('moves focus between headers with arrow, Home, and End keys', () => {
    const [profileHeader, settingsHeader] = headers();

    profileHeader.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowDown', bubbles: true }));
    fixture.detectChanges();
    expect(document.activeElement).toBe(settingsHeader);

    settingsHeader.dispatchEvent(new KeyboardEvent('keydown', { key: 'End', bubbles: true }));
    fixture.detectChanges();
    expect(document.activeElement).toBe(settingsHeader);

    settingsHeader.dispatchEvent(new KeyboardEvent('keydown', { key: 'Home', bubbles: true }));
    fixture.detectChanges();
    expect(document.activeElement).toBe(profileHeader);
  });
});
