"use client";

import { useEffect, useState } from "react";

export function PwaRegister() {
  const [showUpdate, setShowUpdate] = useState(false);
  const [isOffline, setIsOffline] = useState(false);
  const [mutationFailed, setMutationFailed] = useState(false);

  useEffect(() => {
    const handleOffline = () => setIsOffline(true);
    const handleOnline = () => setIsOffline(false);
    window.addEventListener("offline", handleOffline);
    window.addEventListener("online", handleOnline);
    // Re-sync after listeners are registered in case the online/offline event
    // fired between page load and this effect running (e.g. DevTools toggle).
    const syncId = setTimeout(() => setIsOffline(!navigator.onLine), 0);

    if (!("serviceWorker" in navigator)) {
      return () => {
        window.removeEventListener("offline", handleOffline);
        window.removeEventListener("online", handleOnline);
      };
    }

    // Capture whether a SW already controls this page before registering.
    // If true and the controller later changes, a new build has deployed.
    const hadController = !!navigator.serviceWorker.controller;

    navigator.serviceWorker
      .register("/sw.js", { scope: "/" })
      .catch((err) => console.warn("[famapp] SW registration failed:", err));

    const handleControllerChange = () => {
      if (hadController) setShowUpdate(true);
    };
    navigator.serviceWorker.addEventListener("controllerchange", handleControllerChange);

    const handleMessage = (e: MessageEvent) => {
      if (e.data?.type === "OFFLINE_MUTATION") {
        setMutationFailed(true);
        setTimeout(() => setMutationFailed(false), 4000);
      }
    };
    navigator.serviceWorker.addEventListener("message", handleMessage);

    return () => {
      clearTimeout(syncId);
      window.removeEventListener("offline", handleOffline);
      window.removeEventListener("online", handleOnline);
      navigator.serviceWorker.removeEventListener("controllerchange", handleControllerChange);
      navigator.serviceWorker.removeEventListener("message", handleMessage);
    };
  }, []);

  return (
    <>
      {isOffline && (
        <div
          role="status"
          className="fixed top-4 left-1/2 -translate-x-1/2 z-50 flex items-center gap-3 rounded-lg bg-amber-50 px-4 py-3 text-amber-900 shadow-lg ring-1 ring-amber-200 dark:bg-amber-950 dark:text-amber-100 dark:ring-amber-800"
        >
          <span className="text-sm font-medium">You&rsquo;re offline — showing cached content</span>
          <button
            onClick={() => setIsOffline(false)}
            aria-label="Dismiss"
            className="text-sm opacity-60 hover:opacity-100"
          >
            ✕
          </button>
        </div>
      )}

      {mutationFailed && !isOffline && (
        <div
          role="alert"
          className="fixed top-4 left-1/2 -translate-x-1/2 z-50 flex items-center gap-3 rounded-lg bg-destructive px-4 py-3 text-destructive-foreground shadow-lg"
        >
          <span className="text-sm font-medium">Changes can&rsquo;t be saved while offline</span>
        </div>
      )}

      {showUpdate && (
        <div
          role="status"
          className="fixed bottom-6 left-1/2 -translate-x-1/2 z-50 flex items-center gap-3 rounded-lg bg-primary px-4 py-3 text-primary-foreground shadow-lg"
        >
          <span className="text-sm font-medium">New version available</span>
          <button
            onClick={() => window.location.reload()}
            className="text-sm font-semibold underline underline-offset-2"
          >
            Refresh
          </button>
          <button
            onClick={() => setShowUpdate(false)}
            aria-label="Dismiss"
            className="text-sm opacity-60 hover:opacity-100"
          >
            ✕
          </button>
        </div>
      )}
    </>
  );
}
