document.addEventListener("DOMContentLoaded", () => {
  const urlBase64ToUint8Array = (base64String) => {
    const padding = "=".repeat((4 - (base64String.length % 4)) % 4);
    const base64 = (base64String + padding)
      .replace(/-/g, "+")
      .replace(/_/g, "/");
    const rawData = window.atob(base64);
    const outputArray = new Uint8Array(rawData.length);

    for (let index = 0; index < rawData.length; ++index) {
      outputArray[index] = rawData.charCodeAt(index);
    }

    return outputArray;
  };

  const initCountdowns = (containerSelector, valueSelector) => {
    document.querySelectorAll(containerSelector).forEach((countdownEl) => {
      const target = countdownEl.querySelector(valueSelector);
      const deadline = countdownEl.getAttribute("data-deadline");

      if (!target || !deadline) {
        return;
      }

      const deadlineMs = Date.parse(deadline);

      if (Number.isNaN(deadlineMs)) {
        return;
      }

      const tick = () => {
        let seconds = Math.max(0, Math.floor((deadlineMs - Date.now()) / 1000));
        const days = Math.floor(seconds / 86400);
        seconds -= days * 86400;
        const hours = Math.floor(seconds / 3600);
        seconds -= hours * 3600;
        const minutes = Math.floor(seconds / 60);
        seconds -= minutes * 60;

        target.textContent = `${days}d ${String(hours).padStart(2, "0")}h ${String(minutes).padStart(2, "0")}m ${String(seconds).padStart(2, "0")}s`;
      };

      tick();
      window.setInterval(tick, 1000);
    });
  };

  const initWebPushPrompt = async () => {
    const prompt = document.querySelector("[data-web-push-prompt]");

    if (!prompt) {
      return;
    }

    const enableButton = prompt.querySelector("[data-web-push-enable]");
    const dismissButton = prompt.querySelector("[data-web-push-dismiss]");
    const state = prompt.querySelector("[data-web-push-state]");
    const dismissKey = "jlfc_web_push_prompt_dismissed";
    const publicKey = prompt.getAttribute("data-public-key") || "";
    const subscribeUrl = prompt.getAttribute("data-subscribe-url") || "";
    const serviceWorkerUrl =
      prompt.getAttribute("data-service-worker-url") || "";
    const serviceWorkerScope =
      prompt.getAttribute("data-service-worker-scope") || undefined;

    const setState = (message) => {
      if (state) {
        state.textContent = message;
      }
    };

    const hidePrompt = () => {
      prompt.hidden = true;
    };

    const showPrompt = () => {
      prompt.hidden = false;
    };

    if (
      !("serviceWorker" in navigator) ||
      !("PushManager" in window) ||
      !("Notification" in window) ||
      publicKey === "" ||
      subscribeUrl === "" ||
      serviceWorkerUrl === ""
    ) {
      hidePrompt();
      return;
    }

    if (Notification.permission === "denied") {
      hidePrompt();
      return;
    }

    if (
      Notification.permission === "default" &&
      window.localStorage.getItem(dismissKey) !== "1"
    ) {
      showPrompt();
      setState("Allow notifications to receive public JLFC updates.");
    }

    try {
      const registration = await navigator.serviceWorker.register(
        serviceWorkerUrl,
        serviceWorkerScope ? { scope: serviceWorkerScope } : undefined,
      );
      const existingSubscription =
        await registration.pushManager.getSubscription();

      if (existingSubscription) {
        hidePrompt();
        return;
      }
    } catch (error) {
      showPrompt();
      setState("Browser notifications could not be prepared on this device.");
      return;
    }

    if (dismissButton) {
      dismissButton.addEventListener("click", () => {
        window.localStorage.setItem(dismissKey, "1");
        hidePrompt();
      });
    }

    if (enableButton) {
      enableButton.addEventListener("click", async () => {
        enableButton.disabled = true;
        setState("Preparing browser notifications...");

        try {
          const permission = await Notification.requestPermission();

          if (permission !== "granted") {
            setState(
              "Notifications were not enabled. You can allow them from your browser settings.",
            );
            enableButton.disabled = false;
            showPrompt();
            return;
          }

          const registration = await navigator.serviceWorker.register(
            serviceWorkerUrl,
            serviceWorkerScope ? { scope: serviceWorkerScope } : undefined,
          );
          const subscription = await registration.pushManager.subscribe({
            userVisibleOnly: true,
            applicationServerKey: urlBase64ToUint8Array(publicKey),
          });

          const response = await window.fetch(subscribeUrl, {
            method: "POST",
            headers: {
              "Content-Type": "application/json",
              Accept: "application/json",
            },
            body: JSON.stringify({
              action: "subscribe",
              subscription: subscription.toJSON(),
            }),
          });

          if (!response.ok) {
            throw new Error("Subscription save failed");
          }

          window.localStorage.removeItem(dismissKey);
          setState("Live alerts enabled.");
          hidePrompt();
        } catch (error) {
          setState(
            "Could not enable notifications right now. Please try again.",
          );
          enableButton.disabled = false;
          showPrompt();
        }
      });
    }
  };

  const toggleButton = document.querySelector("[data-sidebar-toggle]");
  const sidebar = document.getElementById("sidebarPanel");

  if (toggleButton && sidebar) {
    toggleButton.addEventListener("click", () => {
      sidebar.classList.toggle("is-open");
    });

    document.addEventListener("click", (event) => {
      if (!sidebar.classList.contains("is-open")) {
        return;
      }

      const clickedInsideSidebar = sidebar.contains(event.target);
      const clickedToggle = toggleButton.contains(event.target);

      if (!clickedInsideSidebar && !clickedToggle) {
        sidebar.classList.remove("is-open");
      }
    });
  }

  initCountdowns(
    "[data-transfer-countdown]",
    "[data-transfer-countdown-value]",
  );
  initCountdowns("[data-live-countdown]", "[data-live-countdown-value]");
  initWebPushPrompt();
});
