import { useId } from 'react';

import {
  erklaerungVorlesetext,
  fundstelleText,
  type Erklaerung,
} from '../../../../shared/erklaerungen';
import type { Sprachausgabe } from '../../hooks/useVorlesen';
import { Normstelle } from './Normstelle';
import { Vorlesetaste } from './Vorlesetaste';

export interface ErklaerungstafelProps {
  readonly erklaerung: Erklaerung;
  /**
   * Überschriftenebene der Tafel.
   *
   * Im Lernmodus steht darüber die Rückmeldung (h2), also 3. In der
   * Prüfungsauswertung liegt sie tiefer verschachtelt, dort 4.
   */
  readonly ebene?: 3 | 4;
  /**
   * Als aufklappbarer Block darstellen.
   *
   * Nachgemessen ist die Tafel 1156 Pixel hoch – ein voller Bildschirm. Steht
   * sie immer offen zwischen Antwort und „Nächste Frage“, muss man nach jeder
   * einzelnen Frage scrollen, um weiterzukommen.
   */
  readonly einklappbar?: boolean;
  /**
   * Beim Aufbau geöffnet?
   *
   * Die Regel im Lernmodus: bei falscher Antwort offen – dann braucht man
   * die Begründung –, bei richtiger zu. Wer sie trotzdem lesen will, klappt
   * sie mit einem Griff auf.
   */
  readonly offen?: boolean;
  /**
   * Sprachausgabe für „Erklärung vorlesen“.
   *
   * Ohne Angabe entfällt die Taste. Die Tafel führt bewusst **keine eigene**
   * Instanz: Zwei Sprachausgaben auf demselben Bildschirm brächen einander
   * gegenseitig ab, und der jeweils andere Knopf zeigte weiterhin „läuft“,
   * obwohl er längst überholt wäre. Der Aufrufer reicht die durch, die er
   * ohnehin hat.
   */
  readonly stimme?: Sprachausgabe;
}

/**
 * Die Begründung zur richtigen Antwort.
 *
 * Der amtliche Katalog nennt die richtige Antwort, aber nie den Grund. Genau
 * das steht hier – und zwar mit Fundstelle, damit sich jede Aussage
 * nachschlagen lässt.
 *
 * ## Kennzeichnung
 *
 * Die Tafel ist deutlich als **eigener Zusatz** ausgewiesen. Der amtliche
 * Fragenkatalog darf nicht verändert wiedergegeben werden (§ 62 UrhG); wer
 * hier liest, muss auf einen Blick erkennen, was vom Bundesverwaltungsamt
 * stammt und was nicht.
 *
 * ## Fundstellen
 *
 * Sichtbar steht die übliche juristische Kurzform („§ 12 Abs. 1 Nr. 3
 * Buchst. b WaffG“). Für Bildschirmleser trägt jede Fundstelle zusätzlich
 * einen ausgeschriebenen Namen – „Paragraf 12 Absatz 1 …“ –, weil die
 * Abkürzungen sonst buchstabiert oder falsch betont vorgelesen werden.
 */
export function Erklaerungstafel({
  erklaerung,
  ebene = 4,
  einklappbar = false,
  offen = false,
  stimme,
}: ErklaerungstafelProps): React.JSX.Element {
  const titelId = useId();
  const fundstellenId = useId();

  const titel =
    ebene === 3 ? (
      <h3 className="erklaerung__titel" id={titelId}>
        Warum das so ist
      </h3>
    ) : (
      <h4 className="erklaerung__titel" id={titelId}>
        Warum das so ist
      </h4>
    );

  const inhalt = (
    <>
      <p className="erklaerung__kurz">{erklaerung.kurz}</p>
      <p className="erklaerung__text">{erklaerung.text}</p>

      {erklaerung.merksatz === undefined ? null : (
        <p className="erklaerung__merksatz">
          <span className="erklaerung__merkmarke">Merksatz</span> {erklaerung.merksatz}
        </p>
      )}

      {erklaerung.fundstellen.length > 0 ? (
        <div className="erklaerung__fundstellen">
          <p className="erklaerung__untertitel" id={fundstellenId}>
            Im Gesetz nachlesen
          </p>
          <ul className="erklaerung__liste" aria-labelledby={fundstellenId}>
            {erklaerung.fundstellen.map((fundstelle) => (
              /* Seit 0.22.0 aufklappbar: Der Normtext liegt bei, und die
                 Aufforderung „im Gesetz nachlesen“ lässt sich damit erfüllen,
                 ohne die Anwendung zu verlassen. Sichtbar die Kurzform,
                 vorgelesen die Langform – das besorgt `Normstelle`. */
              <li key={fundstelleText(fundstelle)}>
                <Normstelle fundstelle={fundstelle} />
              </li>
            ))}
          </ul>
        </div>
      ) : null}

      {erklaerung.ohneFundstelleGrund === undefined ? null : (
        <p className="erklaerung__ohnefundstelle">{erklaerung.ohneFundstelleGrund}</p>
      )}

      <p className="erklaerung__herkunft">
        Diese Erklärung ist eine Ergänzung dieser Software und nicht Teil des amtlichen
        Fragenkatalogs.
      </p>

      {/*
        Eine eigene Taste, nicht die der Sitzung.

        Die Vorlesetaste der Lernsitzung liest den langen Text bewusst nicht
        mit – gesprochen dauert er über eine Minute, und die nächste Frage
        wartet (siehe die Begründung an `vorlesenErklaerungBeiFehler` in
        `shared/ipc.ts`). Genau deshalb steht sie hier: Wer die Minute gerade
        übrig hat, drückt hier; wer weiter will, drückt nicht.

        Am Fuß der Tafel und nicht an ihrem Kopf: Wer sie liest, ist dann
        unten – und wer sie hören will, findet sie da, wo der Text aufhört.
      */}
      {stimme?.moeglich === true ? (
        <div className="erklaerung__stimme">
          <Vorlesetaste
            laeuft={stimme.laeuft}
            angehalten={stimme.angehalten}
            gegenstand="Erklärung"
            onSprich={() => {
              stimme.sprich(erklaerungVorlesetext(erklaerung));
            }}
            onAbbrechen={stimme.abbrechen}
            onAnhalten={stimme.anhalten}
            onFortsetzen={stimme.fortsetzen}
          />
        </div>
      ) : null}
    </>
  );

  /* `<details>` statt eines nachgebauten Aufklappers: Es bringt Tastatur,
     Screenreader-Ansage und die Browsersuche in zugeklapptem Inhalt von
     Haus aus mit. Die Überschrift steht im `<summary>`, damit sie auch
     zugeklappt in der Überschriftenliste auftaucht. */
  if (einklappbar) {
    return (
      <details className="erklaerung erklaerung--klappbar" open={offen}>
        <summary className="erklaerung__schalter">{titel}</summary>
        {inhalt}
      </details>
    );
  }

  return (
    <section className="erklaerung" aria-labelledby={titelId}>
      {titel}
      {inhalt}
    </section>
  );
}
