import { TestBed } from '@angular/core/testing';
import { StackedBarChart } from './stacked-bar-chart';

interface EventRow {
  readonly day: string;
  readonly eventType: string;
  readonly count: number;
}

const SAMPLE: readonly EventRow[] = [
  { day: '2026-05-14', eventType: 'auth.sign_in', count: 8 },
  { day: '2026-05-14', eventType: 'auth.sign_in.failed', count: 1 },
  { day: '2026-05-15', eventType: 'auth.sign_in', count: 12 },
  { day: '2026-05-15', eventType: 'admin.access_denied', count: 2 },
];

function render() {
  TestBed.configureTestingModule({ imports: [StackedBarChart] });
  const fixture = TestBed.createComponent<StackedBarChart<EventRow>>(StackedBarChart);
  fixture.componentRef.setInput('data', SAMPLE);
  fixture.componentRef.setInput('xKey', 'day');
  fixture.componentRef.setInput('yKey', 'count');
  fixture.componentRef.setInput('seriesKey', 'eventType');
  fixture.componentRef.setInput('caption', 'Events per day, by type');
  fixture.componentRef.setInput(
    'description',
    'Stacked bar chart showing the daily volume of audit events broken down by event type.',
  );
  fixture.componentRef.setInput('ariaLabel', 'Events per day, by type — stacked bar chart');
  fixture.detectChanges();
  return fixture;
}

describe('StackedBarChart', () => {
  beforeEach(() => TestBed.resetTestingModule());

  it('wraps the chart in a <figure role="img"> with aria-labelledby + aria-describedby', () => {
    const fixture = render();
    const figure = (fixture.nativeElement as HTMLElement).querySelector('figure.chart-figure');
    expect(figure?.getAttribute('role')).toBe('img');
    expect(figure?.getAttribute('aria-labelledby')).toMatch(/^chart-\d+-title$/);
    expect(figure?.getAttribute('aria-describedby')).toMatch(/^chart-\d+-desc$/);
  });

  it('emits an SVG with <title> + <desc> as the first two children', () => {
    const fixture = render();
    const root = fixture.nativeElement as HTMLElement;
    const svg = root.querySelector<SVGSVGElement>('.chart-canvas svg');
    expect(svg).not.toBeNull();
    const children = Array.from(svg?.children ?? []).slice(0, 2);
    expect(children[0]?.tagName).toBe('title');
    expect(children[1]?.tagName).toBe('desc');
    expect(children[0]?.textContent).toBe('Events per day, by type');
  });

  it('renders a <details> tabular fallback with three columns and one row per datum', () => {
    const fixture = render();
    const root = fixture.nativeElement as HTMLElement;
    const headers = root.querySelectorAll('details.chart-fallback thead th');
    expect(headers.length).toBe(3);
    const rows = root.querySelectorAll('details.chart-fallback tbody tr');
    expect(rows.length).toBe(SAMPLE.length);
    expect(rows[0]?.children[0]?.textContent?.trim()).toBe('2026-05-14');
    expect(rows[0]?.children[1]?.textContent?.trim()).toBe('auth.sign_in');
    expect(rows[0]?.children[2]?.textContent?.trim()).toBe('8');
  });
});
