import { cn } from "./index3.js";
import { FieldTooltip } from "./index19.js";
import { hasFieldProps, splitFieldProps } from "./index20.js";
import { Field, FieldBottom, FieldBottomRight, FieldControl, FieldDescription, FieldError, FieldLabel, FieldTop, FieldTopRight } from "./index22.js";
import { Tag } from "./index86.js";
import { Check, ChevronDown } from "lucide-react";
import * as React from "react";
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
import { Autocomplete } from "@base-ui/react/autocomplete";
//#region src/components/molecules/forms/Autocomplete/Autocomplete.tsx
var sizeClasses = {
	sm: "h-8 px-2.5 text-sm",
	md: "h-10 px-3.5 text-base md:text-sm",
	lg: "h-11 px-4 text-base"
};
var tagSizeMap = {
	sm: "sm",
	md: "sm",
	lg: "md"
};
function AutocompleteControl({ placeholder = "Search...", items = [], groups, value, defaultValue, onValueChange, onSelect, disabled = false, destructive = false, startIcon, endIcon, showArrow = true, showCheck = true, filterFn, mode = "list", autoHighlight = false, open, defaultOpen, onOpenChange, className, inputClassName, popupClassName, emptyText = "No results found", name, required, size = "md", multiple = false, selectedItems = [], onSelectedItemsChange, renderSelectedItem, allowCreate = false, createItem, maxItems, preventDuplicates = true, backspaceRemovesLast = true, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, "aria-describedby": ariaDescribedBy, "aria-invalid": ariaInvalid, "aria-required": ariaRequired }) {
	const [internalValue, setInternalValue] = React.useState(defaultValue ?? "");
	const currentValue = value !== void 0 ? value : internalValue;
	const hasStartIcon = !!startIcon;
	const hasEndIcon = !!endIcon || showArrow;
	const hasSelectedItems = multiple && selectedItems.length > 0;
	const inputAriaProps = {
		"aria-label": ariaLabel,
		"aria-labelledby": ariaLabelledBy,
		"aria-describedby": ariaDescribedBy,
		"aria-invalid": ariaInvalid,
		"aria-required": ariaRequired
	};
	const filter = React.useMemo(() => {
		if (!filterFn) return void 0;
		return { filter: (itemValue, inputValue) => filterFn(itemValue, inputValue) };
	}, [filterFn]);
	const handleValueChange = React.useCallback((newValue, eventDetails) => {
		if (multiple && eventDetails?.reason === "item-press") {
			setInternalValue("");
			onValueChange?.("");
			return;
		}
		setInternalValue(newValue);
		onValueChange?.(newValue);
	}, [multiple, onValueChange]);
	const handleItemSelect = React.useCallback((item) => {
		if (multiple) {
			if (maxItems !== void 0 && selectedItems.length >= maxItems) return;
			const isAlreadySelected = selectedItems.some((s) => s.id === item.id);
			if (preventDuplicates && isAlreadySelected) return;
			if (!isAlreadySelected) onSelectedItemsChange?.([...selectedItems, item]);
		}
		onSelect?.(item);
	}, [
		multiple,
		maxItems,
		selectedItems,
		preventDuplicates,
		onSelectedItemsChange,
		onSelect
	]);
	const handleRemoveItem = React.useCallback((itemToRemove) => {
		onSelectedItemsChange?.(selectedItems.filter((item) => item.id !== itemToRemove.id));
	}, [selectedItems, onSelectedItemsChange]);
	const handleCreateItem = React.useCallback((inputValue) => {
		if (!multiple || !allowCreate || !inputValue.trim()) return;
		if (maxItems !== void 0 && selectedItems.length >= maxItems) return;
		const trimmedValue = inputValue.trim();
		if (preventDuplicates) {
			if (selectedItems.some((item) => item.label.toLowerCase() === trimmedValue.toLowerCase())) return;
		}
		const newItem = createItem ? createItem(trimmedValue) : {
			id: trimmedValue.toLowerCase().replace(/\s+/g, "-"),
			label: trimmedValue
		};
		onSelectedItemsChange?.([...selectedItems, newItem]);
		onValueChange?.("");
	}, [
		multiple,
		allowCreate,
		maxItems,
		preventDuplicates,
		selectedItems,
		createItem,
		onSelectedItemsChange,
		onValueChange
	]);
	const handleKeyDown = React.useCallback((e) => {
		if (e.key === "Enter" && allowCreate && currentValue?.trim()) {
			if (!(items.some((item) => item.label.toLowerCase().includes(currentValue.toLowerCase())) || groups?.some((group) => group.items.some((item) => item.label.toLowerCase().includes(currentValue.toLowerCase()))))) {
				e.preventDefault();
				handleCreateItem(currentValue);
			}
		}
		if (e.key === "Backspace" && multiple && backspaceRemovesLast && !currentValue && selectedItems.length > 0) {
			const lastItem = selectedItems[selectedItems.length - 1];
			if (lastItem) handleRemoveItem(lastItem);
		}
	}, [
		allowCreate,
		currentValue,
		items,
		groups,
		handleCreateItem,
		multiple,
		backspaceRemovesLast,
		selectedItems,
		handleRemoveItem
	]);
	const rootItems = groups ? groups.map((g) => ({ items: g.items })) : items;
	return /* @__PURE__ */ jsxs(Autocomplete.Root, {
		items: rootItems,
		value: currentValue,
		onValueChange: handleValueChange,
		mode,
		autoHighlight,
		highlightItemOnHover: true,
		open,
		defaultOpen,
		onOpenChange,
		disabled,
		name,
		itemToStringValue: (item) => item?.label ?? "",
		...filter,
		children: [/* @__PURE__ */ jsx("div", {
			className: cn("relative w-full", multiple && "rounded-md border border-input bg-transparent shadow-xs transition-[color,box-shadow] focus-within:border-ring focus-within:ring-[3px] focus-within:ring-ring/50", multiple && destructive && "border-destructive ring-[3px] ring-destructive/20 focus-within:border-destructive focus-within:ring-destructive/20", multiple && disabled && "opacity-50 cursor-not-allowed", className),
			children: multiple ? /* @__PURE__ */ jsxs("div", {
				className: "flex flex-col w-full",
				children: [/* @__PURE__ */ jsxs("div", {
					className: "relative flex items-center w-full",
					children: [
						hasStartIcon && /* @__PURE__ */ jsx("span", {
							className: "absolute start-3 top-1/2 -translate-y-1/2 text-muted-foreground pointer-events-none [&>svg]:size-5",
							children: startIcon
						}),
						/* @__PURE__ */ jsx(Autocomplete.Input, {
							placeholder: hasSelectedItems ? "" : placeholder,
							required,
							onKeyDown: handleKeyDown,
							...inputAriaProps,
							className: cn("flex-1 bg-transparent py-1 outline-none", "placeholder:text-muted-foreground", "disabled:pointer-events-none disabled:cursor-not-allowed", hasStartIcon && "ps-10", hasEndIcon && "pe-10", sizeClasses[size], "border-none shadow-none focus:ring-0", inputClassName)
						}),
						hasEndIcon && /* @__PURE__ */ jsxs("span", {
							className: "absolute end-3 top-1/2 -translate-y-1/2 flex items-center gap-1",
							children: [endIcon && /* @__PURE__ */ jsx("span", {
								className: "text-muted-foreground pointer-events-none [&>svg]:size-5",
								children: endIcon
							}), showArrow && /* @__PURE__ */ jsx(Autocomplete.Trigger, {
								"aria-label": "Toggle suggestions",
								className: cn("text-muted-foreground", "hover:text-foreground transition-colors", "disabled:opacity-50 disabled:cursor-not-allowed"),
								children: /* @__PURE__ */ jsx(ChevronDown, { className: "size-4 transition-transform duration-200 motion-reduce:transition-none [[data-popup-open]>&]:rotate-180" })
							})]
						})
					]
				}), hasSelectedItems && /* @__PURE__ */ jsx("div", {
					className: "flex flex-wrap gap-1.5 px-3 pb-2.5",
					children: selectedItems.map((item) => renderSelectedItem ? /* @__PURE__ */ jsx(React.Fragment, { children: renderSelectedItem(item, () => handleRemoveItem(item)) }, item.id) : /* @__PURE__ */ jsx(Tag, {
						size: tagSizeMap[size],
						avatar: item.avatar,
						icon: item.icon,
						removable: !disabled,
						onRemove: () => handleRemoveItem(item),
						children: item.label
					}, item.id))
				})]
			}) : /* @__PURE__ */ jsxs(Fragment$1, { children: [
				hasStartIcon && /* @__PURE__ */ jsx("span", {
					className: "absolute start-3 top-1/2 -translate-y-1/2 text-muted-foreground pointer-events-none [&>svg]:size-5",
					children: startIcon
				}),
				/* @__PURE__ */ jsx(Autocomplete.Input, {
					placeholder,
					required,
					...inputAriaProps,
					className: cn("w-full rounded-md border bg-transparent py-1 shadow-xs transition-[color,box-shadow] outline-none", "border-input focus:border-ring focus:ring-[3px] focus:ring-ring/50", "placeholder:text-muted-foreground", "disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50", destructive && "border-destructive ring-[3px] ring-destructive/20 focus:border-destructive focus:ring-destructive/20", hasStartIcon && "ps-10", hasEndIcon && "pe-10", sizeClasses[size], inputClassName)
				}),
				hasEndIcon && /* @__PURE__ */ jsxs("span", {
					className: "absolute end-3 top-1/2 -translate-y-1/2 flex items-center gap-1",
					children: [endIcon && /* @__PURE__ */ jsx("span", {
						className: "text-muted-foreground pointer-events-none [&>svg]:size-5",
						children: endIcon
					}), showArrow && /* @__PURE__ */ jsx(Autocomplete.Trigger, {
						"aria-label": "Toggle suggestions",
						className: cn("text-muted-foreground", "hover:text-foreground transition-colors", "disabled:opacity-50 disabled:cursor-not-allowed"),
						children: /* @__PURE__ */ jsx(ChevronDown, { className: "size-4 transition-transform duration-200 motion-reduce:transition-none [[data-popup-open]>&]:rotate-180" })
					})]
				})
			] })
		}), /* @__PURE__ */ jsx(Autocomplete.Portal, { children: /* @__PURE__ */ jsx(Autocomplete.Positioner, {
			sideOffset: 4,
			className: "z-50",
			children: /* @__PURE__ */ jsx(Autocomplete.Popup, {
				className: cn("w-[var(--anchor-width)] max-h-[300px] overflow-auto rounded-md border bg-popover p-1 shadow-lg", "origin-[var(--transform-origin)]", "transition-[transform,opacity] duration-150 motion-reduce:transition-none", "data-[ending-style]:scale-95 data-[ending-style]:opacity-0", "data-[starting-style]:scale-95 data-[starting-style]:opacity-0", popupClassName),
				children: /* @__PURE__ */ jsxs(Autocomplete.List, { children: [groups ? groups.map((group) => /* @__PURE__ */ jsxs(Autocomplete.Group, {
					items: group.items,
					children: [/* @__PURE__ */ jsx(Autocomplete.GroupLabel, {
						className: "px-2 py-1.5 text-xs font-semibold text-muted-foreground",
						children: group.label
					}), /* @__PURE__ */ jsx(Autocomplete.Collection, { children: (item) => /* @__PURE__ */ jsx(AutocompleteItemComponent, {
						item,
						showCheck,
						onSelect: handleItemSelect,
						isSelected: multiple && selectedItems.some((s) => s.id === item.id)
					}, item.id) })]
				}, group.label)) : /* @__PURE__ */ jsx(Autocomplete.Collection, { children: (item) => /* @__PURE__ */ jsx(AutocompleteItemComponent, {
					item,
					showCheck,
					onSelect: handleItemSelect,
					isSelected: multiple && selectedItems.some((s) => s.id === item.id)
				}, item.id) }), /* @__PURE__ */ jsx(Autocomplete.Empty, {
					className: "px-2 py-6 text-center text-sm text-muted-foreground animate-in fade-in-0 duration-200 motion-reduce:animate-none",
					children: emptyText
				})] })
			})
		}) })]
	});
}
function AutocompleteItemComponent({ item, showCheck, onSelect, isSelected }) {
	return /* @__PURE__ */ jsxs(Autocomplete.Item, {
		value: item,
		disabled: item.disabled,
		onClick: () => onSelect?.(item),
		className: cn("group relative flex items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none cursor-default select-none transition-colors duration-100 motion-reduce:transition-none", "data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground", "data-[disabled]:opacity-50 data-[disabled]:pointer-events-none", showCheck && "ps-8", isSelected && "bg-accent/50 transition-colors duration-150 motion-reduce:transition-none"),
		children: [showCheck && /* @__PURE__ */ jsx("span", {
			className: "absolute start-2 flex size-4 items-center justify-center",
			children: /* @__PURE__ */ jsx(Check, { className: cn("size-4 transition-opacity duration-150 motion-reduce:transition-none", isSelected ? "opacity-100" : "opacity-0 group-data-[highlighted]:opacity-100") })
		}), /* @__PURE__ */ jsx("span", {
			className: "truncate",
			children: item.label
		})]
	});
}
AutocompleteControl.displayName = "AutocompleteControl";
function Autocomplete$1(props) {
	const [fieldPropsObj, controlProps] = splitFieldProps(props);
	if (!hasFieldProps(fieldPropsObj)) return /* @__PURE__ */ jsx(AutocompleteControl, {
		...controlProps,
		required: fieldPropsObj.required
	});
	const { label, error, description, tooltip, labelIcon, topRight, bottomRight, fieldClassName } = fieldPropsObj;
	const cp = controlProps;
	return /* @__PURE__ */ jsxs(Field, {
		state: error ? "destructive" : void 0,
		className: fieldClassName,
		children: [
			(label || topRight) && /* @__PURE__ */ jsxs(FieldTop, { children: [label && /* @__PURE__ */ jsxs(FieldLabel, {
				required: fieldPropsObj.required,
				labelIcon,
				children: [label, tooltip && /* @__PURE__ */ jsx(FieldTooltip, { content: tooltip })]
			}), topRight && /* @__PURE__ */ jsx(FieldTopRight, { children: topRight })] }),
			/* @__PURE__ */ jsx(FieldControl, { children: (ctrlProps) => /* @__PURE__ */ jsx(AutocompleteControl, {
				...cp,
				"aria-describedby": ctrlProps["aria-describedby"],
				"aria-invalid": ctrlProps["aria-invalid"],
				"aria-required": ctrlProps["aria-required"],
				"aria-label": typeof label === "string" ? label : void 0,
				required: fieldPropsObj.required,
				destructive: !!error || cp.destructive
			}) }),
			(error || description || bottomRight) && /* @__PURE__ */ jsxs(FieldBottom, { children: [
				error && /* @__PURE__ */ jsx(FieldError, { children: error }),
				!error && description && /* @__PURE__ */ jsx(FieldDescription, { children: description }),
				bottomRight && /* @__PURE__ */ jsx(FieldBottomRight, {
					className: "ms-auto",
					children: bottomRight
				})
			] })
		]
	});
}
Autocomplete$1.displayName = "Autocomplete";
//#endregion
export { Autocomplete$1 as Autocomplete };

//# sourceMappingURL=index386.js.map