import { createEffect } from "solid-js";
import { createStableCallback } from "../stable-callback.jsx";
import { useAnimationsFinished } from "../use-animations-finished.jsx";

/**
 * Plain `{ current }` ref shape that mirrors React's `RefObject<HTMLElement |
 * null>`. Kept structurally identical to the other `MutableRef<T>`
 * declarations in this codebase (see `use-latest-ref.ts`) so consumers can
 * pass the same object interchangeably.
 */

/**
 * Calls the provided function when the CSS open/close animation or
 * transition on the referenced element completes.
 *
 * Port of Base UI React's
 * `packages/react/src/internals/useOpenChangeComplete.tsx`. The React
 * version re-runs its effect every time `open`, `enabled`, or the
 * stabilized `onComplete` changes — because the effect's dependency
 * array includes those inputs. The Solid equivalent uses a
 * `createEffect` split-form that tracks the same reactive inputs: each
 * change re-fires the apply, which aborts any prior in-flight wait and
 * schedules a fresh `runOnceAnimationsFinish` cycle.
 *
 * The `ref` is intentionally not reactive — matching React, which reads
 * `ref.current` lazily inside `useAnimationsFinished`'s closure. If the
 * ref populates after setup, the next `open` change will pick it up.
 *
 * @example
 * ```ts
 * const [open, setOpen] = createSignal(false);
 * let el!: HTMLDivElement;
 * useOpenChangeComplete({
 *   open,
 *   ref: { get current() { return el; }, set current(v) { el = v!; } },
 *   onComplete: () => setMounted(false),
 * });
 * ```
 */
export function useOpenChangeComplete(parameters) {
  const {
    enabled = true,
    open,
    ref,
    onComplete: onCompleteParam
  } = parameters;
  const isEnabled = () => typeof enabled === "function" ? enabled() : enabled;

  // Stabilize the consumer-provided callback. `createStableCallback` expects
  // a getter so the trampoline can forward to the latest reference at call
  // time; we bind to `onCompleteParam` captured in this closure — in Solid
  // the hook runs once per component, so this getter doesn't need to
  // re-resolve across renders (there are no renders), it just keeps the
  // identity stable for downstream captures.
  const onComplete = createStableCallback(() => onCompleteParam);

  // Resolve the element via the existing ref on each invocation.
  // `useAnimationsFinished` accepts an `ElementSource` which can be an
  // accessor that returns an element — a ref-reader accessor fits exactly.
  const runOnceAnimationsFinish = useAnimationsFinished(() => ref.current);

  // Mirror React's `useEffect` with deps [enabled, open, onComplete,
  // runOnceAnimationsFinish]. The stable-callback trampolines don't
  // change, so the live deps are effectively `isEnabled()` and `open()`.
  // On each apply, abort any outstanding wait cycle (to cancel a stale
  // close wait when a rapid re-open arrives) and schedule a fresh one.
  createEffect(() => ({
    enabled: isEnabled(),
    openValue: open?.()
  }), deps => {
    if (!deps.enabled) {
      return undefined;
    }
    const abortController = new AbortController();
    runOnceAnimationsFinish(onComplete, abortController.signal);
    return () => {
      abortController.abort();
    };
  });
}
//# sourceMappingURL=use-open-change-complete.jsx.map
