// PWA glue: register the service worker, and (for signed-in users on a
// push-enabled server) drive the notification opt-in toggle in the settings
// panel. Anonymous visitors still get the offline reader — only the push
// controls are gated behind sign-in + a configured VAPID key.
(function () {
  if (!("serviceWorker" in navigator)) return;

  var CFG = window.PETE_PUSH || null; // { enabled, publicKey } or null
  var reg = null;

  navigator.serviceWorker.register("/sw.js").then(function (r) {
    reg = r;
    if (canPush()) initPushUI();
  }).catch(function () {});

  function canPush() {
    return !!(CFG && CFG.enabled && CFG.publicKey && window.PETE_USER &&
      "PushManager" in window && "Notification" in window);
  }

  // ---- push subscription ----------------------------------------------------
  function urlBase64ToUint8Array(base64String) {
    var padding = "=".repeat((4 - (base64String.length % 4)) % 4);
    var base64 = (base64String + padding).replace(/-/g, "+").replace(/_/g, "/");
    var raw = atob(base64);
    var out = new Uint8Array(raw.length);
    for (var i = 0; i < raw.length; i++) out[i] = raw.charCodeAt(i);
    return out;
  }

  function currentSub() {
    if (!reg) return Promise.resolve(null);
    return reg.pushManager.getSubscription();
  }

  function subscribe() {
    return reg.pushManager.subscribe({
      userVisibleOnly: true,
      applicationServerKey: urlBase64ToUint8Array(CFG.publicKey),
    }).then(function (sub) {
      return fetch("/api/push/subscribe", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify(sub.toJSON()),
        credentials: "same-origin",
      }).then(function (res) {
        if (!res.ok) throw new Error("subscribe rejected");
        return sub;
      });
    });
  }

  function unsubscribe() {
    return currentSub().then(function (sub) {
      if (!sub) return;
      var endpoint = sub.endpoint;
      return sub.unsubscribe().then(function () {
        return fetch("/api/push/unsubscribe", {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({ endpoint: endpoint }),
          credentials: "same-origin",
        }).catch(function () {});
      });
    });
  }

  // ---- settings-panel toggle ------------------------------------------------
  function initPushUI() {
    var slot = document.querySelector("[data-push-section]");
    if (!slot) return;
    slot.hidden = false;

    var btn = slot.querySelector("[data-push-toggle]");
    var note = slot.querySelector("[data-push-note]");
    if (!btn) return;
    var busy = false;

    function paint(on, text) {
      btn.setAttribute("aria-pressed", on ? "true" : "false");
      btn.textContent = on ? "Notifications on" : "Turn on notifications";
      if (note && text != null) note.textContent = text;
    }

    function refresh() {
      if (Notification.permission === "denied") {
        btn.disabled = true;
        paint(false, "Notifications are blocked in your browser settings.");
        return;
      }
      currentSub().then(function (sub) {
        paint(!!sub, sub ? "You'll get a nudge when new stories land." : "Get a nudge when new stories land.");
      });
    }

    btn.addEventListener("click", function () {
      if (busy) return;
      busy = true;
      btn.disabled = true;
      currentSub().then(function (sub) {
        if (sub) return unsubscribe().then(function () { paint(false, "Notifications off."); });
        return Notification.requestPermission().then(function (perm) {
          if (perm !== "granted") { paint(false, "Permission denied."); return; }
          return subscribe().then(function () { paint(true, "You're all set. New stories will nudge you."); });
        });
      }).catch(function () {
        paint(false, "Something went wrong. Try again.");
      }).finally(function () {
        busy = false;
        btn.disabled = Notification.permission === "denied";
      });
    });

    refresh();
  }
})();
