import { useEffect, useState } from 'react';

import { NORMTEXTE_LEER, type Normtexte } from '../../../shared/normtexte';
import { lernBruecke } from '../lernen/bruecke';

/**
 * Einmal geladen, für die ganze Sitzung gültig – wie Erklärungen und Glossar.
 *
 * Die Datei ist rund 500 KiB groß und ändert sich zur Laufzeit nie. Ein Kanal
 * je Fundstelle wäre bei 2123 Zitaten mehr Verkehr als die ganze Datei, und er
 * brächte dem Lesenden nichts: Wer eine Norm aufschlägt, blättert.
 */
let laufend: Promise<Normtexte | null> | null = null;

function holen(): Promise<Normtexte | null> {
  laufend ??= (async () => {
    const lesen = lernBruecke()?.normtexteLaden;
    if (!lesen) {
      return null;
    }
    try {
      return await lesen();
    } catch {
      /* Der Normtext ist eine Hilfe, keine Voraussetzung. Fehlt er, steht die
         Fundstelle wie bisher als Zitat da – eine Fehlermeldung wäre lauter
         als der Verlust. */
      return null;
    }
  })();
  return laufend;
}

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

export interface NormtexteZustand {
  readonly laedt: boolean;
  /** Nie `null`: Fehlt die Datei, steht hier der leere Bestand. */
  readonly normtexte: Normtexte;
  /** Ob überhaupt Normtexte vorliegen – die Anzeige verspricht sonst nichts. */
  readonly vorhanden: boolean;
}

export function useNormtexte(): NormtexteZustand {
  const [daten, setzeDaten] = useState<Normtexte | null>(null);
  const [laedt, setzeLaedt] = useState(true);

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

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

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

  const normtexte = daten ?? NORMTEXTE_LEER;
  return { laedt, normtexte, vorhanden: Object.keys(normtexte.gesetze).length > 0 };
}
