import { jsxs, jsx } from 'react/jsx-runtime';
import { useId, useRef, useMemo, useState, useLayoutEffect, isValidElement } from 'react';
import { c as cx } from './index-De1g9FRV.js';
import { S as SvgClose } from './close-DZj38AEh.js';
import { S as SvgChevronRight } from './chevron_right-BdpsxX7x.js';
import { B as Button } from './Button-BNzCI47m.js';
import { C as Chip } from './Chip-CxgryK86.js';
import { F as Flex } from './Flex-Bb3iHExM.js';
import { F as FieldLabel } from './FieldLabel-Cm5A1Jcx.js';
import { w as warnDeprecatedErrorUsage } from './utils-CM48ODEJ.js';
import { s as styles } from './SelectTriggerBase.module-Brmw1nYG.js';
import { H as Helper } from './Helper-B_VAFgGd.js';

const ADD_NEW = Symbol.for("add-new");
const SELECT_ALL = Symbol.for("select-all");
const defaultItemToString = function(item) {
  return item != null ? String(item) : "";
};
const defaultItemToKey = function(item) {
  return item;
};
function isMultiple(props) {
  return Object.hasOwn(props, "multiple") && props.multiple === true;
}
function getScrollParent(node) {
  if (node == null) {
    return null;
  }
  if (node.scrollHeight > node.clientHeight) {
    return node;
  } else {
    if (node.parentNode instanceof HTMLElement) {
      return getScrollParent(node.parentNode);
    }
    return null;
  }
}

