import { dynamic } from "@solidjs/web";
import { createEffect, createMemo, omit, onCleanup, untrack } from "solid-js";
import { createChangeEventDetails, REASONS } from "../../internals/change-event-details.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";
import { useSelectRootContext } from "../select-root-context.jsx";
import { compareItemEquality, removeItem } from "../utils/item-equality.jsx";
import { SelectItemContext } from "./select-item-context.jsx";
export function SelectItem(props) {
  const root = useSelectRootContext();
  const itemValue = () => "value" in props ? props.value : null;
  const disabled = () => props.disabled ?? false;
  const nativeButton = () => props.nativeButton ?? false;
  const textRef = {
    current: null
  };
  const listItem = useCompositeListItem({
    label: props.label,
    textRef
  });
  const hasRegistered = createMemo(() => listItem.index() !== -1);
  createEffect(() => ({
    idx: listItem.index(),
    value: itemValue()
  }), ({
    idx,
    value
  }) => {
    if (idx === -1) return;
    const values = root.valuesRef.current;
    values[idx] = value;
  });
  onCleanup(() => {
    const idx = listItem.index();
    if (idx !== -1) {
      delete root.valuesRef.current[idx];
    }
  });
  createEffect(() => ({
    idx: listItem.index(),
    value: itemValue(),
    storeValue: root.value(),
    equals: root.isItemEqualToValue()
  }), ({
    idx,
    value,
    storeValue,
    equals
  }) => {
    if (idx === -1) return;
    let candidate = storeValue;
    if (root.multiple() && Array.isArray(storeValue) && storeValue.length > 0) {
      candidate = storeValue[storeValue.length - 1];
    }
    if (candidate !== undefined && compareItemEquality(value, candidate, equals)) {
      root.setSelectedIndex(idx);
      if (textRef.current) {
        root.selectedItemTextRef.current = textRef.current;
      }
    }
  });
  const highlighted = createMemo(() => root.activeIndex() === listItem.index());

  // P8: value-based equality for selected state.
  const selected = createMemo(() => {
    const comparer = root.isItemEqualToValue();
    const storeValue = root.value();
    const iv = itemValue();
    if (root.multiple()) {
      return Array.isArray(storeValue) && storeValue.some(sv => compareItemEquality(iv, sv, comparer));
    }
    return compareItemEquality(iv, storeValue, comparer);
  });
  const selectedByFocus = createMemo(() => root.selectedIndex() === listItem.index());
  const indexRef = {
    current: -1
  };
  createEffect(() => listItem.index(), i => {
    indexRef.current = i;
  });
  const {
    props: buttonProps,
    ref: buttonRef
  } = useButton({
    disabled,
    focusableWhenDisabled: () => true,
    native: nativeButton
  });
  function commitSelection(event) {
    const storeValue = root.value();
    if (root.multiple()) {
      const currentValue = Array.isArray(storeValue) ? storeValue : [];
      const nextValue = selected() ? removeItem(currentValue, itemValue(), root.isItemEqualToValue()) : [...currentValue, itemValue()];
      root.setValue(nextValue, createChangeEventDetails(REASONS.itemPress, event));
    } else {
      root.setValue(itemValue(), createChangeEventDetails(REASONS.itemPress, event));
      root.setOpen(false, createChangeEventDetails(REASONS.itemPress, event));
    }
  }
  const state = createMemo(() => ({
    disabled: disabled(),
    selected: selected(),
    highlighted: highlighted()
  }));
  let lastKey = null;
  let didPointerDown = false;
  let pointerType = null;
  const contextValue = {
    selected,
    selectedByFocus,
    hasRegistered,
    indexRef,
    textRef
  };
  const internal = {
    role: "option",
    get "aria-selected"() {
      return selected() ? "true" : "false";
    },
    get tabindex() {
      return highlighted() ? 0 : -1;
    },
    onTouchStart() {
      root.selectionRef.current = {
        allowSelectedMouseUp: false,
        allowUnselectedMouseUp: false
      };
    },
    onKeyDown(event) {
      lastKey = event.key;
      root.setActiveIndex(listItem.index());
      if (event.key === " " && root.typingRef.current) {
        event.preventDefault();
      }
    },
    onClick(event) {
      didPointerDown = false;
      if (event.type === "keydown" && lastKey === null) return;
      if (disabled()) return;
      if (event.type === "keydown" && lastKey === " " && root.typingRef.current) {
        return;
      }
      lastKey = null;
      commitSelection(event);
    },
    onPointerEnter(event) {
      pointerType = event.pointerType;
    },
    onPointerDown(event) {
      pointerType = event.pointerType;
      didPointerDown = true;
    },
    onMouseUp(event) {
      if (disabled()) return;
      if (didPointerDown) {
        didPointerDown = false;
        return;
      }
      const guard = root.selectionRef.current;
      const disallowSelectedMouseUp = !guard.allowSelectedMouseUp && selected();
      const disallowUnselectedMouseUp = !guard.allowUnselectedMouseUp && !selected();
      if (disallowSelectedMouseUp || disallowUnselectedMouseUp || pointerType !== "touch" && !highlighted()) {
        return;
      }
      const target = event.currentTarget;
      target?.click();
    },
    // Default projection: disabled/selected/highlighted → presence.
    get "data-disabled"() {
      return state().disabled ? "" : undefined;
    },
    get "data-selected"() {
      return state().selected ? "" : undefined;
    },
    get "data-highlighted"() {
      return state().highlighted ? "" : undefined;
    }
  };
  const userClassStyle = resolveClassStyle(props, () => state());
  const userProps = omit(props, "as", "class", "style", "attrs", "value", "disabled", "label", "nativeButton");

  // `getItemProps` resolves the interaction `item` bags eagerly. The
  // `active`/`selected` it consumes (via `useRole`) only feed an unused
  // `-fui-option` id and an `aria-selected` that `internal` re-provides
  // reactively below, so this is a one-shot snapshot — untrack the read to
  // avoid `[STRICT_READ_UNTRACKED]`.
  let merged = mergeRootProps(untrack(() => root.interactions.getItemProps({
    active: highlighted(),
    selected: selected()
  })), buttonProps);
  merged = mergeRootProps(merged, internal);
  merged = mergeRootProps(merged, userClassStyle);
  merged = mergeRootProps(merged, userProps);
  const Tag = dynamic(() => props.as ?? "div");
  return <SelectItemContext value={contextValue}>
			<Tag {...merged} ref={composeRefs(buttonRef, listItem.ref, userRef(props))} />
		</SelectItemContext>;
}
//# sourceMappingURL=select-item.jsx.map
