"use client";

import * as React from "react";
import { useToast } from "@/components/ui/toast";

/**
 * Registers the service worker once on mount. SSR-safe: no-op on the server
 * and on browsers without ServiceWorker support. When the active SW changes
 * (a new version has activated), shows a toast prompting reload.
 */
export function SwRegister() {
  const { toast } = useToast();

  React.useEffect(() => {
    if (typeof window === "undefined") return;
    if (!("serviceWorker" in navigator)) return;

    let cancelled = false;

    // Defer registration to idle time so it doesn't fight initial paint.
    const register = () => {
      if (cancelled) return;
      navigator.serviceWorker
        .register("/sw.js", { scope: "/" })
        .catch(() => {
          // Registration can fail in private browsing or with strict CSP.
          // We intentionally swallow — the app still works without offline support.
        });
    };

    const w = window as Window & {
      requestIdleCallback?: (cb: () => void) => number;
    };
    if (typeof w.requestIdleCallback === "function") {
      w.requestIdleCallback(register);
    } else {
      window.setTimeout(register, 1500);
    }

    let toastedThisLoad = false;
    const onControllerChange = () => {
      // Fired when a new SW takes control of the page. Skip the very first
      // fire on a never-controlled page (no prior controller → fresh install).
      if (toastedThisLoad) return;
      toastedThisLoad = true;
      toast({
        title: "A new version is available",
        description: "Reload to pick up the latest changes.",
        duration: 0,
        action: (
          <button
            type="button"
            onClick={() => window.location.reload()}
            className="rounded-md bg-primary px-3 py-1 text-xs font-medium text-primary-foreground hover:bg-primary/90"
          >
            Reload
          </button>
        ),
      });
    };

    navigator.serviceWorker.addEventListener("controllerchange", onControllerChange);

    return () => {
      cancelled = true;
      navigator.serviceWorker.removeEventListener("controllerchange", onControllerChange);
    };
  }, [toast]);

  return null;
}

export default SwRegister;
