"use client";

import { useCallback, useEffect, useState } from "react";
import { useNotifPrefs } from "@/lib/notifications/notification-prefs.store";
import { requestNotificationNav } from "@/lib/notifications/notification-routes";

export type PermissionState = NotificationPermission | "unsupported";

export function notificationsSupported(): boolean {
  return typeof window !== "undefined" && "Notification" in window;
}

export function getPermission(): PermissionState {
  if (!notificationsSupported()) return "unsupported";
  return Notification.permission;
}

export async function requestNotificationPermission(): Promise<PermissionState> {
  if (!notificationsSupported()) return "unsupported";
  try {
    return await Notification.requestPermission();
  } catch {
    return Notification.permission;
  }
}

/**
 * Show a native OS/Windows desktop notification. Gated by the user's prefs and the
 * browser permission, and — by design — only fires when the dashboard tab is NOT
 * the focused/visible one. When the user is looking at the dashboard, the in-app
 * toast + sound already covers it; the OS popup is for when they're in another app.
 */
export function showDesktopNotification(opts: {
  title: string;
  body?: string;
  /** Collapses repeat popups for the same subject (e.g. the order id). */
  tag?: string;
  /** In-app path to open when the popup is clicked. */
  path?: string | null;
  /** Bypass the "only when tab hidden" rule — for the settings test button. */
  force?: boolean;
}): void {
  if (!notificationsSupported()) return;
  if (!useNotifPrefs.getState().desktopEnabled) return;
  if (Notification.permission !== "granted") return;
  if (!opts.force && typeof document !== "undefined" && document.visibilityState === "visible") return;
  try {
    const n = new Notification(opts.title, {
      body: opts.body,
      tag: opts.tag,
      icon: "/icons/icon-192.png",
      badge: "/icons/icon-192.png",
      lang: "fa",
    });
    n.onclick = () => {
      try {
        window.focus();
      } catch {
        // ignore
      }
      // Bring the user straight to the related page (handled by the nav bridge).
      if (opts.path) requestNotificationNav(opts.path);
      n.close();
    };
  } catch {
    // notification construction can throw on some platforms — non-fatal
  }
}

/** Reactive permission state + request action, for the settings UI. */
export function useNotificationPermission() {
  const [permission, setPermission] = useState<PermissionState>("unsupported");

  useEffect(() => {
    setPermission(getPermission());
  }, []);

  const request = useCallback(async () => {
    const p = await requestNotificationPermission();
    setPermission(p);
    return p;
  }, []);

  return { permission, request, supported: notificationsSupported() };
}
