import { dynamic } from "@solidjs/web";
import { createMemo, omit } from "solid-js";
import { createChangeEventDetails, REASONS } from "../../internals/change-event-details.jsx";
import { composeRefs, userRef } from "../../internals/compose-refs.jsx";
import { mergeRootProps } from "../../internals/merge-root-props.jsx";
import { resolveClassStyle } from "../../internals/resolve-class-style.jsx";
import { useComboboxChipsContext } from "../chips/chips-context.jsx";
import { useComboboxRootContext } from "../root/combobox-root-context.jsx";
/**
 * A text input to search for items in the list. Renders an `<input>`.
 */
export function ComboboxInput(props) {
  const root = useComboboxRootContext();
  const chips = useComboboxChipsContext();
  const disabled = () => root.disabled() || (props.disabled ?? false);
  const readOnly = () => root.readOnly();
  const listEmpty = createMemo(() => root.flatFilteredItems().length === 0);
  const setInputRef = el => {
    root.setInputElement(el);
  };
  const state = createMemo(() => ({
    open: root.open(),
    disabled: disabled(),
    readOnly: readOnly(),
    popupSide: root.popupSide(),
    listEmpty: listEmpty()
  }));
  function onInput(event) {
    const value = event.currentTarget.value;
    const details = createChangeEventDetails(REASONS.inputChange, event);
    root.setInputValue(value, details);
    if (!readOnly() && !disabled()) {
      if (!root.open() && (value !== "" || root.openOnInputClick())) {
        root.setOpen(true, details);
      }
    }
    if (!root.autoHighlightMode()) {
      root.setIndices({
        activeIndex: null,
        type: "keyboard"
      });
    }
  }

  // Chip keyboard navigation (multi-select only). Returns `true` when the
  // event was consumed so the main handler can bail before the
  // Enter/Escape logic runs. No-op (returns `false`) when chips aren't in use.
  function handleChipKeyDown(event) {
    if (!chips) return false;
    const inputEl = event.currentTarget;
    const sv = root.selectedValue();
    const selectedArr = Array.isArray(sv) ? sv : [];
    const highlighted = chips.highlightedChipIndex();
    const renderedChips = chips.chipsRef.current.length;

    // A chip is already focused: arrow keys move between chips, stepping
    // back into the input past either end.
    if (highlighted !== undefined) {
      if (event.key === "ArrowLeft") {
        event.preventDefault();
        const next = highlighted > 0 ? highlighted - 1 : undefined;
        chips.setHighlightedChipIndex(next);
        if (next !== undefined) chips.chipsRef.current[next]?.focus();else root.inputRef.current?.focus();
        return true;
      }
      if (event.key === "ArrowRight") {
        event.preventDefault();
        const next = highlighted < renderedChips - 1 ? highlighted + 1 : undefined;
        chips.setHighlightedChipIndex(next);
        if (next !== undefined) chips.chipsRef.current[next]?.focus();else root.inputRef.current?.focus();
        return true;
      }
      return false;
    }

    // Caret at the input's start: ArrowLeft enters the chip strip.
    if (event.key === "ArrowLeft" && inputEl && (inputEl.selectionStart ?? 0) === 0 && selectedArr.length > 0) {
      event.preventDefault();
      const next = renderedChips > 0 ? renderedChips - 1 : undefined;
      chips.setHighlightedChipIndex(next);
      if (next !== undefined) chips.chipsRef.current[next]?.focus();
      return true;
    }

    // Empty input: Backspace removes the last selected chip.
    if (event.key === "Backspace" && inputEl && inputEl.value === "" && selectedArr.length > 0) {
      event.preventDefault();
      const removalIndex = renderedChips > 0 ? renderedChips - 1 : selectedArr.length - 1;
      root.setIndices({
        activeIndex: null,
        selectedIndex: null,
        type: root.keyboardActiveRef.current ? "keyboard" : "pointer"
      });
      const details = createChangeEventDetails(REASONS.none, event);
      root.setSelectedValue(selectedArr.filter((_, i) => i !== removalIndex), details);
      return true;
    }
    return false;
  }
  function onKeyDown(event) {
    if (disabled() || readOnly()) return;
    root.keyboardActiveRef.current = true;
    if (handleChipKeyDown(event)) return;
    if (event.key === "Enter" && root.open()) {
      const ai = root.activeIndex();
      if (ai == null) return;
      event.preventDefault();
      const li = root.listRef.current[ai];
      if (li) {
        li.click();
      }
      return;
    }
    if (event.key === "Escape" && !root.open() && root.selectedValue() != null && !Array.isArray(root.selectedValue())) {
      const details = createChangeEventDetails(REASONS.escapeKey, event);
      root.setInputValue("", details);
      root.setSelectedValue(null, details);
    }
  }
  function onPointerMove() {
    root.keyboardActiveRef.current = false;
  }
  function onPointerDown() {
    root.keyboardActiveRef.current = false;
  }
  const internal = {
    type: "text",
    autocomplete: "off",
    spellcheck: false,
    role: "combobox",
    "aria-autocomplete": "list",
    get "aria-expanded"() {
      return root.open() ? "true" : "false";
    },
    get "aria-haspopup"() {
      return root.grid() ? "grid" : "listbox";
    },
    get "aria-controls"() {
      return root.open() ? root.listElement()?.id ?? "" : "";
    },
    get value() {
      return root.inputValue();
    },
    get disabled() {
      return disabled();
    },
    get readOnly() {
      return readOnly();
    },
    get required() {
      return root.required();
    },
    onInput,
    onKeyDown,
    onPointerMove,
    onPointerDown,
    // inputStateAttributesMapping projection.
    get "data-popup-open"() {
      return state().open ? "" : undefined;
    },
    get "data-disabled"() {
      return state().disabled ? "" : undefined;
    },
    get "data-readonly"() {
      return state().readOnly ? "" : undefined;
    },
    get "data-list-empty"() {
      return state().listEmpty ? "" : undefined;
    },
    get "data-popup-side"() {
      return state().popupSide ?? undefined;
    }
  };
  const userClassStyle = resolveClassStyle(props, () => state());
  const userProps = omit(props, "as", "class", "style", "attrs", "disabled");
  let merged = mergeRootProps(root.interactions.getReferenceProps(), internal);
  merged = mergeRootProps(merged, userClassStyle);
  merged = mergeRootProps(merged, userProps);
  const Tag = dynamic(() => props.as ?? "input");
  return <Tag {...merged} ref={composeRefs(setInputRef, userRef(props))} />;
}
//# sourceMappingURL=combobox-input.jsx.map
