// ─────────────────────────────────────────────────────────────────────────
// Download-Seite mit Anbindung an den serverseitigen /api/releases-Endpunkt.
//
// Vertrag (siehe ../server/ für Beispiel-Implementierungen):
//
//   GET /api/releases  →  200
//   {
//     "version":    "1.4.0",
//     "releasedAt": "2026-04-30T12:00:00Z",
//     "macUrl":     "https://gitlab2.…/uploads/…/Schienengenerator-1.4.0.dmg",
//     "winUrl":     "https://gitlab2.…/uploads/…/Schienengenerator-Setup-1.4.0.exe",
//     "macFile":    "Schienengenerator-1.4.0.dmg",
//     "winFile":    "Schienengenerator-Setup-1.4.0.exe",
//     "macSize":    "84 MB",
//     "winSize":    "76 MB"
//   }
//
// Der GITLAB_TOKEN bleibt serverseitig — das Frontend kennt ihn nicht.
// ─────────────────────────────────────────────────────────────────────────

const RELEASES_ENDPOINT = "/api/releases";

// Fallback-Release-Daten für lokale Entwicklung ohne Backend.
const FALLBACK_RELEASE = {
  version: "1.4.0",
  releasedAt: "2026-04-30",
  macUrl: "#",
  winUrl: "#",
  macFile: "Schienengenerator-1.4.0.dmg",
  winFile: "Schienengenerator-Setup-1.4.0.exe",
  macSize: "—",
  winSize: "—",
};

function formatReleaseDate(value) {
  if (!value) return "";
  const d = new Date(value);
  if (isNaN(d)) return value;
  return d.toLocaleDateString("de-DE", {
    day: "2-digit",
    month: "2-digit",
    year: "numeric",
  });
}

function AppleGlyph() {
  return (
    <svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
      <path d="M17.05 12.04c-.03-2.71 2.21-4.02 2.31-4.08-1.26-1.84-3.22-2.09-3.92-2.12-1.67-.17-3.26.98-4.11.98-.85 0-2.16-.96-3.55-.93-1.83.03-3.51 1.06-4.45 2.7-1.9 3.29-.49 8.16 1.36 10.83.9 1.31 1.97 2.78 3.37 2.73 1.35-.05 1.86-.87 3.49-.87 1.63 0 2.09.87 3.51.84 1.45-.02 2.37-1.33 3.26-2.65 1.03-1.52 1.45-2.99 1.47-3.07-.03-.01-2.82-1.08-2.84-4.36zM14.5 4.07c.74-.9 1.24-2.15 1.1-3.4-1.07.05-2.36.71-3.13 1.6-.69.79-1.29 2.06-1.13 3.28 1.19.09 2.41-.6 3.16-1.48z" />
    </svg>
  );
}
function WindowsGlyph() {
  return (
    <svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
      <path d="M3 5.4 11.06 4.3v7.7H3V5.4Zm0 13.2v-6.6h8.06v7.7L3 18.6Zm9.94-14.43L21 3v9H12.94V4.17Zm0 9.46H21V21l-8.06-1.17v-6.2Z" />
    </svg>
  );
}

function DownloadCard({ os, version, file, size, glyph, href, disabled }) {
  const isMac = os === "macOS";
  const ext = isMac ? ".dmg" : ".exe";
  const description = isMac
    ? "Universal-Build für Apple Silicon und Intel. Geöffnet per Rechtsklick → Öffnen beim ersten Mal."
    : "Installer mit Auto-Update. Läuft auf Windows 10 und 11 ab Version 21H2.";

  return (
    <a
      className="dl-card"
      href={disabled ? undefined : href}
      aria-label={`Download für ${os}`}
      aria-disabled={disabled || undefined}
      style={disabled ? { opacity: 0.6, pointerEvents: "none" } : undefined}
    >
      <div className="os-icon">{glyph}</div>
      <div>
        <h3>{os}</h3>
        <p style={{ marginTop: 6 }}>{description}</p>
      </div>
      <Button
        variant="primary"
        icon="download"
        size="lg"
        href={disabled ? undefined : href}
      >
        Download für {os} ({ext})
      </Button>
      <div className="meta">
        <span>
          <Icon name="package_2" /> {file || "—"}
        </span>
        <span>
          <Icon name="hard_drive" /> {size || "—"}
        </span>
        <span>
          <Icon name="schedule" /> v{version}
        </span>
      </div>
    </a>
  );
}

