"use client";
import { useEffect, useRef } from "react";
import { APP_EVENT_DOM_NAME } from "./useAppEvent.js";
const SSE_ENDPOINT = "/api/events/stream";
const HEARTBEAT_TIMEOUT = 45e3;
const RECONNECT_BASE_MS = 1e3;
const RECONNECT_MAX_MS = 3e4;
const DEDUP_WINDOW_MS = 500;
const BRIDGE_RECONNECTED_EVENT_ID = "om:bridge:reconnected";
function useEventBridge() {
  const sourceRef = useRef(null);
  const reconnectAttempts = useRef(0);
  const reconnectTimer = useRef(null);
  const heartbeatTimer = useRef(null);
  const recentEvents = useRef(/* @__PURE__ */ new Map());
  const hasEverConnected = useRef(false);
  const reconnectPending = useRef(false);
  useEffect(() => {
    let mounted = true;
    function isDuplicate(eventPayload) {
      const key = `${eventPayload.id}:${JSON.stringify(eventPayload.payload ?? {})}`;
      const lastSeen = recentEvents.current.get(key);
      if (lastSeen && Date.now() - lastSeen < DEDUP_WINDOW_MS) return true;
      recentEvents.current.set(key, Date.now());
      if (recentEvents.current.size > 100) {
        const now = Date.now();
        for (const [k, v] of recentEvents.current) {
          if (now - v > DEDUP_WINDOW_MS * 2) recentEvents.current.delete(k);
        }
      }
      return false;
    }
    function resetHeartbeatTimer() {
      if (heartbeatTimer.current) clearTimeout(heartbeatTimer.current);
      heartbeatTimer.current = setTimeout(() => {
        console.warn("[EventBridge] Heartbeat timeout \u2014 reconnecting");
        disconnect();
        scheduleReconnect();
      }, HEARTBEAT_TIMEOUT);
    }
    function connect() {
      if (!mounted) return;
      if (sourceRef.current) return;
      try {
        const source = new EventSource(SSE_ENDPOINT, { withCredentials: true });
        sourceRef.current = source;
        source.onopen = () => {
          const shouldEmitReconnect = hasEverConnected.current && reconnectPending.current;
          hasEverConnected.current = true;
          reconnectPending.current = false;
          reconnectAttempts.current = 0;
          resetHeartbeatTimer();
          if (shouldEmitReconnect) {
            window.dispatchEvent(
              new CustomEvent(APP_EVENT_DOM_NAME, {
                detail: {
                  id: BRIDGE_RECONNECTED_EVENT_ID,
                  payload: {},
                  timestamp: Date.now(),
                  organizationId: ""
                }
              })
            );
          }
        };
        source.onmessage = (event) => {
          resetHeartbeatTimer();
          if (!event.data || event.data === ":heartbeat") return;
          try {
            const parsed = JSON.parse(event.data);
            if (!parsed.id || typeof parsed.id !== "string") return;
            if (isDuplicate(parsed)) return;
            window.dispatchEvent(
              new CustomEvent(APP_EVENT_DOM_NAME, { detail: parsed })
            );
          } catch {
          }
        };
        source.onerror = () => {
          if (hasEverConnected.current) {
            reconnectPending.current = true;
          }
          disconnect();
          if (mounted) scheduleReconnect();
        };
      } catch {
        if (hasEverConnected.current) {
          reconnectPending.current = true;
        }
        if (mounted) scheduleReconnect();
      }
    }
    function disconnect() {
      if (sourceRef.current) {
        sourceRef.current.close();
        sourceRef.current = null;
      }
      if (heartbeatTimer.current) {
        clearTimeout(heartbeatTimer.current);
        heartbeatTimer.current = null;
      }
    }
    function scheduleReconnect() {
      if (reconnectTimer.current) return;
      const delay = Math.min(
        RECONNECT_BASE_MS * Math.pow(2, reconnectAttempts.current),
        RECONNECT_MAX_MS
      );
      reconnectAttempts.current++;
      reconnectTimer.current = setTimeout(() => {
        reconnectTimer.current = null;
        connect();
      }, delay);
    }
    connect();
    return () => {
      mounted = false;
      disconnect();
      if (reconnectTimer.current) {
        clearTimeout(reconnectTimer.current);
        reconnectTimer.current = null;
      }
    };
  }, []);
}
export {
  useEventBridge
};
//# sourceMappingURL=eventBridge.js.map
