/**
 * Stage 4.4 port of Base UI React's `useHoverInteractionSharedState`.
 *
 * React source:
 *   `base-ui/packages/react/src/floating-ui-react/hooks/useHoverInteractionSharedState.ts`
 *
 * Exposes the `HoverInteraction` class — a plain mutable bag of state
 * shared between `useHoverReferenceInteraction` (reference-side) and
 * `useHoverFloatingInteraction` (floating-side) so both can cooperate on
 * cursor-type tracking, timers, and safe-polygon bookkeeping.
 *
 * The instance is attached to `rootStore.context.dataRef.current` under a
 * `hoverInteractionState` key so independent hook instances on the same
 * floating root share the same mutable bag (matches React).
 *
 * ### React → Solid deviations
 *
 * 1. `useRefWithInit(HoverInteraction.create)` → plain variable access.
 *    Solid component bodies run once per mount, so `new HoverInteraction()`
 *    at setup time matches React's one-shot initialization.
 * 2. `useOnMount(dispose)` → `onCleanup(dispose)` registered during setup.
 *    Same effect: timers get cleared when the owning scope disposes.
 * 3. No reactivity is involved — all fields are plain mutables. The class
 *    shape, `dispose()` semantics, and `Timeout` usage are copied 1:1.
 */

import { onCleanup } from "solid-js";
import { Timeout } from "../../use-timeout.jsx";
import { isInteractiveElement } from "../utils/element.jsx";
export { isInteractiveElement };

/**
 * Shared mutable state bag for a single floating root's hover cluster.
 */
export class HoverInteraction {
  constructor() {
    this.pointerType = undefined;
    this.interactedInside = false;
    this.handler = undefined;
    this.blockMouseMove = true;
    this.performedPointerEventsMutation = false;
    this.pointerEventsScopeElement = null;
    this.pointerEventsReferenceElement = null;
    this.pointerEventsFloatingElement = null;
    this.restTimeoutPending = false;
    this.openChangeTimeout = new Timeout();
    this.restTimeout = new Timeout();
    this.handleCloseOptions = undefined;
  }
  static create() {
    return new HoverInteraction();
  }
  dispose = () => {
    this.openChangeTimeout.clear();
    this.restTimeout.clear();
  };
}
/**
 * Track which `HoverInteraction` instance currently owns the pointer-events
 * mutation for a given scope element. Only the owner may clear the styles,
 * preventing sibling hover surfaces from stomping on each other.
 */
const pointerEventsMutationOwnerByScopeElement = new WeakMap();
export function clearSafePolygonPointerEventsMutation(instance) {
  if (!instance.performedPointerEventsMutation) {
    return;
  }
  const scopeElement = instance.pointerEventsScopeElement;
  if (scopeElement && pointerEventsMutationOwnerByScopeElement.get(scopeElement) === instance) {
    instance.pointerEventsScopeElement?.style.removeProperty("pointer-events");
    instance.pointerEventsReferenceElement?.style.removeProperty("pointer-events");
    instance.pointerEventsFloatingElement?.style.removeProperty("pointer-events");
    pointerEventsMutationOwnerByScopeElement.delete(scopeElement);
  }
  instance.performedPointerEventsMutation = false;
  instance.pointerEventsScopeElement = null;
  instance.pointerEventsReferenceElement = null;
  instance.pointerEventsFloatingElement = null;
}
export function applySafePolygonPointerEventsMutation(instance, options) {
  const {
    scopeElement,
    referenceElement,
    floatingElement
  } = options;
  const existingOwner = pointerEventsMutationOwnerByScopeElement.get(scopeElement);
  if (existingOwner && existingOwner !== instance) {
    clearSafePolygonPointerEventsMutation(existingOwner);
  }
  clearSafePolygonPointerEventsMutation(instance);
  instance.performedPointerEventsMutation = true;
  instance.pointerEventsScopeElement = scopeElement;
  instance.pointerEventsReferenceElement = referenceElement;
  instance.pointerEventsFloatingElement = floatingElement;
  pointerEventsMutationOwnerByScopeElement.set(scopeElement, instance);
  scopeElement.style.pointerEvents = "none";
  referenceElement.style.pointerEvents = "auto";
  floatingElement.style.pointerEvents = "auto";
}
/**
 * Returns the `HoverInteraction` bag for the given root store, creating
 * and caching it on the shared `dataRef` if needed. All hover hooks that
 * cooperate on the same root share a single instance.
 */
export function useHoverInteractionSharedState(store) {
  const data = store.context.dataRef.current;
  if (!data.hoverInteractionState) {
    data.hoverInteractionState = HoverInteraction.create();
  }
  const instance = data.hoverInteractionState;

  // React uses `useOnMount(disposeEffect)` — run `dispose()` on unmount.
  // In Solid, the owning scope's `onCleanup` is the direct analogue.
  onCleanup(() => {
    instance.dispose();
  });
  return instance;
}
//# sourceMappingURL=use-hover-interaction-shared-state.jsx.map
