"use client";
import * as React from "react";
import * as ReactDOM from "react-dom";
import { useIsoLayoutEffect } from "../../../../utils/esm/useIsoLayoutEffect.js";
import { useComboboxRootContext, useComboboxDerivedItemsContext } from "../root/ComboboxRootContext.js";
import { useCompositeListItem, IndexGuessBehavior } from "../../composite/list/useCompositeListItem.js";
import { useRenderElement } from "../../utils/useRenderElement.js";
import { ComboboxItemContext } from "./ComboboxItemContext.js";
import { selectors } from "../store.js";
import { useComboboxRowContext } from "../row/ComboboxRowContext.js";
import { findItemIndex, compareItemEquality } from "../../utils/itemEquality.js";
import { jsx } from "react/jsx-runtime";
import { useButton } from "../../use-button/useButton.js";
import { useStore } from "../../../../utils/esm/store/useStore.js";
const ComboboxItem = /* @__PURE__ */ React.memo(/* @__PURE__ */ React.forwardRef(function ComboboxItem2(componentProps, forwardedRef) {
  const {
    render,
    className,
    value = null,
    index: indexProp,
    disabled = false,
    nativeButton = false,
    ...elementProps
  } = componentProps;
  const didPointerDownRef = React.useRef(false);
  const textRef = React.useRef(null);
  const listItem = useCompositeListItem({
    index: indexProp,
    textRef,
    indexGuessBehavior: IndexGuessBehavior.GuessFromOrder
  });
  const store = useComboboxRootContext();
  const isRow = useComboboxRowContext();
  const {
    flatFilteredItems
  } = useComboboxDerivedItemsContext();
  const open = useStore(store, selectors.open);
  const selectionMode = useStore(store, selectors.selectionMode);
  const readOnly = useStore(store, selectors.readOnly);
  const virtualized = useStore(store, selectors.virtualized);
  const isItemEqualToValue = useStore(store, selectors.isItemEqualToValue);
  const selectable = selectionMode !== "none";
  const index = indexProp ?? (virtualized ? findItemIndex(flatFilteredItems, value, isItemEqualToValue) : listItem.index);
  const hasRegistered = listItem.index !== -1;
  const rootId = useStore(store, selectors.id);
  const highlighted = useStore(store, selectors.isActive, index);
  const matchesSelectedValue = useStore(store, selectors.isSelected, value);
  const items = useStore(store, selectors.items);
  const getItemProps = useStore(store, selectors.getItemProps);
  const itemRef = React.useRef(null);
  const id = rootId != null && hasRegistered ? `${rootId}-${index}` : void 0;
  const selected = matchesSelectedValue && selectable;
  useIsoLayoutEffect(() => {
    const shouldRun = hasRegistered && (virtualized || indexProp != null);
    if (!shouldRun) {
      return void 0;
    }
    const list = store.state.listRef.current;
    list[index] = itemRef.current;
    return () => {
      delete list[index];
    };
  }, [hasRegistered, virtualized, index, indexProp, store]);
  useIsoLayoutEffect(() => {
    if (!hasRegistered || items) {
      return void 0;
    }
    const visibleMap = store.state.valuesRef.current;
    visibleMap[index] = value;
    if (selectionMode !== "none") {
      store.state.allValuesRef.current.push(value);
    }
    return () => {
      delete visibleMap[index];
    };
  }, [hasRegistered, items, index, value, store, selectionMode]);
  useIsoLayoutEffect(() => {
    if (!open) {
      didPointerDownRef.current = false;
      return;
    }
    if (!hasRegistered || items) {
      return;
    }
    const selectedValue = store.state.selectedValue;
    const lastSelectedValue = Array.isArray(selectedValue) ? selectedValue[selectedValue.length - 1] : selectedValue;
    if (compareItemEquality(lastSelectedValue, value, isItemEqualToValue)) {
      store.set("selectedIndex", index);
    }
  }, [hasRegistered, items, open, store, index, value, isItemEqualToValue]);
  const state = React.useMemo(() => ({
    disabled,
    selected,
    highlighted
  }), [disabled, selected, highlighted]);
  const rootProps = getItemProps({
    active: highlighted,
    selected
  });
  rootProps.id = void 0;
  rootProps.onFocus = void 0;
  const {
    getButtonProps,
    buttonRef
  } = useButton({
    disabled,
    focusableWhenDisabled: true,
    native: nativeButton
  });
  function commitSelection(nativeEvent) {
    function selectItem() {
      store.state.handleSelection(nativeEvent, value);
    }
    if (store.state.submitOnItemClick) {
      ReactDOM.flushSync(selectItem);
      store.state.requestSubmit();
    } else {
      selectItem();
    }
  }
  const defaultProps = {
    id,
    role: isRow ? "gridcell" : "option",
    "aria-disabled": disabled || void 0,
    "aria-selected": selectable ? selected : void 0,
    // Focusable items steal focus from the input upon mouseup.
    // Warn if the user renders a natively focusable element like `<button>`,
    // as it should be a `<div>` instead.
    tabIndex: void 0,
    onPointerDownCapture(event) {
      didPointerDownRef.current = true;
      event.preventDefault();
    },
    onClick(event) {
      if (disabled || readOnly) {
        return;
      }
      commitSelection(event.nativeEvent);
    },
    onMouseUp(event) {
      const pointerStartedOnItem = didPointerDownRef.current;
      didPointerDownRef.current = false;
      if (disabled || readOnly || event.button !== 0 || pointerStartedOnItem || !highlighted) {
        return;
      }
      commitSelection(event.nativeEvent);
    }
  };
  const element = useRenderElement("div", componentProps, {
    ref: [buttonRef, forwardedRef, listItem.ref, itemRef],
    state,
    props: [rootProps, defaultProps, elementProps, getButtonProps]
  });
  const contextValue = React.useMemo(() => ({
    selected,
    textRef
  }), [selected, textRef]);
  return /* @__PURE__ */ jsx(ComboboxItemContext.Provider, {
    value: contextValue,
    children: element
  });
}));
if (process.env.NODE_ENV !== "production") ComboboxItem.displayName = "ComboboxItem";
export {
  ComboboxItem
};
//# sourceMappingURL=ComboboxItem.js.map
