// Push-varsler til telefonens OS (Web Push/VAPID, 2026-07-28). Ren
// klientkode -- selve abonnementet lagres server-side via /push/subscribe.
// VIKTIG plattformbegrensning (se FEATURE_BACKLOG.md): iOS Safari støtter
// Web Push KUN når PWA-en er lagt til på hjemskjermen (installert som
// "standalone") -- en vanlig Safari-fane kan aldri abonnere, uansett
// tillatelse. isPushSupported() dekker dette.

function urlBase64ToUint8Array(base64: string): Uint8Array {
  const padding = "=".repeat((4 - (base64.length % 4)) % 4)
  const base64Safe = (base64 + padding).replace(/-/g, "+").replace(/_/g, "/")
  const raw = atob(base64Safe)
  const output = new Uint8Array(raw.length)
  for (let i = 0; i < raw.length; i++) output[i] = raw.charCodeAt(i)
  return output
}

export function isPushSupported(): boolean {
  if (typeof window === "undefined") return false
  if (!("serviceWorker" in navigator) || !("PushManager" in window) || !("Notification" in window)) return false
  const nav = window.navigator as Navigator & { standalone?: boolean }
  const isIOS = /iphone|ipad|ipod/i.test(window.navigator.userAgent)
  const isStandalone = window.matchMedia("(display-mode: standalone)").matches || nav.standalone === true
  // iOS krever installasjon til hjemskjermen -- alle andre støttede
  // nettlesere (Chrome/Edge/Firefox-familien) trenger det ikke.
  return !isIOS || isStandalone
}

export async function getExistingSubscription(): Promise<PushSubscription | null> {
  if (!("serviceWorker" in navigator)) return null
  const registration = await navigator.serviceWorker.ready
  return registration.pushManager.getSubscription()
}

export async function subscribeToPush(): Promise<{ ok: boolean; reason?: string }> {
  if (!isPushSupported()) {
    return { ok: false, reason: "unsupported" }
  }
  const permission = await Notification.requestPermission()
  if (permission !== "granted") {
    return { ok: false, reason: "denied" }
  }
  const keyRes = await fetch("/push/vapid-public-key", { credentials: "include" })
  if (!keyRes.ok) return { ok: false, reason: "server-error" }
  const { public_key, configured }: { public_key: string | null; configured: boolean } = await keyRes.json()
  if (!configured || !public_key) return { ok: false, reason: "not-configured" }

  const registration = await navigator.serviceWorker.ready
  const subscription = await registration.pushManager.subscribe({
    userVisibleOnly: true,
    applicationServerKey: urlBase64ToUint8Array(public_key),
  })

  const json = subscription.toJSON()
  const subscribeRes = await fetch("/push/subscribe", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    credentials: "include",
    body: JSON.stringify({
      endpoint: json.endpoint,
      keys: { p256dh: json.keys?.p256dh, auth: json.keys?.auth },
    }),
  })
  if (!subscribeRes.ok) {
    return { ok: false, reason: "server-error" }
  }
  return { ok: true }
}

export async function unsubscribeFromPush(): Promise<void> {
  const subscription = await getExistingSubscription()
  if (!subscription) return
  const endpoint = subscription.endpoint
  await subscription.unsubscribe()
  await fetch("/push/subscribe", {
    method: "DELETE",
    headers: { "Content-Type": "application/json" },
    credentials: "include",
    body: JSON.stringify({ endpoint }),
  }).catch(() => {})
}
