/* =====================================================================
   admin-auth.js — gemeinsame Session-Logik fürs interne Team-Login
   (dasselbe Owner-/Rollen-System wie schon fürs frühere Bewerbungs-
   Postfach).

   Session (Token + Rolle/Rechte) liegt in localStorage (Nutzer-Wunsch
   04.08.2026: "den Zugangscode auf der Verwaltungsseite nur einmal am Tag
   eingeben müssen") — localStorage übersteht anders als sessionStorage
   auch das Schließen des Tabs/Browsers, sonst wäre "einmal am Tag" nicht
   möglich. Eigener 24-Stunden-Ablauf hier im Client (siehe SESSION_MAX_AGE_MS)
   zusätzlich zum server-seitigen Session-Timeout (lib/auth.js, ebenfalls
   24 Std) — beide zusammen sorgen dafür, dass wirklich niemand länger als
   einen Tag mit einem alten Code eingeloggt bleiben kann.

   Ursprünglich für postfach.html/zugaenge.html gebaut (Bewerbungs-
   Verwaltung) — die wurden am 01.08.2026 auf Dogis Wunsch entfernt ("nicht
   mehr gebraucht"). Diese Datei selbst ist aber ein reines, seitenneutrales
   Login-Werkzeug (kein Bewerbungscode) und wurde am 04.08.2026 reaktiviert
   für verwaltung.html (Supporter-Abo-Administration) — nutzt exakt
   denselben, weiterhin voll funktionsfähigen Backend-Login
   (POST /auth/login), nur eine neue Seite drumherum.
   ===================================================================== */

const SESSION_KEY = "dogfather_admin_session";
const SESSION_MAX_AGE_MS = 24 * 60 * 60 * 1000;

function getSession() {
  try {
    const session = JSON.parse(localStorage.getItem(SESSION_KEY) || "null");
    if (!session) return null;
    if (!session.loggedInAt || Date.now() - session.loggedInAt > SESSION_MAX_AGE_MS) {
      clearSession(); // älter als 24 Std -> als abgelaufen behandeln, neuer Code nötig
      return null;
    }
    return session;
  } catch {
    return null;
  }
}

function setSession(data) {
  localStorage.setItem(SESSION_KEY, JSON.stringify({ ...data, loggedInAt: Date.now() }));
}

function clearSession() {
  localStorage.removeItem(SESSION_KEY);
}

/** Prüft, ob die aktuelle Session (Owner oder Rolle+Overrides) ein Recht hat. */
function sessionHasPermission(session, key) {
  if (!session) return false;
  if (session.isOwner) return true;
  const overrides = session.overrides || {};
  if (Object.prototype.hasOwnProperty.call(overrides, key)) return !!overrides[key];
  return Array.isArray(session.permissions) && session.permissions.includes(key);
}

async function apiCall(apiBaseUrl, path, body, { auth = true } = {}) {
  const session = getSession();
  const headers = { "Content-Type": "application/json" };
  if (auth && session?.token) headers["Authorization"] = `Bearer ${session.token}`;

  const res = await fetch(`${apiBaseUrl}${path}`, {
    method: "POST",
    headers,
    body: JSON.stringify(body || {}),
  });
  let data;
  try {
    data = await res.json();
  } catch {
    data = { ok: false, error: "Ungültige Antwort vom Server." };
  }
  if (res.status === 401 && auth) {
    clearSession(); // Session ist abgelaufen/ungültig -> zurück zum Login zwingen
  }
  return { httpOk: res.ok, ...data };
}

async function doLogin(apiBaseUrl, code) {
  const res = await apiCall(apiBaseUrl, "/auth/login", { code }, { auth: false });
  if (res.ok) {
    setSession({
      token: res.token,
      isOwner: res.isOwner,
      name: res.name,
      username: res.username,
      roleName: res.roleName,
      permissions: res.permissions || [],
      overrides: res.overrides || {},
    });
  }
  return res;
}

async function doLogout(apiBaseUrl) {
  await apiCall(apiBaseUrl, "/auth/logout", {});
  clearSession();
}

// Für Einbindung ohne Modul-Bundler global verfügbar machen.
if (typeof window !== "undefined") {
  window.AdminAuth = { getSession, setSession, clearSession, sessionHasPermission, apiCall, doLogin, doLogout };
}
