import { useEffect, useRef, useState } from 'react';

/**
 * Erkennt, ob nach einem Deploy eine neue Frontend-Version vorliegt, während
 * der Nutzer die App offen hat (der einzige Fall, den Cache-Header NICHT
 * abfangen können – eine laufende SPA holt sich nicht von selbst neuen Code).
 *
 * Prinzip: Die `index.html` wird server-seitig mit `no-store` ausgeliefert,
 * ist also immer frisch. Sie referenziert die Vite-Hash-Assets
 * (`/assets/index-<hash>.js`), deren Namen sich bei jedem Build ändern. Wir
 * holen die index.html periodisch (und beim Zurückkehren zum Tab), extrahieren
 * die Menge der referenzierten Assets als "Signatur" und vergleichen sie mit
 * der beim App-Start geladenen. Ändert sie sich → neue Version deployt.
 */
function extractAssetSignature(html: string): string {
  const matches = html.match(/\/assets\/[A-Za-z0-9._-]+/g) || [];
  return [...new Set(matches)].sort().join('|');
}

async function fetchSignature(): Promise<string | null> {
  try {
    const res = await fetch('/index.html', { cache: 'no-store' });
    if (!res.ok) return null;
    const sig = extractAssetSignature(await res.text());
    return sig || null;
  } catch {
    // Netz-Aussetzer o.ä. – kein Alarm, nächster Intervall versucht es erneut.
    return null;
  }
}

export function useVersionCheck(intervalMs = 5 * 60 * 1000): boolean {
  const [updateAvailable, setUpdateAvailable] = useState(false);
  const baseline = useRef<string | null>(null);

  useEffect(() => {
    // Kein Dev-Guard nötig: der Vite-Dev-Server liefert keine
    // `/assets/<hash>`-Dateien aus → extractAssetSignature ist leer →
    // fetchSignature gibt null zurück → check() bricht ab, kein Alarm.
    // Im Prod-Build greift die Hash-Signatur wie gewünscht.
    let cancelled = false;

    const check = async () => {
      const sig = await fetchSignature();
      if (cancelled || !sig) return;
      if (baseline.current === null) {
        baseline.current = sig; // erster Lauf = Referenzstand
      } else if (sig !== baseline.current) {
        setUpdateAvailable(true);
      }
    };

    check(); // sofort Baseline setzen
    const id = window.setInterval(check, intervalMs);
    const onVisible = () => {
      if (document.visibilityState === 'visible') check();
    };
    document.addEventListener('visibilitychange', onVisible);

    return () => {
      cancelled = true;
      window.clearInterval(id);
      document.removeEventListener('visibilitychange', onVisible);
    };
  }, [intervalMs]);

  return updateAvailable;
}
