import { dynamic } from "@solidjs/web";
import { createEffect, createRenderEffect, createSignal, omit, onCleanup, Show, untrack } from "solid-js";
import { mergeRootProps } from "../../internals/merge-root-props.jsx";
import { resolveClassStyle } from "../../internals/resolve-class-style.jsx";
import { useAnimationsFinished } from "../../internals/use-animations-finished.jsx";
import { useImageLoadingStatus } from "../../internals/use-image-loading-status.jsx";
import { useTransitionStatus } from "../../internals/use-transition-status/use-transition-status.jsx";
import { useAvatarRootContext } from "../avatar-root-context.jsx";
/**
 * The image to be displayed in the avatar. Renders an `<img>` element.
 *
 * Mount/unmount is driven by {@link useTransitionStatus}: the element mounts
 * as soon as the standalone probe reports `loaded`, and stays mounted (with
 * `data-ending-style`) on unload until any CSS transitions / animations
 * settle — matching Base UI React's
 * `useTransitionStatus` + `useOpenChangeComplete` composition.
 */
export function AvatarImage(props) {
  const context = useAvatarRootContext();

  // Solid 2's JSX typings widen HTML attributes to `string | RemoveAttribute`
  // (RFC 07 — boolean false removes the attribute). The probe only
  // understands plain strings; coerce out the boolean branch here.
  const asString = v => typeof v === "string" ? v : undefined;
  const status = useImageLoadingStatus({
    src: () => asString(props.src),
    referrerPolicy: () => asString(props.referrerpolicy),
    crossOrigin: () => asString(props.crossorigin)
  });
  const isVisible = () => status() === "loaded";
  const {
    mounted,
    transitionStatus,
    setMounted
  } = useTransitionStatus(isVisible);

  // Mirror the internal status into the root context (so `<Avatar.Fallback>`
  // can react) and notify the consumer callback. Two separate split effects
  // keep the dependencies explicit.
  createEffect(() => status(), next => {
    if (next !== "idle") {
      context.setImageLoadingStatus(next);
    }
  });
  createEffect(() => status(), next => {
    if (next !== "idle") {
      // Resolve the latest callback at fire time, untracked — the
      // apply scope is strict-read and the callback identity isn't
      // a dependency of this effect.
      untrack(() => props.onLoadingStatusChange)?.(next);
    }
  });

  // Ensure we reset the root context status on unmount so a later remount
  // starts fresh rather than reading a stale `loaded`/`error` signal.
  onCleanup(() => {
    context.setImageLoadingStatus("idle");
  });

  // Image element signal — captured via the ref forwarded to `renderElement`
  // below. `ownedWrite` mirrors the pattern used by `useCollapsiblePanel`:
  // the ref callback fires from an unowned scope.
  const [imageElement, setImageElement] = createSignal(null, {
    ownedWrite: true
  });
  const runOnceAnimationsFinish = useAnimationsFinished(imageElement);

  // Defer the unmount until CSS transitions / animations on the image settle.
  // Mirrors React's `useOpenChangeComplete({ open: isVisible, onComplete: () =>
  // setMounted(false) })`: when `isVisible` flips false while we're still
  // mounted, wait for animations, then drop `mounted` to false so
  // `useTransitionStatus` clears `transitionStatus` back to `undefined`.
  createRenderEffect(() => isVisible(), visible => {
    if (!visible && untrack(mounted)) {
      runOnceAnimationsFinish(() => {
        setMounted(false);
      });
    }
  });
  const imageRef = el => {
    setImageElement(el);
  };
  const userStyling = resolveClassStyle(props, () => ({
    imageLoadingStatus: context.imageLoadingStatus(),
    transitionStatus: transitionStatus()
  }));
  const userHtmlProps = omit(props, "class", "style", "attrs", "as", "onLoadingStatusChange");
  const internalProps = {
    ref: imageRef,
    get "data-starting-style"() {
      return transitionStatus() === "starting" ? "" : undefined;
    },
    get "data-ending-style"() {
      return transitionStatus() === "ending" ? "" : undefined;
    }
  };
  const styledUserProps = mergeRootProps(userStyling, userHtmlProps);
  const merged = mergeRootProps(internalProps, styledUserProps);

  // Only mount the real `<img>` once our standalone probe has fired `load`
  // (matches Base UI React's `if (!mounted) return null`). Rendering the DOM
  // img during `idle`/`loading` would dispatch its own load events and flash
  // a broken-image icon before the probe settles. Staying mounted during the
  // `ending` phase lets CSS exit animations run before the node leaves the
  // tree.
  const Tag = dynamic(() => props.as ?? "img");
  return <Show when={mounted()}>
			<Tag {...merged} />
		</Show>;
}
//# sourceMappingURL=avatar-image.jsx.map
