/**
 * Die Ruhepause vor einer Live-Region.
 *
 * **Der Anlass.** Die Fragensuche schickte ihre Trefferansage seit jeher erst
 * nach 400 Millisekunden Ruhe an die Live-Region – mit der Begründung, die der
 * Prüfplan zu WCAG 4.1.3 gibt: Eine höfliche Region, die bei jedem
 * Tastenanschlag eine neue Zahl spricht, erzeugt beim Tippen eine Kette
 * einander unterbrechender Ansagen zwischen den Zeichen-Echos.
 *
 * Die Glossaransicht rendert dieselbe Art Auskunft („N von 87 Einträgen“) –
 * und tat das bis 0.22.0 **unmittelbar**. Dieselbe Sache, zwei
 * Verhaltensweisen; die eine davon war die, vor der die eigene Begründung
 * warnt.
 *
 * Geprüft wird hier die Mechanik und daneben, dass beide Ansichten wirklich
 * aus derselben Quelle schöpfen – sonst stünde die gemeinsame Regel zwar da,
 * bliebe aber wirkungslos.
 */

import { readFileSync } from 'node:fs';
import { join } from 'node:path';

import { act, renderHook } from '@testing-library/react';
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';

import { RUHE_MS, useVerzoegerteAnsage } from '../src/renderer/src/hooks/useVerzoegerteAnsage';

/* `process.cwd()` und nicht `import.meta.url`: Diese Datei braucht jsdom für
   den Hook, und dort ist `import.meta.url` eine http-Adresse – derselbe
   Stolperstein, den `tests/sicherheit.test.ts` in seinem Kopf benennt.
   Vitest läuft aus `app/`. */
function quelle(...teile: string[]): string {
  return readFileSync(join(process.cwd(), 'src', 'renderer', 'src', ...teile), 'utf8');
}

beforeEach(() => {
  vi.useFakeTimers();
});

afterEach(() => {
  vi.useRealTimers();
});

describe('Ansage mit Ruhepause', () => {
  it('zeigt den ersten Text sofort', () => {
    /* Beim Aufbau der Ansicht wartet niemand: Die Region muss von der ersten
       Darstellung an im Baum stehen und etwas sagen. */
    const { result } = renderHook(() => useVerzoegerteAnsage('87 Einträge'));

    expect(result.current).toBe('87 Einträge');
  });

  it('schweigt, solange getippt wird', () => {
    const { result, rerender } = renderHook(({ text }) => useVerzoegerteAnsage(text), {
      initialProps: { text: '87 Einträge' },
    });

    for (const zwischenstand of ['12 von 87', '5 von 87', '2 von 87']) {
      rerender({ text: zwischenstand });
      act(() => {
        vi.advanceTimersByTime(RUHE_MS - 100);
      });
      expect(result.current).toBe('87 Einträge');
    }
  });

  it('zieht nach der Ruhepause nach', () => {
    const { result, rerender } = renderHook(({ text }) => useVerzoegerteAnsage(text), {
      initialProps: { text: '87 Einträge' },
    });

    rerender({ text: '2 von 87 Einträgen' });
    act(() => {
      vi.advanceTimersByTime(RUHE_MS + 10);
    });

    expect(result.current).toBe('2 von 87 Einträgen');
  });

  it('überspringt die Zwischenstände, statt sie nachzuholen', () => {
    /* Die Zwischenstände dürfen nicht nachträglich hintereinander gesprochen
       werden – das wäre dieselbe Kette, nur später. */
    const { result, rerender } = renderHook(({ text }) => useVerzoegerteAnsage(text), {
      initialProps: { text: 'a' },
    });

    rerender({ text: 'b' });
    rerender({ text: 'c' });
    rerender({ text: 'd' });
    act(() => {
      vi.advanceTimersByTime(RUHE_MS + 10);
    });

    expect(result.current).toBe('d');
  });
});

describe('Beide Filterfelder schöpfen aus derselben Quelle', () => {
  it('die Fragensuche', () => {
    expect(quelle('hooks', 'useFragensuche.ts')).toContain('useVerzoegerteAnsage');
  });

  it('die Glossaransicht', () => {
    /* Der eigentliche Befund: Hier stand die Zahl unmittelbar am
       `role="status"`-Element. */
    expect(quelle('components', 'lernen', 'Glossaransicht.tsx')).toContain('useVerzoegerteAnsage');
  });

  it('und keine von beiden führt eine eigene Ruhezahl', () => {
    /* Zwei Zahlen an zwei Stellen laufen auseinander, und eine davon wäre
       dann die falsche. */
    for (const datei of [
      quelle('hooks', 'useFragensuche.ts'),
      quelle('components', 'lernen', 'Glossaransicht.tsx'),
    ]) {
      expect(datei).not.toMatch(/RUHE_MS\s*=\s*\d/u);
    }
  });
});