const COLLAPSE_SEARCH_ITERATION_MARGIN = 4;
function getDoneCollapseSearchState(key, collapsedChips = false, visibleChipsCount = null) {
  return {
    status: "done",
    key,
    collapsedChips,
    visibleChipsCount,
    low: 0,
    high: 0,
    candidate: null,
    bestFit: visibleChipsCount,
    iterations: 0
  };
}
function getMaxCollapseSearchIterations(selectedItemsCount) {
  return Math.ceil(Math.log2(Math.max(selectedItemsCount, 2))) + COLLAPSE_SEARCH_ITERATION_MARGIN;
}
const FNV_1A_OFFSET_BASIS = 2166136261;
const FNV_1A_PRIME = 16777619;
function addByteToCollapseHash(hash, byte) {
  return Math.imul(hash ^ byte, FNV_1A_PRIME) >>> 0;
}
function addNumberToCollapseHash(hash, value) {
  let nextHash = hash;
  nextHash = addByteToCollapseHash(nextHash, value & 255);
  nextHash = addByteToCollapseHash(nextHash, value >>> 8 & 255);
  nextHash = addByteToCollapseHash(nextHash, value >>> 16 & 255);
  nextHash = addByteToCollapseHash(nextHash, value >>> 24 & 255);
  return nextHash;
}
function addLabelToCollapseHash(hash, label) {
  let nextHash = addNumberToCollapseHash(hash, label.length);
  for (let index = 0; index < label.length; index += 1) {
    const codeUnit = label.charCodeAt(index);
    nextHash = addByteToCollapseHash(nextHash, codeUnit & 255);
    nextHash = addByteToCollapseHash(nextHash, codeUnit >>> 8);
  }
  return nextHash;
}
function getCollapseKey(maxRows, selectedItems, itemToString) {
  if (maxRows === void 0) return null;
  let selectedItemsHash = FNV_1A_OFFSET_BASIS;
  for (const item of selectedItems) {
    selectedItemsHash = addLabelToCollapseHash(
      selectedItemsHash,
      itemToString(item)
    );
  }
  return `${maxRows}:${selectedItems.length}:${selectedItemsHash.toString(36)}`;
}
function getCollapseSearchCandidate(low, high) {
  return Math.floor((low + high) / 2);
}
function mergeChipProps(...propSets) {
  const merged = propSets.reduce(
    (acc, props) => ({ ...acc, ...props }),
    {}
  );
  return merged;
}
const SelectTriggerBase = function({
  className,
  label,
  size,
  error,
  hint,
  description,
  prefix,
  suffix,
  maxRows,
  selectedItemProps = (_item, _index) => ({}),
  disabled,
  readOnly,
  /** ======== */
  disableClearSelection,
  itemToString: itemToStringProp,
  selectedItem,
  selectedItems,
  removeSelectedItem,
  inputValue,
  referenceRef,
  /** ======== */
  variant = "select",
  onClearButtonClick,
  labelProps,
  inputWrapperProps = {},
  toggleButtonProps = {},
  inputProps = {},
  chipProps = (_item, _index) => ({}),
  disableToggleButton = false,
  warning,
  placeholder,
  ...rest
}) {
  const itemToString = itemToStringProp ?? defaultItemToString;
  const ComboboxTriggerClassNames = cx(styles["search-field"], {
    [styles["select"]]: variant === "select"
  });
  const noClearButton = disabled || readOnly || disableClearSelection;
  const ComboboxInputWrapperClassNames = cx(
    styles["input-wrapper"],
    className ? {
      [className]: variant === "select"
    } : {},
    {
      [styles["small"]]: size === "small",
      [styles["large"]]: size === "large",
      [styles["no-clear-button"]]: noClearButton,
      [styles["no-toggle-button"]]: disableToggleButton
    }
  );
  const ComboboxInputClassNames = cx(
    styles["input"],
    className ? {
      [className]: variant === "combobox"
    } : {},
    {
      [styles["error"]]: error
    }
  );
  const helperUid = "helper" + useId();
  const placeholderUid = "placeholder" + useId();
  const ariaDescribedBy = `${helperUid} ${placeholderUid}`;
  warnDeprecatedErrorUsage("SelectTrigger", error);
  const errorMessages = typeof error === "boolean" || error === void 0 ? void 0 : error;
  const rowsRef = useRef(null);
  const collapseKey = useMemo(
    () => getCollapseKey(maxRows, selectedItems, itemToString),
    [maxRows, selectedItems, itemToString]
  );
  const [collapseSearch, setCollapseSearch] = useState(
    () => getDoneCollapseSearchState(null)
  );
  const stillCalculating = collapseSearch.status !== "done";
  useLayoutEffect(() => {
    if (maxRows === void 0) {
      if (collapseSearch.status !== "done" || collapseSearch.collapsedChips || collapseSearch.visibleChipsCount !== null || collapseSearch.key !== null) {
        setCollapseSearch(getDoneCollapseSearchState(null));
      }
      return;
    }
    if (collapseSearch.key !== collapseKey) {
      setCollapseSearch({
        status: "measuring",
        key: collapseKey,
        collapsedChips: false,
        visibleChipsCount: null,
        low: 0,
        high: Math.max(selectedItems.length - 1, 0),
        candidate: null,
        bestFit: null,
        iterations: 0
      });
      return;
    }
    if (collapseSearch.status === "done") return;
    if (rowsRef?.current?.children) {
      const children = rowsRef?.current?.children;
      const chipChildren = Array.from(children).filter(
        (child) => !child.classList?.contains(styles["input-flex"])
      );
      const rowData = chipChildren.reduce(
        (acc, child) => {
          const top = child.getBoundingClientRect().top;
          if (!acc.length) {
            return [{ count: 1, top }];
          } else if (acc[acc.length - 1].top === top) {
            return [
              ...acc.slice(0, -1),
              { count: acc[acc.length - 1].count + 1, top }
            ];
          } else if (acc[acc.length - 1].top !== top) {
            return [...acc, { count: 1, top }];
          } else {
            return acc;
          }
        },
        []
      );
      const fitsWithinMaxRows = !rowData[maxRows];
      if (collapseSearch.status === "measuring") {
        if (fitsWithinMaxRows || selectedItems.length === 1) {
          setCollapseSearch(getDoneCollapseSearchState(collapseKey));
          return;
        }
        const quickGuess = Math.max(
          rowData.slice(0, maxRows).reduce((sum, row) => sum + row.count, -1),
          0
        );
        setCollapseSearch({
          status: "searching",
          key: collapseKey,
          collapsedChips: true,
          visibleChipsCount: quickGuess,
          low: 0,
          high: Math.max(selectedItems.length - 1, 0),
          candidate: quickGuess,
          bestFit: null,
          iterations: 0
        });
        return;
      }
      if (collapseSearch.candidate === null) return;
      const iterations = collapseSearch.iterations + 1;
      const bestFit = fitsWithinMaxRows ? collapseSearch.candidate : collapseSearch.bestFit;
      const low = fitsWithinMaxRows ? collapseSearch.candidate + 1 : collapseSearch.low;
      const high = fitsWithinMaxRows ? collapseSearch.high : collapseSearch.candidate - 1;
      const maxIterations = getMaxCollapseSearchIterations(
        selectedItems.length
      );
      if (low > high || iterations >= maxIterations) {
        setCollapseSearch(
          getDoneCollapseSearchState(collapseKey, true, bestFit ?? 0)
        );
        return;
      }
      const candidate = getCollapseSearchCandidate(low, high);
      setCollapseSearch({
        status: "searching",
        key: collapseKey,
        collapsedChips: true,
        visibleChipsCount: candidate,
        low,
        high,
        candidate,
        bestFit,
        iterations
      });
    }
  }, [collapseKey, collapseSearch, maxRows, selectedItems.length]);
  const selectedItemsDisplayCount = collapseSearch.collapsedChips && maxRows != null && collapseSearch.visibleChipsCount !== null ? collapseSearch.visibleChipsCount : selectedItems.length;
  return /* @__PURE__ */ jsxs("div", { ...rest, className: ComboboxTriggerClassNames, ref: referenceRef, children: [
    label ? /* @__PURE__ */ jsx(
      FieldLabel,
      {
        ...labelProps,
        className: cx(styles["label"], labelProps?.className),
        children: label
      }
    ) : null,
    /* @__PURE__ */ jsxs(
      "div",
      {
        ...inputWrapperProps,
        className: ComboboxInputWrapperClassNames,
        ...variant === "select" ? {
          "aria-describedby": ariaDescribedBy,
          "aria-labelledby": labelProps?.id
        } : {},
        children: [
          /* @__PURE__ */ jsxs("div", { className: styles["buttons-wrapper"], children: [
            (inputValue || selectedItem || selectedItems.length) && !noClearButton ? /* @__PURE__ */ jsx("div", { className: styles["close-button-wrapper"], children: /* @__PURE__ */ jsx(
              Button,
              {
                "aria-label": "clear selection",
                appearance: "ghost",
                size: "small",
                icon: SvgClose,
                className: styles["close-button"],
                onClick: (e) => {
                  e.stopPropagation();
                  onClearButtonClick?.(e);
                },
                tabIndex: -1
              }
            ) }) : null,
            disableToggleButton ? null : /* @__PURE__ */ jsx("div", { className: styles["toggle-button-wrapper"], children: /* @__PURE__ */ jsx(
              Button,
              {
                ...toggleButtonProps,
                ...variant === "select" ? { tabIndex: -1, inert: "true" } : {},
                className: styles["toggle-button"],
                "aria-label": "toggle menu",
                icon: SvgChevronRight,
                appearance: "ghost",
                size: "small",
                disabled
              }
            ) })
          ] }),
          /* @__PURE__ */ jsx("div", { className: styles["prefix-wrapper"], children: prefix ? /* @__PURE__ */ jsx("div", { className: styles["prefix"], children: prefix }) : null }),
          /* @__PURE__ */ jsxs(
            "div",
            {
              className: cx(styles["rows-wrapper"], {
                [styles["max-rows"]]: maxRows !== void 0,
                [styles["single-row"]]: maxRows === 1 && !stillCalculating
              }),
              ref: rowsRef,
              children: [
                selectedItems.length && removeSelectedItem != null ? selectedItems.slice(0, selectedItemsDisplayCount).map((item, index) => {
                  return /* @__PURE__ */ jsx(
                    "div",
                    {
                      className: styles["chip-wrapper"],
                      children: /* @__PURE__ */ jsx(
                        Chip,
                        {
                          ...mergeChipProps(
                            chipProps(item, index),
                            selectedItemProps(item, index),
                            {
                              label: itemToString(item),
                              onClose: disabled || readOnly ? void 0 : (_e) => {
                                removeSelectedItem(item);
                              },
                              className: styles["chip"],
                              title: itemToString(item)
                            }
                          )
                        }
                      )
                    },
                    `selected-item-${index}`
                  );
                }) : null,
                collapseSearch.collapsedChips && maxRows != null ? /* @__PURE__ */ jsx("div", { className: styles["chip-wrapper"], children: /* @__PURE__ */ jsx(
                  Chip,
                  {
                    label: `+${selectedItems.length - selectedItemsDisplayCount}`,
                    className: styles["chip"],
                    title: selectedItems.slice(selectedItemsDisplayCount).map((item) => itemToString(item)).join(", ")
                  }
                ) }) : null,
                /* @__PURE__ */ jsxs(Flex, { className: styles["input-flex"], alignItems: "center", children: [
                  variant === "select" ? /* @__PURE__ */ jsx(
                    "div",
                    {
                      ...inputProps,
                      className: cx(ComboboxInputClassNames, inputProps.className),
                      children: selectedItems.length ? null : selectedItem ? itemToString(selectedItem) : /* @__PURE__ */ jsx(
                        "span",
                        {
                          className: styles["fake-placeholder"],
                          id: placeholderUid,
                          children: placeholder
                        }
                      )
                    }
                  ) : /* @__PURE__ */ jsx(
                    "input",
                    {
                      type: "text",
                      ...inputProps,
                      placeholder,
                      className: cx(ComboboxInputClassNames, inputProps.className),
                      ...inputProps["aria-expanded"] != null && inputProps["aria-controls"] != null ? {
                        role: "combobox"
                      } : {}
                    }
                  ),
                  suffix ? /* @__PURE__ */ jsx("div", { className: styles["suffix"], children: suffix }) : null
                ] })
              ]
            }
          )
        ]
      }
    ),
    hint || errorMessages || warning || description ? /* @__PURE__ */ jsx(
      Helper,
      {
        id: helperUid,
        error: typeof errorMessages === "string" || Array.isArray(errorMessages) ? errorMessages : void 0,
        warning,
        errorMessage: isValidElement(errorMessages) ? errorMessages : void 0,
        hint,
        description
      }
    ) : null
  ] });
};

export { ADD_NEW as A, SelectTriggerBase as S, defaultItemToKey as a, SELECT_ALL as b, defaultItemToString as d, getScrollParent as g, isMultiple as i };
//# sourceMappingURL=SelectTriggerBase-lYieONTb.js.map
