import { useEffect, useState } from 'react';

import type { Erklaerung, Erklaerungen } from '../../../shared/erklaerungen';
import { lernBruecke } from '../lernen/bruecke';

export interface ErklaerungenZustand {
  readonly laedt: boolean;
  /** Erklärung zu einer Frage, oder `null`, wenn es keine gibt. */
  readonly zu: (frageId: string) => Erklaerung | null;
  /** Angaben zur Herkunft, für die Fußnote unter den Erklärungen. */
  readonly meta: Erklaerungen['meta'] | null;
}

/**
 * Einmal geladen, für die ganze Sitzung gültig.
 *
 * Die Erklärungen ändern sich zur Laufzeit nicht – sie kommen als eine Datei
 * mit der Anwendung. Ein Modul-weiter Zwischenspeicher genügt deshalb; ohne
 * ihn würde jede Frage einen neuen IPC-Aufruf auslösen, obwohl die Antwort
 * immer dieselbe ist.
 */
let laufend: Promise<Erklaerungen | null> | null = null;

function holen(): Promise<Erklaerungen | null> {
  laufend ??= (async () => {
    const lesen = lernBruecke()?.erklaerungenLaden;
    if (!lesen) {
      return null;
    }
    try {
      return await lesen();
    } catch {
      /* Erklärungen sind eine Zugabe. Fehlen sie, lernt man ohne sie weiter –
         eine Fehlermeldung an dieser Stelle wäre lauter als der Verlust. */
      return null;
    }
  })();
  return laufend;
}

/** Gegenstück für Tests: leert den Zwischenspeicher. */
export function erklaerungenZwischenspeicherLeeren(): void {
  laufend = null;
}

export function useErklaerungen(): ErklaerungenZustand {
  const [daten, setzeDaten] = useState<Erklaerungen | null>(null);
  const [laedt, setzeLaedt] = useState(true);

  useEffect(() => {
    let abgebrochen = false;

    void holen().then((ergebnis) => {
      if (!abgebrochen) {
        setzeDaten(ergebnis);
        setzeLaedt(false);
      }
    });

    return () => {
      abgebrochen = true;
    };
  }, []);

  return {
    laedt,
    meta: daten?.meta ?? null,
    zu: (frageId: string) => daten?.zuFrage[frageId] ?? null,
  };
}
