let deferredInstallPrompt = null;

function isStandalone() {
  return window.matchMedia("(display-mode: standalone)").matches || window.navigator.standalone === true;
}

export function wirePwaInstall({ sectionId = "pwaInstallSection", buttonId = "installPwa" } = {}) {
  const section = document.getElementById(sectionId);
  const button = document.getElementById(buttonId);
  if (!section || !button) return;

  const hide = () => { section.hidden = true; };
  if (isStandalone()) { hide(); return; }
  hide();

  window.addEventListener("beforeinstallprompt", (e) => {
    e.preventDefault();
    deferredInstallPrompt = e;
    section.hidden = false;
  });

  window.addEventListener("appinstalled", () => {
    deferredInstallPrompt = null;
    hide();
  });

  button.addEventListener("click", async () => {
    if (!deferredInstallPrompt) return;
    deferredInstallPrompt.prompt();
    await deferredInstallPrompt.userChoice;
    deferredInstallPrompt = null;
    hide();
  });
}

export async function registerPwa() {
  if (!("serviceWorker" in navigator)) return;
  try {
    const reg = await navigator.serviceWorker.register("/sw.js");
    if ("sync" in ServiceWorkerRegistration.prototype) {
      navigator.serviceWorker.ready.then((readyReg) => {
        readyReg.sync?.register("sync-logs").catch(() => {});
      });
    }
    return reg;
  } catch (e) {
    console.error("SW registration failed:", e);
  }
}

export async function subscribePush(vapidPublicKey) {
  if (!("PushManager" in window)) throw new Error("Push nicht unterstützt");
  const reg = await navigator.serviceWorker.ready;
  let sub = await reg.pushManager.getSubscription();
  if (!sub) {
    sub = await reg.pushManager.subscribe({
      userVisibleOnly: true,
      applicationServerKey: urlBase64ToUint8Array(vapidPublicKey),
    });
  }
  return sub.toJSON();
}

function urlBase64ToUint8Array(base64String) {
  const padding = "=".repeat((4 - (base64String.length % 4)) % 4);
  const base64 = (base64String + padding).replace(/-/g, "+").replace(/_/g, "/");
  const raw = atob(base64);
  return Uint8Array.from([...raw].map((c) => c.charCodeAt(0)));
}
