import {
  ScrollArea
} from "./chunk-ZKZDVS7G.js";
import {
  Popover
} from "./chunk-5AVBYDPB.js";
import {
  Grid
} from "./chunk-EGEQY3KT.js";
import {
  Typo
} from "./chunk-52MVZ6AN.js";
import {
  Flex
} from "./chunk-25HMMI7R.js";
import {
  Button
} from "./chunk-U7JPP7WJ.js";
import {
  AutoSizingInput
} from "./chunk-YJCCE5WP.js";
import {
  Badge
} from "./chunk-EWD4AO5N.js";
import {
  CheckIcon
} from "./chunk-OXXF2CUB.js";

// src/molecules/tag-selector.tsx
import {
  useCallback,
  useEffect,
  useMemo,
  useRef,
  useState
} from "react";
import {
  ChevronRightIcon,
  Cross1Icon,
  MagnifyingGlassIcon
} from "@radix-ui/react-icons";
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
var OPTION_HEIGHT = 32;
var DefaultDropdownContainer = (props) => {
  return props.children;
};
function TagSelector(props) {
  const {
    options = [],
    tagRender,
    placeholder,
    maxCount = 0,
    DropdownContainer = DefaultDropdownContainer,
    size = "medium",
    readOnly,
    error
  } = props;
  const [_selected, _setSelected] = useState(props.selected || []);
  const selected = props.selected || _selected;
  const setSelected = props.onChange || _setSelected;
  const [value, setValue] = useState("");
  const [focusIndex, setFocusIndex] = useState(null);
  const [open, setOpen] = useState(false);
  const [focus, setFocus] = useState(false);
  const fieldRef = useRef(null);
  const scrollRef = useRef(null);
  const closeRef = useRef();
  const onFocus = useCallback(() => {
    clearTimeout(closeRef.current);
    setFocus(true);
    setOpen(true);
  }, []);
  const onBlur = useCallback(() => {
    closeRef.current = setTimeout(() => {
      setFocus(false);
      setOpen(false);
      setTimeout(() => {
        setValue("");
      }, 100);
    }, 300);
  }, []);
  const onChangeValue = useCallback(
    (e) => {
      setValue(e.target.value);
    },
    []
  );
  const filteredOptions = useMemo(() => {
    return options.filter((option) => {
      return option.name.includes(value);
    });
  }, [options, value]);
  const selectedItem = useMemo(() => {
    const result = [];
    selected.forEach((id) => {
      const maybeItem = options.find((option) => option.id === id);
      if (maybeItem)
        result.push(maybeItem);
    });
    return result;
  }, [options, selected]);
  const onDelete = useCallback(
    (id) => {
      setSelected(selected.filter((el) => el !== id));
    },
    [selected, setSelected]
  );
  const onSelect = useCallback(
    (id) => {
      if (maxCount && selected.length + 1 > maxCount)
        return;
      setSelected([...selected, id]);
    },
    [maxCount, selected, setSelected]
  );
  const toggleItem = useCallback(
    (id) => {
      if (selected.includes(id)) {
        onDelete(id);
      } else {
        onSelect(id);
      }
    },
    [onDelete, onSelect, selected]
  );
  const setScroll = useCallback((index) => {
    if (scrollRef.current) {
      const scrollTop = scrollRef.current.scrollTop;
      const clientHeight = scrollRef.current.clientHeight;
      const focusTop = index * OPTION_HEIGHT;
      if (focusTop < scrollTop) {
        scrollRef.current.scrollTop = focusTop;
      } else if (focusTop + OPTION_HEIGHT > scrollTop + clientHeight) {
        scrollRef.current.scrollTop = focusTop + OPTION_HEIGHT - clientHeight;
      }
    }
  }, []);
  const handleKeyDown = useCallback(
    (e) => {
      var _a;
      const key = e.key;
      switch (key) {
        case "ArrowDown": {
          e.preventDefault();
          let newFocus = 0;
          if (typeof focusIndex === "number") {
            newFocus = focusIndex + 1 >= options.length ? 0 : focusIndex + 1;
          }
          setFocusIndex(newFocus);
          setScroll(newFocus);
          break;
        }
        case "ArrowUp": {
          e.preventDefault();
          let newFocus = 0;
          if (typeof focusIndex === "number") {
            newFocus = focusIndex - 1 < 0 ? options.length - 1 : focusIndex - 1;
          }
          setFocusIndex(newFocus);
          setScroll(newFocus);
          break;
        }
        case "Enter":
          setValue("");
          if (focusIndex !== null) {
            toggleItem((_a = filteredOptions[focusIndex]) == null ? void 0 : _a.id);
          }
          break;
        case "Backspace":
          if (value.length === 0) {
            setSelected(selected.slice(0, -1));
          }
          break;
        case "Escape":
          setOpen(false);
          break;
      }
    },
    [
      focusIndex,
      value.length,
      setScroll,
      options.length,
      toggleItem,
      filteredOptions,
      setSelected,
      selected
    ]
  );
  const placeholderVisible = useMemo(() => {
    if (selectedItem.length)
      return false;
    if (value)
      return false;
    if (focus)
      return false;
    return true;
  }, [focus, selectedItem.length, value]);
  useEffect(() => {
    setFocusIndex(null);
  }, [open]);
  useEffect(() => {
    setFocusIndex(0);
  }, [filteredOptions]);
  const badgeSize = useMemo(() => {
    switch (size) {
      case "large":
        return "large";
      case "medium":
      case "small":
      default:
        return "small";
    }
  }, [size]);
  const placeholderVariant = useMemo(() => {
    switch (size) {
      case "large":
        return "subtitle";
      case "medium":
      default:
        return "body";
    }
  }, [size]);
  const focusClassName = focus ? " focused" : "";
  const readOnlyClassName = readOnly ? " read-only" : "";
  const errorClassName = error ? " error" : "";
  const readonlyContent = /* @__PURE__ */ jsx(Flex, { gap: "1", children: selectedItem.map((item) => {
    return tagRender ? tagRender(item) : /* @__PURE__ */ jsx(Badge, { size: badgeSize, children: item.name }, item.id);
  }) });
  const editContent = /* @__PURE__ */ jsxs(Fragment, { children: [
    /* @__PURE__ */ jsxs(
      Flex,
      {
        align: "center",
        gap: "1",
        maxWidth: "100%",
        overflow: "hidden",
        wrap: "wrap",
        children: [
          selectedItem.map((item) => {
            return tagRender ? tagRender(item) : /* @__PURE__ */ jsxs(Badge, { size: badgeSize, children: [
              item.name,
              /* @__PURE__ */ jsx(
                Button,
                {
                  onClick: () => {
                    onDelete(item.id);
                  },
                  variant: "transparent",
                  children: /* @__PURE__ */ jsx(Cross1Icon, {})
                }
              )
            ] }, item.id);
          }),
          placeholderVisible ? /* @__PURE__ */ jsx(Typo, { color: "gray", variant: placeholderVariant, children: placeholder }) : null,
          /* @__PURE__ */ jsx(
            AutoSizingInput,
            {
              onBlur,
              onChange: onChangeValue,
              onFocus,
              onKeyDown: handleKeyDown,
              ref: fieldRef,
              value
            }
          )
        ]
      }
    ),
    focus ? /* @__PURE__ */ jsx(MagnifyingGlassIcon, {}) : /* @__PURE__ */ jsx(ChevronRightIcon, {})
  ] });
  return /* @__PURE__ */ jsxs(Popover.Root, { open: Boolean(filteredOptions.length) && open, children: [
    /* @__PURE__ */ jsx(Popover.Trigger, { style: { position: "relative" }, children: /* @__PURE__ */ jsx(
      Grid,
      {
        align: "center",
        className: `tag-selector ${size} ${focusClassName}${readOnlyClassName}${errorClassName}`,
        columns: "1fr auto",
        gap: "1",
        onClick: () => {
          var _a;
          return !readOnly && ((_a = fieldRef.current) == null ? void 0 : _a.focus());
        },
        children: readOnly ? readonlyContent : editContent
      }
    ) }),
    /* @__PURE__ */ jsx(
      Popover.Content,
      {
        onOpenAutoFocus: (e) => {
          e.preventDefault();
        },
        children: /* @__PURE__ */ jsx(
          DropdownContainer,
          {
            currentItem: filteredOptions[focusIndex || 0],
            items: filteredOptions,
            children: /* @__PURE__ */ jsx(
              ScrollArea,
              {
                ref: scrollRef,
                scrollbars: "vertical",
                style: { height: OPTION_HEIGHT * 8 },
                type: "auto",
                children: /* @__PURE__ */ jsx(Flex, { direction: "column", children: filteredOptions.map((item, i) => {
                  const isSelected = Boolean(
                    selected.find((el) => el === item.id)
                  );
                  const isFocus = i === focusIndex;
                  return /* @__PURE__ */ jsx(
                    Button,
                    {
                      className: `tag-selector-button ${isFocus ? "focus" : ""}`,
                      onClick: () => {
                        var _a;
                        toggleItem(item.id);
                        (_a = fieldRef.current) == null ? void 0 : _a.focus();
                      },
                      onMouseEnter: () => {
                        setFocusIndex(i);
                      },
                      style: {
                        width: "100%",
                        background: isFocus ? "var(--accent-a3)" : void 0,
                        color: "var(--gray-12)",
                        fontWeight: 400,
                        boxShadow: "none"
                      },
                      variant: isSelected ? "soft" : "outline",
                      children: /* @__PURE__ */ jsxs(Flex, { justify: "between", width: "100%", children: [
                        item.name,
                        isSelected ? /* @__PURE__ */ jsx(CheckIcon, {}) : null
                      ] })
                    },
                    item.id
                  );
                }) })
              }
            )
          }
        )
      }
    )
  ] });
}

export {
  TagSelector
};
//# sourceMappingURL=chunk-I6ZXMXVT.js.map