import { useEffect, useRef } from "react";
import type { DomainHook } from "./domainHook.js";

/** Payload shape for notification.escalated domain events. */
interface EscalationPayload {
  escalationId: string;
  taskId: string;
  title: string;
  message: string;
  source: string;
  urgency: string;
  taskUrl: string;
}

/** Domain event shape matching GrackleEvent from the event bus. */
interface DomainEvent {
  type: string;
  payload: Record<string, unknown>;
}

/**
 * Hook that requests browser notification permission and shows
 * native notifications when escalation events arrive.
 */
export function useNotifications(): {
  handleEvent: (event: DomainEvent) => boolean;
  domainHook: DomainHook;
} {
  const permissionRef = useRef<NotificationPermission>("default");

  // Sync permission state on mount (don't auto-request — browsers require a user gesture)
  useEffect(() => {
    if (typeof Notification === "undefined") {
      return;
    }
    permissionRef.current = Notification.permission;
  }, []);

  function handleEvent(event: DomainEvent): boolean {
    if (event.type !== "notification.escalated") {
      return false;
    }

    if (typeof Notification === "undefined") {
      return true; // Consumed the event but browser doesn't support notifications
    }

    // Request permission on first escalation event (user gesture proxy — the
    // event is triggered by agent activity, not page load)
    if (permissionRef.current === "default") {
      Notification.requestPermission().then((perm) => {
        permissionRef.current = perm;
      }).catch(() => {});
      return true;
    }

    if (permissionRef.current !== "granted") {
      return true; // Permission denied, consume silently
    }

    const payload = event.payload as unknown as EscalationPayload;
    const notification = new Notification(payload.title || "Agent needs input", {
      body: payload.message || "An agent is waiting for your input.",
      tag: payload.escalationId, // Prevents duplicate notifications for same escalation
      icon: "/icon-192x192.png",
    });

    notification.onclick = () => {
      window.focus();
      if (payload.taskUrl) {
        window.location.href = payload.taskUrl;
      }
      notification.close();
    };

    return true;
  }

  const domainHook: DomainHook = {
    onConnect: async () => {},
    onDisconnect: () => {},
    handleEvent,
  };

  return { handleEvent, domainHook };
}
