import { useId } from 'react';

import { KONTAKT, KONTAKT_ANLIEGEN } from '../../../../shared/kontakt';
import {
  EUPL_HINWEIS,
  EUPL_KENNUNG,
  KATALOG_HINWEIS,
  type Lizenzangaben,
} from '../../../../shared/lizenzen';
import { UNTERSTUETZUNG_URL, unterstuetzungsziel } from '../../../../shared/unterstuetzung';
import type { KatalogIndex } from '../../hooks/useKatalog';
import { useDatenschutz } from '../../hooks/useDatenschutz';
import { useLizenzen } from '../../hooks/useLizenzen';
import { datumText } from '../../pruefung/zeit';
import { Hinweis } from '../lernen/Hinweis';
import { Datenschutztext } from './Datenschutztext';
import { Lizenzblock } from './Lizenzblock';
import { Unterstuetzung } from './Unterstuetzung';

export interface UeberSoftwareProps {
  readonly einstiegRef: React.RefObject<HTMLHeadingElement | null>;
  readonly katalogIndex: KatalogIndex | null;
  readonly onZurueck: () => void;
}

/**
 * Ersatzangaben, wenn der Kanal `lizenzen:lesen` nicht antwortet.
 *
 * Die Pflichtangaben zur eigenen Lizenz und zum amtlichen Fragenkatalog stehen
 * als Festtexte im Vertrag. Sie dürfen nicht daran hängen, ob ein IPC-Kanal
 * gerade erreichbar ist – ohne sie wäre die Auslieferung nicht zulässig.
 */
const ERSATZANGABEN: Lizenzangaben = Object.freeze({
  eigene: Object.freeze({
    kennung: EUPL_KENNUNG,
    name: 'European Union Public Licence, Version 1.2',
    hinweis: EUPL_HINWEIS,
    text: null,
  }),
  katalog: Object.freeze({
    quellenangabe: 'Amtlicher Fragenkatalog für die Sachkundeprüfung des Bundesverwaltungsamtes.',
    quelleUrl: 'https://www.bva.bund.de/',
    hinweis: KATALOG_HINWEIS,
  }),
  dritte: Object.freeze([]),
});

/**
 * Bereich „Über diese Software“.
 *
 * Keine Höflichkeit, sondern Pflicht: MIT, BSD und Apache verlangen sämtlich,
 * dass Lizenztext und Urheberrechtsvermerk mitgeliefert werden. Die eigene
 * Software steht unter der EUPL 1.2; der amtliche Fragenkatalog bekommt
 * bewusst keine Lizenz und wird nur mit Quellenangabe wiedergegeben.
 */
