import { useState, useEffect, useCallback } from "react";

export type NotificationMode = "my_turn" | "all_picks";

function getEnabledKey(userId: string, seasonId: string) {
  return `draftNotifications-${userId}-${seasonId}`;
}

function getModeKey(userId: string, seasonId: string) {
  return `draftNotificationMode-${userId}-${seasonId}`;
}

export function useDraftNotifications(seasonId: string, userId: string) {
  const [permissionState, setPermissionState] = useState<
    NotificationPermission | "unsupported"
  >("unsupported");
  const [enabled, setEnabledState] = useState(false);
  const [mode, setModeState] = useState<NotificationMode>("my_turn");

  // Check browser support, restore persisted preferences, and watch for permission changes
  useEffect(() => {
    if (typeof window === "undefined" || !("Notification" in window)) {
      return;
    }

    setPermissionState(Notification.permission);

    // Restore preferences from localStorage only if permission is granted
    if (Notification.permission === "granted") {
      const storedEnabled = localStorage.getItem(getEnabledKey(userId, seasonId));
      if (storedEnabled === "true") {
        setEnabledState(true);
      }
    }

    const storedMode = localStorage.getItem(getModeKey(userId, seasonId));
    if (storedMode === "my_turn" || storedMode === "all_picks") {
      setModeState(storedMode);
    }

    // Watch for the user revoking/granting permission in browser settings.
    // Use an abort flag so that if the component unmounts before the promise
    // resolves, the cleanup doesn't fail to clear onchange (permissionStatus
    // would still be null at that point without the flag).
    let aborted = false;
    let permissionStatus: PermissionStatus | null = null;
    let changeHandler: (() => void) | null = null;
    navigator.permissions
      .query({ name: "notifications" })
      .then((status) => {
        if (aborted) return;
        permissionStatus = status;
        changeHandler = () => {
          setPermissionState(status.state as NotificationPermission);
          // If permission was revoked, disable notifications
          if (status.state !== "granted") {
            setEnabledState(false);
          }
        };
        status.addEventListener("change", changeHandler);
      })
      .catch(() => {
        // Permissions API not available in all environments; silently ignore
      });

    return () => {
      aborted = true;
      if (permissionStatus && changeHandler) {
        permissionStatus.removeEventListener("change", changeHandler);
      }
    };
  }, [seasonId, userId]);

  const setEnabled = useCallback(
    async (value: boolean) => {
      if (typeof window === "undefined" || !("Notification" in window)) return;

      if (value) {
        // Request permission if not yet granted
        if (Notification.permission === "default") {
          const result = await Notification.requestPermission();
          setPermissionState(result);
          if (result !== "granted") {
            return;
          }
        } else if (Notification.permission === "denied") {
          return;
        }

        setEnabledState(true);
        localStorage.setItem(getEnabledKey(userId, seasonId), "true");
      } else {
        setEnabledState(false);
        localStorage.setItem(getEnabledKey(userId, seasonId), "false");
      }
    },
    [userId, seasonId]
  );

  const setMode = useCallback(
    (value: NotificationMode) => {
      setModeState(value);
      localStorage.setItem(getModeKey(userId, seasonId), value);
    },
    [userId, seasonId]
  );

  const sendNotification = useCallback(
    (title: string, body: string) => {
      if (
        !enabled ||
        typeof window === "undefined" ||
        !("Notification" in window) ||
        Notification.permission !== "granted" ||
        typeof document === "undefined" ||
        !document.hidden
      ) {
        return;
      }

      const n = new Notification(title, {
        body,
        tag: `draft-${seasonId}`,
      });
      n.addEventListener("click", () => window.focus());
    },
    [enabled, seasonId]
  );

  return {
    permissionState,
    enabled,
    setEnabled,
    mode,
    setMode,
    sendNotification,
  };
}
