/**
 * Der Hinweis-Baustein.
 *
 * Anlass: Die Verlustanzeige der Datensicherung reicht Absätze und eine
 * Liste als Kinder hinein. Bis 0.20.0 trug der Baustein jeden Inhalt in
 * einem `<p>` – ungültiges HTML, React meldete im Testlauf „In HTML, <ul>
 * cannot be a descendant of <p>“. Ein Browser, der solches HTML einliest,
 * repariert den Baum still; was ein Screenreader vorliest, entspräche dann
 * nicht mehr dem geschriebenen Code. Seither wählt `blockinhalt` einen
 * `<div>` als Textträger – diese Tests halten beide Varianten fest.
 */

import { render, screen } from '@testing-library/react';
import { describe, expect, it, vi } from 'vitest';

import { Hinweis } from '../src/renderer/src/components/lernen/Hinweis';

describe('Hinweis mit reinem Text', () => {
  it('trägt den Inhalt in einem echten Absatz', () => {
    /* Die Absatzsemantik soll die Blockvariante nicht stillschweigend
       verdrängen – kurze Hinweise bleiben, was sie sind: ein Absatz. */
    const { container } = render(<Hinweis art="hinweis">Nur ein Satz.</Hinweis>);

    const traeger = container.querySelector('.hinweis__text');
    expect(traeger?.tagName).toBe('P');
    expect(traeger).toHaveTextContent('Hinweis: Nur ein Satz.');
  });

  it('wird auf Wunsch als Meldung angesagt', () => {
    render(
      <Hinweis art="fehler" alsMeldung>
        Speichern fehlgeschlagen.
      </Hinweis>,
    );

    expect(screen.getByRole('alert')).toHaveTextContent('Fehler: Speichern fehlgeschlagen.');
  });
});

describe('Hinweis mit Blockinhalt', () => {
  function blockbeispiel(): React.JSX.Element {
    return (
      <Hinweis art="fehler" blockinhalt>
        <p>Das geht verloren:</p>
        <ul>
          <li>Ein Profil</li>
        </ul>
        <p>Mehr nicht.</p>
      </Hinweis>
    );
  }

  it('legt Absätze und Liste nie in einen Absatz', () => {
    const { container } = render(blockbeispiel());

    expect(container.querySelector('.hinweis__text')?.tagName).toBe('DIV');
    expect(container.querySelector('p ul')).toBeNull();
    expect(container.querySelector('p p')).toBeNull();
  });

  it('rendert ohne DOM-Verschachtelungswarnung von React', () => {
    /* Genau die Meldung, die der Fehlerkasten der Datensicherung bis 0.20.0
       auslöste. `restoreMocks` räumt den Spion nach dem Test wieder ab. */
    const fehlerSpion = vi.spyOn(console, 'error');

    render(blockbeispiel());

    expect(fehlerSpion).not.toHaveBeenCalled();
  });

  it('behält Vorspann und Inhalt in der Lesereihenfolge', () => {
    render(blockbeispiel());

    const vorspann = screen.getByText('Fehler:');
    expect(vorspann.compareDocumentPosition(screen.getByText('Das geht verloren:'))).toBe(
      Node.DOCUMENT_POSITION_FOLLOWING,
    );
    expect(screen.getByRole('list')).toBeInTheDocument();
  });
});
