'use client';
import {
  useApiClient,
  useEventBus
} from "./chunk-HNZOXH4L.mjs";

// src/contexts/AuthTokenContext.tsx
import { createContext, useContext } from "react";
import { jsx } from "react/jsx-runtime";
var AuthTokenContext = createContext(void 0);
function AuthTokenProvider({
  token,
  children
}) {
  return /* @__PURE__ */ jsx(AuthTokenContext.Provider, { value: token, children });
}
function useAuthToken() {
  const context = useContext(AuthTokenContext);
  if (context === void 0) {
    throw new Error("useAuthToken must be used within an AuthTokenProvider");
  }
  return context;
}

// src/contexts/useEventSubscription.ts
import { useEffect, useRef, useMemo } from "react";
function useEventSubscription(eventName, handler) {
  const eventBus = useEventBus();
  const handlerRef = useRef(handler);
  useEffect(() => {
    handlerRef.current = handler;
  });
  useEffect(() => {
    const stableHandler = (payload) => {
      handlerRef.current(payload);
    };
    const subscription = eventBus.get(eventName).subscribe(stableHandler);
    return () => {
      subscription.unsubscribe();
    };
  }, [eventName, eventBus]);
}
function useEventSubscriptions(subscriptions) {
  const eventBus = useEventBus();
  const handlersRef = useRef(subscriptions);
  useEffect(() => {
    handlersRef.current = subscriptions;
  });
  const eventNames = useMemo(
    () => Object.keys(subscriptions).sort(),
    // eslint-disable-next-line react-hooks/exhaustive-deps
    [Object.keys(subscriptions).sort().join(",")]
  );
  useEffect(() => {
    const subscriptions2 = [];
    for (const eventName of eventNames) {
      const stableHandler = (payload) => {
        const currentHandler = handlersRef.current[eventName];
        if (currentHandler) {
          currentHandler(payload);
        } else {
          console.warn("[useEventSubscriptions] No current handler found for:", eventName);
        }
      };
      const subscription = eventBus.get(eventName).subscribe(stableHandler);
      subscriptions2.push(subscription);
    }
    return () => {
      for (const subscription of subscriptions2) {
        subscription.unsubscribe();
      }
    };
  }, [eventNames, eventBus]);
}

// src/hooks/useBeckonFlow.ts
import { useState, useRef as useRef2, useCallback, useEffect as useEffect2 } from "react";
import { accessToken } from "@semiont/core";
function useBeckonFlow() {
  const eventBus = useEventBus();
  const [hoveredAnnotationId, setHoveredAnnotationId] = useState(null);
  const handleAnnotationHover = useCallback(({ annotationId }) => {
    setHoveredAnnotationId(annotationId);
    if (annotationId) {
      eventBus.get("beckon:sparkle").next({ annotationId });
    }
  }, []);
  const handleAnnotationClick = useCallback(({ annotationId }) => {
    eventBus.get("beckon:focus").next({ annotationId });
  }, []);
  useEventSubscriptions({
    "beckon:hover": handleAnnotationHover,
    "browse:click": handleAnnotationClick
  });
  return { hoveredAnnotationId };
}
var HOVER_DELAY_MS = 150;
function createHoverHandlers(emit, delayMs) {
  let currentHover = null;
  let timer = null;
  const cancelTimer = () => {
    if (timer !== null) {
      clearTimeout(timer);
      timer = null;
    }
  };
  const handleMouseEnter = (annotationId) => {
    if (currentHover === annotationId) return;
    cancelTimer();
    timer = setTimeout(() => {
      timer = null;
      currentHover = annotationId;
      emit(annotationId);
    }, delayMs);
  };
  const handleMouseLeave = () => {
    cancelTimer();
    if (currentHover !== null) {
      currentHover = null;
      emit(null);
    }
  };
  return { handleMouseEnter, handleMouseLeave, cleanup: cancelTimer };
}
function useHoverEmitter(annotationId, hoverDelayMs = HOVER_DELAY_MS) {
  const eventBus = useEventBus();
  const currentHoverRef = useRef2(null);
  const timerRef = useRef2(null);
  const onMouseEnter = useCallback(() => {
    if (currentHoverRef.current === annotationId) return;
    if (timerRef.current !== null) {
      clearTimeout(timerRef.current);
    }
    timerRef.current = setTimeout(() => {
      timerRef.current = null;
      currentHoverRef.current = annotationId;
      eventBus.get("beckon:hover").next({ annotationId });
    }, hoverDelayMs);
  }, [annotationId, hoverDelayMs]);
  const onMouseLeave = useCallback(() => {
    if (timerRef.current !== null) {
      clearTimeout(timerRef.current);
      timerRef.current = null;
    }
    if (currentHoverRef.current !== null) {
      currentHoverRef.current = null;
      eventBus.get("beckon:hover").next({ annotationId: null });
    }
  }, []);
  useEffect2(() => {
    return () => {
      if (timerRef.current !== null) {
        clearTimeout(timerRef.current);
        timerRef.current = null;
      }
    };
  }, []);
  return { onMouseEnter, onMouseLeave };
}
function useAttentionStream() {
  const client = useApiClient();
  const token = useAuthToken();
  const tokenRef = useRef2(token);
  useEffect2(() => {
    tokenRef.current = token;
  });
  const [status, setStatus] = useState("disconnected");
  useEffect2(() => {
    setStatus("connecting");
    try {
      const sub = client.flows.attentionStream(
        () => tokenRef.current ? accessToken(tokenRef.current) : void 0
      );
      setStatus("connected");
      return () => {
        sub.unsubscribe();
        setStatus("disconnected");
      };
    } catch (error) {
      console.error("[AttentionStream] Failed to connect:", error);
      setStatus("error");
      return;
    }
  }, [client]);
  return { status };
}

export {
  AuthTokenProvider,
  useAuthToken,
  useEventSubscription,
  useEventSubscriptions,
  useBeckonFlow,
  HOVER_DELAY_MS,
  createHoverHandlers,
  useHoverEmitter,
  useAttentionStream
};
//# sourceMappingURL=chunk-BQJWOK4C.mjs.map