/**
 * `<Autocomplete.Item>` — like `<Combobox.Item>` but with no `selected` state.
 */

import { dynamic } from "@solidjs/web";
import { createEffect, createMemo, omit, onCleanup, Show, untrack } from "solid-js";
import { findItemIndex } from "../../combobox/internals/item-equality.jsx";
import { useComboboxRootContext } from "../../combobox/root/combobox-root-context.jsx";
import { composeRefs, userRef } from "../../internals/compose-refs.jsx";
import { useCompositeListItem } from "../../internals/composite/composite-list.jsx";
import { mergeRootProps } from "../../internals/merge-root-props.jsx";
import { resolveClassStyle } from "../../internals/resolve-class-style.jsx";
import { useButton } from "../../internals/use-button/use-button.jsx";
/**
 * An individual item in the list. Renders a `<div>` with `role="option"`.
 */
export function AutocompleteItem(props) {
  const root = useComboboxRootContext();
  const itemValue = () => props.value ?? null;
  const disabled = () => props.disabled ?? false;
  const nativeButton = () => props.nativeButton ?? false;
  const listItem = useCompositeListItem();
  const hasItems = () => root.items() !== undefined;
  const resolvedIndex = createMemo(() => {
    if (props.index != null) return props.index;
    if (hasItems()) {
      const iv = itemValue();
      if (iv == null) return -1;
      return findItemIndex(root.flatFilteredItems(), iv, root.isItemEqualToValue());
    }
    return listItem.index();
  });
  const highlighted = createMemo(() => root.activeIndex() === resolvedIndex() && resolvedIndex() !== -1);
  let itemRef = null;
  createEffect(() => ({
    has: hasItems(),
    idx: resolvedIndex(),
    iv: itemValue()
  }), ({
    has,
    idx,
    iv
  }) => {
    if (idx === -1 || iv == null) return;
    // Register the rendered node into `listRef` in BOTH modes. In
    // `items`-mode the root only SIZES `listRef` (`.length = flat.length`)
    // and never fills the nodes, so `useListNavigation`'s pointer path
    // (`listRef.indexOf(currentTarget)`) returns -1 and hover highlighting
    // is dead. Keyboard nav is unaffected (it drives `activeIndex`
    // numerically). The `valuesRef` / `allValuesRef` bookkeeping below
    // stays items-mode-excluded — the root owns it from the items list.
    if (itemRef) root.listRef.current[idx] = itemRef;
    if (has) return;
    const list = root.valuesRef.current;
    list[idx] = iv;
    if (!root.allValuesRef.current.includes(iv)) {
      root.allValuesRef.current.push(iv);
    }
  });
  onCleanup(() => {
    const idx = resolvedIndex();
    if (idx === -1) return;
    if (root.listRef.current[idx] === itemRef) {
      delete root.listRef.current[idx];
    }
    if (!hasItems()) {
      delete root.valuesRef.current[idx];
    }
  });
  const id = createMemo(() => {
    const rid = root.id();
    const idx = resolvedIndex();
    if (rid == null || idx === -1) return undefined;
    return `${rid}-${idx}`;
  });
  const state = createMemo(() => ({
    disabled: disabled(),
    highlighted: highlighted()
  }));
  const {
    ref: buttonRef
  } = useButton({
    disabled,
    focusableWhenDisabled: () => true,
    native: nativeButton,
    composite: true
  });
  function onPointerDown(event) {
    event.preventDefault();
  }
  function onMouseDown(event) {
    event.preventDefault();
  }
  function onClick(event) {
    if (disabled() || root.readOnly()) return;
    const iv = itemValue();
    if (iv == null) return;
    root.handleSelection(event, iv);
  }
  const internal = {
    role: "option",
    get id() {
      return id() ?? "";
    },
    onPointerDown,
    onMouseDown,
    onClick,
    // itemStateAttributesMapping projection.
    get "data-highlighted"() {
      return state().highlighted ? "" : undefined;
    },
    get "data-disabled"() {
      return state().disabled ? "" : undefined;
    }
  };
  const userClassStyle = resolveClassStyle(props, () => state());
  const userProps = omit(props, "as", "class", "style", "attrs", "value", "index", "disabled", "nativeButton");

  // `getItemProps` resolves the interaction `item` bags eagerly (the `useRole`
  // item callback reads `active` synchronously). It only feeds an unused
  // `-fui-option` id here, so this is a one-shot snapshot — untrack the read
  // to avoid `[STRICT_READ_UNTRACKED]`.
  let merged = mergeRootProps(untrack(() => root.interactions.getItemProps({
    get active() {
      return highlighted();
    },
    selected: false
  })), internal);
  merged = mergeRootProps(merged, userClassStyle);
  merged = mergeRootProps(merged, userProps);

  // In items-mode an item is visible iff it survived filtering
  // (`resolvedIndex() !== -1`). In static-children mode there is no
  // `flatFilteredItems`, so the item filters itself against the live query via
  // `root.matchesQuery` (mode-aware: `inline` / `none` keep all items visible).
  const visible = createMemo(() => {
    if (hasItems()) return resolvedIndex() !== -1;
    const iv = itemValue();
    if (iv == null) return true;
    return root.matchesQuery(iv);
  });

  // Report live visibility so `<Autocomplete.Empty>` / `<Autocomplete.List>`
  // can reflect the count of matching static children. Inert in items-mode
  // (always reports `false`; empty derives from `flatFilteredItems` there).
  const visibilityToken = Symbol("autocomplete-item-visible");
  createEffect(() => hasItems() ? false : visible(), reportVisible => {
    root.setItemVisible(visibilityToken, reportVisible);
  });
  onCleanup(() => {
    root.setItemVisible(visibilityToken, false);
  });
  const Tag = dynamic(() => props.as ?? "div");
  return <Show when={visible()}>
			<Tag {...merged} ref={composeRefs(buttonRef, listItem.ref, el => {
      itemRef = el;
    }, userRef(props))} />
		</Show>;
}
//# sourceMappingURL=autocomplete-item.jsx.map