function DownloadPage() {
  const [release, setRelease] = React.useState(FALLBACK_RELEASE);
  const [status, setStatus] = React.useState("idle"); // idle | loading | ready | error
  const [error, setError] = React.useState(null);

  const loadReleases = React.useCallback(async (signal) => {
    setStatus("loading");
    setError(null);
    try {
      const res = await fetch(RELEASES_ENDPOINT, {
        signal,
        headers: { Accept: "application/json" },
      });
      if (!res.ok) throw new Error(`HTTP ${res.status}`);
      const data = await res.json();
      // Defensiv mergen, damit fehlende Felder den Fallback nicht löschen.
      setRelease((prev) => ({ ...prev, ...data }));
      setStatus("ready");
    } catch (err) {
      if (err.name === "AbortError") return;
      setError(err.message || String(err));
      setStatus("error");
    }
  }, []);

  React.useEffect(() => {
    const ctrl = new AbortController();
    loadReleases(ctrl.signal);
    return () => ctrl.abort();
  }, [loadReleases]);

  const macHref =
    release.macUrl && release.macUrl !== "#" ? release.macUrl : null;
  const winHref =
    release.winUrl && release.winUrl !== "#" ? release.winUrl : null;

  return (
    <main>
      <section className="dl-hero">
        <div className="container">
          <div className="version-pill">
            {status === "loading" ? (
              <>
                <span
                  className="dot"
                  style={{ background: "var(--fg-subtle)" }}
                />
                Releases werden geladen …
              </>
            ) : status === "error" ? (
              <>
                <span className="dot" style={{ background: "#b03a2e" }} />
                Aktuelle Version: <code>vX.X.X</code>
              </>
            ) : (
              <>
                <span className="dot" />
                Aktuelle Version <code>v{release.version}</code>
                {release.releasedAt ? (
                  <> · {formatReleaseDate(release.releasedAt)}</>
                ) : null}
              </>
            )}
          </div>
          <h1>Download Schienengenerator</h1>
          <p className="lede">
            Lade die App für dein Betriebssystem herunter. Schienengenerator
            läuft vollständig lokal — keine Cloud, keine Anmeldung.
          </p>
        </div>
      </section>

      <section className="container" style={{ paddingBottom: 80 }}>
        {status === "error" && (
          <div className="dl-error" role="alert">
            <Icon name="error" />
            <div>
              <b>Die aktuellen Releases sind nicht erreichbar.</b>
              <p>
                Bitte versuche es in einem Moment erneut. Die Download-Buttons
                sind solange deaktiviert.
              </p>
            </div>
            <button
              type="button"
              className="btn"
              onClick={() => loadReleases()}
            >
              <Icon name="refresh" /> Erneut versuchen
            </button>
          </div>
        )}

        <div className="dl-cards">
          <DownloadCard
            os="macOS"
            version={release.version}
            file={release.macFile}
            size={release.macSize}
            glyph={<AppleGlyph />}
            href={macHref || "#"}
            disabled={!macHref}
          />
          <DownloadCard
            os="Windows"
            version={release.version}
            file={release.winFile}
            size={release.winSize}
            glyph={<WindowsGlyph />}
            href={winHref || "#"}
            disabled={!winHref}
          />
        </div>

        <div className="sysreq">
          <h4>Systemanforderungen</h4>
          <div className="sysreq-grid">
            <div>
              <b>macOS</b> — 12 Monterey oder neuer · Apple Silicon oder Intel ·
              250 MB freier Speicher
            </div>
            <div>
              <b>Windows</b> — 10 (21H2) oder 11 · 64-Bit · 250 MB freier
              Speicher
            </div>
            <div>
              <b>Excel</b> — Eingabedateien als .xlsx (Excel 2016+, LibreOffice
              ≥ 7)
            </div>
            <div>
              <b>Optional</b> — WinSchool für XML-Direktimport
            </div>
          </div>
        </div>
      </section>
    </main>
  );
}

window.DownloadPage = DownloadPage;
