/**
 * Die dauerhafte Kapitelabwahl im echten Fenster.
 *
 * Was die Vitest-Tests an einer Attrappe und an einer Wegwerf-Datenbank
 * prüfen, läuft hier am echten Katalog mit seinen 575 Fragen und an der
 * echten SQLite-Datei: Der Schalter schreibt wirklich in die Profilzeile,
 * die Zahl im Gesamtfortschritt ändert sich wirklich, und die Umstellung
 * überlebt einen Neuaufbau der Oberfläche wirklich.
 *
 * Der Neuaufbau geschieht per `reload()` – kein Prozessneustart, aber genau
 * der Weg, um den es geht: React baut frisch auf und liest die Profilzeile
 * neu aus der Datenbank.
 */

import { type ElectronApplication, type Page } from '@playwright/test';

import { amStart, appStarten, bauPruefen } from './electron-hilfe';
import { expect, test } from './konsolenwache';

/** Der amtliche Katalog, und was ohne Kapitel IV davon übrig bleibt. */
const GESAMT = 575;
const OHNE_KAPITEL_IV = 486;

let app: ElectronApplication | undefined;
let fenster: Page;

test.beforeAll(async () => {
  bauPruefen();
  ({ app, fenster } = await appStarten());
});

test.afterAll(async () => {
  await app?.close();
});

test.describe.configure({ mode: 'serial' });

function schalter() {
  return fenster.getByRole('checkbox', { name: /Kapitel IV .* mitlernen/u });
}

/**
 * Der Lernumfang, wie ihn die Ampel ausweist.
 *
 * Aus `aria-valuemax` statt aus dem Text: Der Satz der Ampel ändert seine
 * Form je nach Stufe – bei leerem Stand nennt er die Regel statt einer Zahl –,
 * die Obergrenze des Balkens ist dagegen immer der Umfang.
 */
async function umfang(): Promise<number> {
  const wert = await fenster
    .getByRole('progressbar', { name: 'Prüfungsreife insgesamt' })
    .getAttribute('aria-valuemax');
  return Number(wert ?? 0);
}

async function zumStart(): Promise<void> {
  for (let i = 0; i < 4; i++) {
    if (await amStart(fenster)) {
      return;
    }
    const zurueck = fenster.getByRole('button', { name: /^(Zum Start|Sitzung beenden)$/u });
    if ((await zurueck.count()) === 0) {
      return;
    }
    await zurueck.first().click();
    await fenster.waitForTimeout(250);
  }
}

test.describe('Kapitel IV dauerhaft abwählen', () => {
  test('nimmt Kapitel IV aus dem Lernumfang und sagt es an', async () => {
    await zumStart();
    expect(await umfang()).toBe(GESAMT);

    await schalter().click();

    /* Die Ansage steht nur für Bildschirmleser im Dokument, ist aber ein
       echtes Element – sichtbar im Sinne von Playwright ist sie nicht. */
    await expect(fenster.getByText(/Kapitel IV ist für dieses Profil abgewählt/u)).toBeAttached();
    await expect.poll(umfang).toBe(OHNE_KAPITEL_IV);
  });

  test('überlebt den Neuaufbau der Oberfläche', async () => {
    /* Der Punkt der ganzen Übung: „dauerhaft“ heißt in der Profilzeile, nicht
       im Zustand einer React-Komponente. */
    await fenster.reload();
    await fenster.waitForLoadState('domcontentloaded');
    await fenster.waitForSelector('h1', { state: 'visible' });

    await expect(schalter()).not.toBeChecked();
    await expect.poll(umfang).toBe(OHNE_KAPITEL_IV);
  });

  test('lässt die Suche den ganzen Katalog behalten', async () => {
    /* Abgewählt heißt: zählt nicht mit. Nicht: gibt es nicht mehr. Wer im
       Lehrgang nach einer Signalpistole gefragt wird, muss sie nachschlagen
       können. */
    await fenster.getByRole('button', { name: /Fragen durchsuchen/u }).click();
    await fenster.getByRole('heading', { name: 'Fragen durchsuchen', level: 1 }).waitFor();

    await expect(
      fenster.getByText(`Durchsucht wird der Wortlaut aller ${String(GESAMT)} amtlichen Fragen`, {
        exact: false,
      }),
    ).toBeVisible();

    await fenster.getByLabel('Suchbegriff').fill('Seenotsignalmittel');
    await expect(fenster.locator('.treffer__frage').first()).toBeVisible();
  });

  test('vermerkt das Kapitel in der Kapitelwahl, statt es zu verbergen', async () => {
    /* Weder verschwinden noch sperren: Verschwände es, fände niemand den Weg
       zurück zum Schalter; und ein gesperrter Knopf nimmt keinen Fokus – die
       Erklärung daneben würde nie vorgelesen. */
    await zumStart();
    await fenster.getByRole('button', { name: /Kapitel wählen/u }).click();
    await fenster.getByRole('heading', { name: 'Kapitel wählen', level: 1 }).waitFor();

    await expect(fenster.getByText(/Für dieses Profil abgewählt/u)).toBeVisible();
    await expect(fenster.getByRole('button', { name: /Ganzes Kapitel IV üben/u })).toBeEnabled();
  });

  test('holt das Kapitel vollständig zurück', async () => {
    /* Zuletzt, damit die Datei den Zustand hinterlässt, in dem sie ihn
       vorgefunden hat – die übrigen Prüfläufe rechnen mit 575. */
    await zumStart();
    await schalter().click();

    await expect(fenster.getByText(/Kapitel IV wird wieder mitgelernt/u)).toBeAttached();
    await expect.poll(umfang).toBe(GESAMT);
  });
});
