/**
 * Die Anzeigegröße des Fensters.
 *
 * **Warum das hier liegt und nicht im Renderer.** Der Zoom gehört zum
 * Fenster, nicht zum Dokument: `webContents.setZoomFactor` skaliert alles,
 * was darin dargestellt wird – Text, Bedienelemente und die siebzehn
 * Prüfzeichen, bei denen das Bild die Antwort ist. Eine reine
 * CSS-Schriftvergrößerung ließe die Zeichen unberührt, und ausgerechnet wer
 * größere Schrift braucht, braucht sie erst recht.
 *
 * Außerdem muss die Größe schon anliegen, bevor der erste Bildpunkt
 * gezeichnet wird – sonst blitzt die Anwendung beim Start in der falschen
 * Größe auf.
 *
 * **Ein Weg für beide Bedienungen.** Die Größe lässt sich über das
 * Anwendungsmenü (mit den gewohnten Tastenkürzeln) und über Schaltflächen in
 * den Einstellungen ändern. Beides läuft durch {@link anzeigegroesseSetzen} –
 * andernfalls zeigte die Einstellung eine Zahl an, die das Menü längst
 * überholt hat.
 */

import { BrowserWindow, webContents, type WebContents } from 'electron';

import { anzeigegroesseBereinigen, groesser, kleiner, zoomfaktor } from '../shared/ansicht';
import { KANAL_ANZEIGEGROESSE_GEAENDERT } from '../shared/ipc';
import { einstellungenLesen, einstellungenSchreiben } from './einstellungen';

/** Die zuletzt gesetzte Größe, damit Menü und Einstellungen dieselbe kennen. */
let aktuell: number | null = null;

/** Die gespeicherte Größe; beim ersten Aufruf aus den Einstellungen gelesen. */
export function anzeigegroesse(): number {
  aktuell ??= anzeigegroesseBereinigen(einstellungenLesen().anzeigegroesse);
  return aktuell;
}

/**
 * Setzt die Größe, sichert sie und meldet sie allen Fenstern.
 *
 * Das Sichern darf scheitern, ohne dass die Umstellung verloren geht: Wer
 * gerade die Schrift vergrößert, weil er sonst nichts lesen kann, soll nicht
 * wegen eines vollen Datenträgers wieder vor kleiner Schrift sitzen. Der
 * Fehlschlag landet in der Konsole, nicht als Ausnahme beim Aufrufer.
 */
export function anzeigegroesseSetzen(prozentRoh: unknown): number {
  const prozent = anzeigegroesseBereinigen(prozentRoh);
  aktuell = prozent;

  for (const inhalt of webContents.getAllWebContents()) {
    anwendenAuf(inhalt);
  }

  try {
    einstellungenSchreiben({ anzeigegroesse: prozent });
  } catch (fehler: unknown) {
    console.warn('[anzeige] Größe konnte nicht gesichert werden:', fehler);
  }

  for (const fenster of BrowserWindow.getAllWindows()) {
    fenster.webContents.send(KANAL_ANZEIGEGROESSE_GEAENDERT, prozent);
  }

  return prozent;
}

/**
 * Legt die gespeicherte Größe auf ein Fenster.
 *
 * Muss für jedes neue Fenster aufgerufen werden: Der Zoomfaktor hängt an den
 * `webContents` und wird nicht vererbt.
 */
export function anwendenAuf(inhalt: WebContents): void {
  inhalt.setZoomFactor(zoomfaktor(anzeigegroesse()));
}

/** Eine Stufe größer – für das Menü. */
export function anzeigeVergroessern(): number {
  return anzeigegroesseSetzen(groesser(anzeigegroesse()));
}

/** Eine Stufe kleiner – für das Menü. */
export function anzeigeVerkleinern(): number {
  return anzeigegroesseSetzen(kleiner(anzeigegroesse()));
}

/** Zurück auf 100 Prozent. */
export function anzeigeZuruecksetzen(): number {
  return anzeigegroesseSetzen(100);
}