export function UeberSoftware({
  einstiegRef,
  katalogIndex,
  onZurueck,
}: UeberSoftwareProps): React.JSX.Element {
  const zustand = useLizenzen();
  const datenschutz = useDatenschutz();
  const titelId = useId();
  const kontaktTitelId = useId();
  const dritteTitelId = useId();

  const angaben = zustand.art === 'fertig' ? zustand.angaben : ERSATZANGABEN;
  const meta = katalogIndex?.katalog.meta ?? null;

  return (
    <section className="ueber abschnitt" aria-labelledby={titelId}>
      <h1 id={titelId} ref={einstiegRef} tabIndex={-1}>
        Über diese Software
      </h1>

      <p>
        Diese Anwendung läuft vollständig offline auf Ihrem Rechner. Sie überträgt keine Daten,
        führt keine Telemetrie und braucht kein Konto.
      </p>

      {zustand.art === 'laedt' ? <p>Die Lizenzangaben werden gelesen …</p> : null}
      {zustand.art === 'fehler' ? (
        <Hinweis art="hinweis">
          {zustand.meldung} Die Pflichtangaben unten stammen deshalb aus der Anwendung selbst; die
          Volltexte der Fremdkomponenten fehlen in dieser Ansicht.
        </Hinweis>
      ) : null}

      {/* Bewusst der erste Block, vor allen Lizenzangaben. Wer hier landet,
          weil er nicht weiterkommt, soll den Rückmeldeweg finden, ohne vier
          Rechtsblöcke zu durchscrollen. Die Lizenzhinweise sind Pflicht, aber
          sie sind nicht dringend – dieser Block ist es. */}
      <div className="ueber__block">
        <h2 id={kontaktTitelId}>Rückmeldung und Kontakt</h2>
        <p>
          Wenn Sie in dieser Anwendung auf eine Barriere stoßen oder einen Fehler finden, melden Sie
          es bitte. Sie bekommen eine Antwort {KONTAKT.frist}.
        </p>

        <ul aria-labelledby={kontaktTitelId}>
          {KONTAKT_ANLIEGEN.map((anliegen) => (
            <li key={anliegen}>{anliegen}</li>
          ))}
        </ul>

        {/* Nur Name und E-Mail. Telefon und Ort sind bewusst entfernt – die
            Begründung steht im Kopf von `shared/kontakt.ts`: Prüfschritt 9.2.3
            verlangt einen Kanal, der nicht ausschließlich Telefon ist, und
            E-Mail allein erfüllt ihn. */}
        <dl className="ueber__angaben">
          <dt>Verantwortlich</dt>
          <dd>{KONTAKT.name}</dd>

          <dt>E-Mail</dt>
          <dd>{KONTAKT.epost}</dd>
        </dl>

        <p className="ueber__fussnote">
          Die Angaben stehen als Text da und sind nicht verknüpft: Die Anwendung öffnet von sich aus
          keine Verbindung ins Netz und startet auch kein E-Mail-Programm. Kopieren Sie die Adresse
          in das Programm Ihrer Wahl.
        </p>
      </div>

      <div className="ueber__block">
        <h2>Datenschutz</h2>
        <p>
          Diese Anwendung arbeitet vollständig offline. Alles, was beim Lernen entsteht, bleibt auf
          diesem Rechner; es wird nichts übertragen und nichts an Dritte weitergegeben. Die
          vollständige Erklärung steht hier – sie ist mitgeliefert und braucht keine Verbindung.
        </p>
        {datenschutz.art === 'fertig' && datenschutz.angaben.erklaerung !== null ? (
          <Datenschutztext erklaerung={datenschutz.angaben.erklaerung} />
        ) : (
          /* Kein leerer Bereich: Wer hier nichts findet, hielte die Erklärung für
             nicht vorhanden statt für nicht ladbar – beim Datenschutz der
             falscheste aller Eindrücke. */
          <p className="hinweis">
            {datenschutz.art === 'fehler'
              ? datenschutz.meldung
              : ((datenschutz.art === 'fertig' ? datenschutz.angaben.warnung : null) ??
                'Die Datenschutzerklärung wird geladen.')}
          </p>
        )}
      </div>

      <div className="ueber__block">
        <h2>Lizenz dieser Anwendung</h2>
        <p className="ueber__kennung">
          {angaben.eigene.name} ({angaben.eigene.kennung})
        </p>
        <p>{angaben.eigene.hinweis}</p>
        <Lizenzblock
          schalter="Volltext der Lizenz anzeigen"
          bereich="Volltext der Lizenz"
          text={angaben.eigene.text}
        />
      </div>

      <div className="ueber__block">
        <h2>Rechtslage des Fragenkatalogs</h2>
        <p>{angaben.katalog.hinweis}</p>
        <dl className="ueber__angaben">
          {/* Lädt der Katalog nicht, liefert der Kern leere Zeichenketten.
              Eine leere Definitionszeile unter „Quellenangabe" wäre die
              schlechteste Antwort darauf – die Pflichtangabe steht als
              Festtext ohnehin bereit. */}
          <dt>Quellenangabe</dt>
          <dd>{angaben.katalog.quellenangabe.trim() || ERSATZANGABEN.katalog.quellenangabe}</dd>

          <dt>Quelle</dt>
          <dd>
            <code className="ueber__url">
              {angaben.katalog.quelleUrl.trim() || ERSATZANGABEN.katalog.quelleUrl}
            </code>
          </dd>

          <dt>Katalogstand</dt>
          <dd>{meta === null ? 'Der Fragenkatalog ist nicht geladen.' : datumText(meta.stand)}</dd>

          {meta === null ? null : (
            <>
              <dt>Herausgeber</dt>
              <dd>{meta.herausgeber}</dd>

              <dt>Fragen im Katalog</dt>
              <dd>{meta.fragen_gesamt}</dd>
            </>
          )}
        </dl>
        <p className="ueber__fussnote">
          Die Adresse steht bewusst als Text da: Die Anwendung öffnet von sich aus keine Verbindung
          ins Netz.
        </p>
      </div>

      <div className="ueber__block">
        <h2>Verwendete Verfahren</h2>
        <p>
          Die Wiedervorlage folgt dem Free Spaced Repetition Scheduler in der Fassung FSRS-6. Das
          Verfahren schätzt für jede Frage, wie lange Sie sie noch abrufen können, und legt den
          nächsten Termin so, dass Sie sie kurz vor dem Vergessen wiedersehen. FSRS ist ein
          offengelegtes Verfahren und an keine Lizenz gebunden; die Umsetzung in dieser Anwendung
          ist eigener Quelltext und gegen die Referenzimplementierung des Projekts
          open-spaced-repetition abgeglichen.
        </p>
        <p>
          Wie eng die Wiederholungen liegen, richtet sich zusätzlich nach Ihrem Prüfungstermin.
          Diese Anpassung stammt von dieser Anwendung und ist nicht Teil von FSRS.
        </p>
      </div>

      <div className="ueber__block">
        <h2 id={dritteTitelId}>Mitgelieferte Fremdkomponenten</h2>
        {angaben.dritte.length === 0 ? (
          <p>Zu dieser Ansicht liegen zurzeit keine Angaben über Fremdkomponenten vor.</p>
        ) : (
          <ul className="ueber__dritte" aria-labelledby={dritteTitelId}>
            {angaben.dritte.map((komponente) => (
              <li className="ueber__komponente" key={komponente.name}>
                <p className="ueber__komponentenname">
                  {komponente.name}
                  {komponente.version === null ? '' : ` ${komponente.version}`} –{' '}
                  {komponente.lizenz}
                </p>
                {komponente.hinweis === undefined ? null : (
                  <p className="ueber__komponentenhinweis">{komponente.hinweis}</p>
                )}
                {komponente.url === null ? null : (
                  <p>
                    <code className="ueber__url">{komponente.url}</code>
                  </p>
                )}
                <Lizenzblock
                  hinweisVorhanden={komponente.hinweis !== undefined}
                  schalter={`Lizenztext von ${komponente.name} anzeigen`}
                  bereich={`Lizenztext von ${komponente.name}`}
                  text={komponente.lizenztext}
                />
              </li>
            ))}
          </ul>
        )}
      </div>

      {/* Zuletzt und nicht zuerst. Oben in dieser Ansicht steht der
          Rückmeldeweg – wer hier landet, weil er auf eine Barriere gestoßen
          ist, darf nicht zuerst um Geld gebeten werden. Die Pflichtangaben
          gehen ebenfalls vor: Lizenzhinweise sind geschuldet, diese Bitte ist
          es nicht. Ohne eingetragene Adresse rendert der Block nichts – die
          Begründung im Einzelnen steht in `shared/unterstuetzung.ts`. */}
      <Unterstuetzung ziel={unterstuetzungsziel(UNTERSTUETZUNG_URL)} />

      <button type="button" className="knopf knopf--leise" onClick={onZurueck}>
        Zum Start
      </button>
    </section>
  );
}
