import { useId } from 'react';

export interface Sprungziel {
  /** `id` der Überschrift, zu der gesprungen wird. */
  readonly id: string;
  /** Beschriftung des Verweises. Sie muss das Ziel vorhersagen. */
  readonly text: string;
}

export interface SprungmenueProps {
  readonly ziele: readonly Sprungziel[];
  /** Steht sichtbar vor der Leiste und benennt zugleich die Landmarke. */
  readonly beschriftung: string;
}

/**
 * Ein Inhaltsverzeichnis innerhalb einer langen Ansicht.
 *
 * **Warum es das braucht.** Der Startbildschirm ist bei 1265 Pixel Breite
 * **8530** Pixel hoch – gemessen am 30.08.2026 an
 * `docs/bildschirmfotos/01-startbildschirm-hell.png`, im Farbschema „Hoher
 * Kontrast“ 8602. Zum Stand 0.20.0 waren es 8078, vor dem Zusammenlegen der
 * drei Druckkarten 9032. Neun Bildschirme bleiben es auch danach:
 * Wer mit einem Bildschirmleser arbeitet, hat die Überschriftenliste und kommt
 * damit überall hin. Wer sieht und mit Maus oder Tastatur bedient, hatte bisher
 * nur das Rollen: kein Verzeichnis, keine Anker, kein Sprung.
 *
 * **Warum Verweise und keine Schaltflächen.** Anders als die A-bis-Z-Leiste des
 * Glossars (`Glossaransicht.tsx`), deren Buchstaben nirgendwo sonst vorkommen,
 * trägt dieses Verzeichnis dieselben Namen wie die Schaltflächen der Karten –
 * „Fragen durchsuchen“ steht in der Leiste und auf dem Knopf, und das ist seit
 * der Vereinheitlichung der Benennung genau so gewollt. Als Schaltfläche wäre
 * jeder Eintrag ein zweiter Knopf desselben Namens; ein Verweis ist eine
 * Sprungmarke und trägt die Rolle `link`. Beides zusammen ist auch die
 * ehrlichere Auskunft: Der Eintrag führt an eine Stelle dieser Seite, er tut
 * nichts.
 *
 * **Warum der Klick trotzdem abgefangen wird.** Ein `href="#…"` allein schriebe
 * die Adresse fort und legte je Sprung einen Eintrag in die Fensterhistorie –
 * in einer Anwendung ohne Adresszeile ist das kein Gewinn, sondern ein zweiter
 * Zustand neben dem der Oberfläche. Das `href` bleibt trotzdem stehen: Es
 * benennt das Ziel, macht den Eintrag über die Tastatur bedienbar und gibt ihm
 * die richtige Rolle.
 *
 * **Warum der Fokus mitwandert.** Reines Rollen wäre für Tastatur und
 * Bildschirmleser wirkungslos – der nächste Tabulatorsprung begänne wieder
 * ganz oben (WCAG 2.4.3). Die Zielüberschriften tragen deshalb `tabIndex={-1}`
 * und nehmen den Fokus entgegen, ohne selbst ein Tabulatorhalt zu werden.
 */
export function Sprungmenue({ ziele, beschriftung }: SprungmenueProps): React.JSX.Element {
  const titelId = useId();

  const springen = (id: string): void => {
    const ziel = document.getElementById(id);
    if (ziel === null) {
      return;
    }
    /* Erst rollen, dann fokussieren – wie im Glossar: `focus()` allein schöbe
       die Überschrift nur eben in den Sichtbereich, ans untere Fensterende.
       Kein `behavior: 'smooth'`: Ohne Angabe gilt das CSS, und dort schaltet
       `prefers-reduced-motion` jedes Rollen auf sofort (tokens.css). jsdom
       kennt die Methode nicht, daher der Typtest. */
    if (typeof ziel.scrollIntoView === 'function') {
      ziel.scrollIntoView({ block: 'start' });
    }
    ziel.focus({ preventScroll: true });
  };

  return (
    <nav className="sprungmenue" aria-labelledby={titelId}>
      {/* Ein sichtbarer Text, der zugleich die Landmarke benennt: Ein
          zusätzliches `aria-label` sagte dasselbe ein zweites Mal, und beide
          liefen mit der Zeit auseinander. */}
      <span className="sprungmenue__titel" id={titelId}>
        {beschriftung}
      </span>

      <div className="sprungmenue__liste">
        {ziele.map((ziel) => (
          <a
            key={ziel.id}
            className="knopf sprungmenue__ziel"
            href={`#${ziel.id}`}
            onClick={(ereignis) => {
              ereignis.preventDefault();
              springen(ziel.id);
            }}
          >
            {ziel.text}
          </a>
        ))}
      </div>
    </nav>
  );
}
