/*
 * Copyright 2025 Palantir Technologies, Inc. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import { Button } from "@base-ui/react/button";
import classnames from "classnames";
import React, { memo, useCallback, useMemo, useState } from "react";
import { Combobox } from "../../../base-components/combobox/Combobox.js";
import { useFilterListBoundary } from "../FilterListBoundaryContext.js";
import { getOptionLabelText, OptionLabel } from "./OptionLabel.js";
import { SelectInputSkeleton } from "./SelectInputSkeleton.js";
import sharedStyles from "./shared.module.css.js";
import styles from "./TextTagsInput.module.css.js";
const TAG_SEPARATOR_PATTERN = /[,\n]/u;
const TagItem = /*#__PURE__*/memo(function ({
  tag,
  onRemove
}) {
  const handleRemove = useCallback(() => {
    onRemove(tag);
  }, [tag, onRemove]);
  const displayLabel = getOptionLabelText(tag);
  return /*#__PURE__*/React.createElement("span", {
    className: sharedStyles.tag
  }, /*#__PURE__*/React.createElement(OptionLabel, {
    value: tag
  }), /*#__PURE__*/React.createElement(Button, {
    type: "button",
    className: sharedStyles.tagRemove,
    onClick: handleRemove,
    "aria-label": `Remove ${displayLabel}`
  }, "\xD7"));
});
function TextTagsInputInner({
  suggestions,
  isLoading,
  error,
  tags,
  onChange,
  className,
  style,
  placeholder = "Add a tag...",
  allowCustomTags = true,
  suggestionLimit = 10,
  ariaLabel = "Add tag"
}) {
  const collisionBoundary = useFilterListBoundary();
  const [inputValue, setInputValue] = useState("");
  const filteredSuggestions = useMemo(() => {
    if (!suggestionLimit) return [];
    const lowerInput = inputValue.toLowerCase();
    return suggestions.filter(s => (!inputValue.trim() || s.value.toLowerCase().includes(lowerInput)) && !tags.includes(s.value)).slice(0, suggestionLimit);
  }, [suggestions, inputValue, tags, suggestionLimit]);
  const addTag = useCallback(tag => {
    const trimmedTag = tag.trim();
    if (trimmedTag && !tags.includes(trimmedTag)) {
      onChange([...tags, trimmedTag]);
    }
    setInputValue("");
  }, [tags, onChange]);
  const removeTag = useCallback(tag => {
    onChange(tags.filter(t => t !== tag));
  }, [tags, onChange]);
  const handleValueChange = useCallback(newTags => {
    onChange(newTags ?? []);
  }, [onChange]);
  const handleInputValueChange = useCallback(value => {
    setInputValue(value);
  }, []);
  const handleKeyDown = useCallback(e => {
    if (e.key === "Enter" && inputValue.trim()) {
      if (filteredSuggestions.length > 0) {
        return;
      }
      e.preventDefault();
      if (allowCustomTags) {
        addTag(inputValue);
      }
    } else if (e.key === "Backspace" && !inputValue && tags.length > 0) {
      removeTag(tags[tags.length - 1]);
    }
  }, [inputValue, tags, addTag, removeTag, allowCustomTags, filteredSuggestions]);
  const handlePaste = useCallback(e => {
    const pastedText = e.clipboardData.getData("text");
    if (TAG_SEPARATOR_PATTERN.test(pastedText)) {
      e.preventDefault();
      const newTags = pastedText.split(TAG_SEPARATOR_PATTERN).map(t => t.trim()).filter(t => t && !tags.includes(t));
      if (newTags.length > 0) {
        onChange([...tags, ...newTags]);
      }
    }
  }, [tags, onChange]);
  return /*#__PURE__*/React.createElement("div", {
    className: classnames(styles.textTags, className),
    style: style,
    "data-loading": isLoading && suggestions.length > 0
  }, /*#__PURE__*/React.createElement("span", {
    className: sharedStyles.srOnly,
    role: "status"
  }, isLoading ? "Loading options" : ""), error && /*#__PURE__*/React.createElement("div", {
    className: sharedStyles.errorMessage
  }, "Error loading suggestions: ", error.message), /*#__PURE__*/React.createElement(Combobox.Root, {
    multiple: true,
    value: tags,
    onValueChange: handleValueChange,
    inputValue: inputValue,
    onInputValueChange: handleInputValueChange
  }, tags.length > 0 && /*#__PURE__*/React.createElement("div", {
    className: sharedStyles.tagContainer
  }, tags.map(tag => /*#__PURE__*/React.createElement(TagItem, {
    key: tag,
    tag: tag,
    onRemove: removeTag
  }))), /*#__PURE__*/React.createElement(Combobox.SearchInput, {
    className: styles.input,
    placeholder: tags.length > 0 ? "" : placeholder,
    onKeyDown: handleKeyDown,
    onPaste: handlePaste,
    "aria-label": ariaLabel
  }), /*#__PURE__*/React.createElement(Combobox.Portal, null, /*#__PURE__*/React.createElement(Combobox.Positioner, {
    collisionBoundary: collisionBoundary
  }, /*#__PURE__*/React.createElement(Combobox.Popup, null, filteredSuggestions.length === 0 ? allowCustomTags && inputValue.trim() ? /*#__PURE__*/React.createElement(Combobox.Empty, null, "Press Enter to add \"", inputValue, "\"") : /*#__PURE__*/React.createElement(Combobox.Empty, null, suggestionLimit ? "No suggestions" : "Type to add a tag") : filteredSuggestions.map(({
    value,
    count
  }) => /*#__PURE__*/React.createElement(Combobox.Item, {
    key: value,
    value: value
  }, /*#__PURE__*/React.createElement(OptionLabel, {
    value: value
  }), " (", count.toLocaleString(), ")")))))), !error && suggestions.length === 0 && isLoading && !!suggestionLimit && /*#__PURE__*/React.createElement(SelectInputSkeleton, null));
}
export const TextTagsInput = /*#__PURE__*/memo(TextTagsInputInner);
//# sourceMappingURL=TextTagsInput.js.map