"use client";

import * as React from "react";
import { cva, type VariantProps } from "class-variance-authority";
import {
	Check,
	XCircle,
	ChevronDown,
	X,
	WandSparkles,
} from "lucide-react";

import { cn } from "@/lib/utils";
import { Separator } from "@/components/ui/separator";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import {
	Popover,
	PopoverContent,
	PopoverTrigger,
} from "@/components/ui/popover";
import {
	Command,
	CommandEmpty,
	CommandGroup,
	CommandInput,
	CommandItem,
	CommandList,
	CommandSeparator,
} from "@/components/ui/command";
import { useVirtualizer } from "@tanstack/react-virtual";

/**
 * Animation types and configurations
 */
export interface AnimationConfig {
	/** Badge animation type */
	badgeAnimation?: "bounce" | "pulse" | "wiggle" | "fade" | "slide" | "none";
	/** Popover animation type */
	popoverAnimation?: "scale" | "slide" | "fade" | "flip" | "none";
	/** Option hover animation type */
	optionHoverAnimation?: "highlight" | "scale" | "glow" | "none";
	/** Animation duration in seconds */
	duration?: number;
	/** Animation delay in seconds */
	delay?: number;
}

/**
 * Variants for the multi-select component to handle different styles.
 * Uses class-variance-authority (cva) to define different styles based on "variant" prop.
 */
const multiSelectVariants = cva("m-1 transition-all duration-300 ease-in-out", {
	variants: {
		variant: {
			default: "border-gray-200 text-foreground bg-gray-50 hover:bg-gray-100/80",
			secondary:
				"border-foreground/10 bg-secondary text-secondary-foreground hover:bg-secondary/80",
			destructive:
				"border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80",
			inverted: "inverted",
		},
		badgeAnimation: {
			bounce: "hover:-translate-y-1 hover:scale-110",
			pulse: "hover:animate-pulse",
			wiggle: "hover:animate-wiggle",
			fade: "hover:opacity-80",
			slide: "hover:translate-x-1",
			none: "",
		},
	},
	defaultVariants: {
		variant: "default",
		badgeAnimation: "bounce",
	},
});

/**
 * Option interface for MultiSelect component
 */
interface MultiSelectOption {
	/** The text to display for the option. */
	label: string;
	/** The unique value associated with the option. */
	value: string;
	/** Optional icon component to display alongside the option. */
	icon?: React.ComponentType<{ className?: string }>;
	/** Whether this option is disabled */
	disabled?: boolean;
	/** Custom styling for the option */
	style?: {
		badgeColor?: string;
		iconColor?: string;
		gradient?: string;
	};
}

/**
 * Group interface for organizing options
 */
interface MultiSelectGroup {
	/** Group heading */
	heading: string;
	/** Options in this group */
	options: MultiSelectOption[];
}

/**
 * Props for MultiSelect component
 */
interface MultiSelectProps
	extends Omit<
		React.ButtonHTMLAttributes<HTMLButtonElement>,
		"animationConfig" | "defaultValue"
	>,
	VariantProps<typeof multiSelectVariants> {
	/**
	 * An array of option objects or groups to be displayed in the multi-select component.
	 */
	options: MultiSelectOption[] | MultiSelectGroup[];
	/**
	 * Callback function triggered when the selected values change.
	 * Receives an array of the new selected values.
	 */
	onValueChange: (value: string[]) => void;

	/** The current selected values (controlled value). */
	value?: string[];

	/** The default selected values when the component mounts. */
	defaultValue?: string[];

	/**
	 * Placeholder text to be displayed when no values are selected.
	 * Optional, defaults to "Select options".
	 */
	placeholder?: string;

	/**
	 * Animation duration in seconds for the visual effects (e.g., bouncing badges).
	 * Optional, defaults to 0 (no animation).
	 */
	animation?: number;

	/**
	 * Advanced animation configuration for different component parts.
	 * Optional, allows fine-tuning of various animation effects.
	 */
	animationConfig?: AnimationConfig;

	/**
	 * Maximum number of items to display. Extra selected items will be summarized.
	 * Optional, defaults to 3.
	 */
	maxCount?: number;

	/**
	 * The modality of the popover. When set to true, interaction with outside elements
	 * will be disabled and only popover content will be visible to screen readers.
	 * Optional, defaults to false.
	 */
	modalPopover?: boolean;

	/**
	 * If true, renders the multi-select component as a child of another component.
	 * Optional, defaults to false.
	 */
	asChild?: boolean;

	/**
	 * Additional class names to apply custom styles to the multi-select component.
	 */
	className?: string;

	/**
	 * If true, disables the select all functionality.
	 * Optional, defaults to false.
	 */
	hideSelectAll?: boolean;

	/**
	 * If true, shows search functionality in the popover.
	 * If false, hides the search input completely.
	 * Optional, defaults to true.
	 */
	searchable?: boolean;

	/**
	 * Custom empty state message when no options match search.
	 * Optional, defaults to "No results found."
	 */
	emptyIndicator?: React.ReactNode;

	/**
	 * If true, allows the component to grow and shrink with its content.
	 * If false, uses fixed width behavior.
	 * Optional, defaults to false.
	 */
	autoSize?: boolean;

	/**
	 * If true, shows badges in a single line with horizontal scroll.
	 * If false, badges wrap to multiple lines.
	 * Optional, defaults to false.
	 */
	singleLine?: boolean;

	/**
	 * Custom CSS class for the popover content.
	 */
	popoverClassName?: string;

	/**
	 * If true, disables the component completely.
	 * Optional, defaults to false.
	 */
	disabled?: boolean;

	/**
	 * Responsive configuration for different screen sizes.
	 */
	responsive?:
	| boolean
	| {
		/** Configuration for mobile devices (< 640px) */
		mobile?: {
			maxCount?: number;
			hideIcons?: boolean;
			compactMode?: boolean;
		};
		/** Configuration for tablet devices (640px - 1024px) */
		tablet?: {
			maxCount?: number;
			hideIcons?: boolean;
			compactMode?: boolean;
		};
		/** Configuration for desktop devices (> 1024px) */
		desktop?: {
			maxCount?: number;
			hideIcons?: boolean;
			compactMode?: boolean;
		};
	};

	/**
	 * Minimum width for the component.
	 */
	minWidth?: string;

	/**
	 * Maximum width for the component.
	 */
	maxWidth?: string;

	/**
	 * If true, automatically removes duplicate options based on their value.
	 * Optional, defaults to false.
	 */
	deduplicateOptions?: boolean;

	/**
	 * If true, the component will reset its internal state when value changed externally.
	 */
	resetOnDefaultValueChange?: boolean;

	/**
	 * If true, automatically closes the popover after selecting an option.
	 */
	closeOnSelect?: boolean;

	/** Controlled search value. */
	searchValue?: string;

	/** Controlled search value change callback. */
	onSearchValueChange?: (value: string) => void;
}

/**
 * Imperative methods exposed through ref
 */
export interface MultiSelectRef {
	reset: () => void;
	getSelectedValues: () => string[];
	setSelectedValues: (values: string[]) => void;
	clear: () => void;
	focus: () => void;
}

const MultiSelectComponent = React.forwardRef<MultiSelectRef, MultiSelectProps>(
	(
		{
			options,
			onValueChange,
			variant,
			value: controlledValue,
			defaultValue = [],
			placeholder = "Select options",
			animation = 0,
			animationConfig,
			maxCount = 3,
			modalPopover = false,
			asChild = false,
			className,
			hideSelectAll = false,
			searchable = true,
			emptyIndicator,
			autoSize = false,
			singleLine = false,
			popoverClassName,
			disabled = false,
			responsive,
			minWidth,
			maxWidth,
			deduplicateOptions = false,
			resetOnDefaultValueChange = true,
			closeOnSelect = false,
			searchValue: controlledSearchValue,
			onSearchValueChange,
			...props
		},
		ref
	) => {
		const [internalSelectedValues, setInternalSelectedValues] =
			React.useState<string[]>(defaultValue);

		const selectedValues = controlledValue ?? internalSelectedValues;

		const arraysEqual = React.useCallback(
			(a: string[], b: string[]): boolean => {
				if (a.length !== b.length) return false;
				const sortedA = [...a].sort();
				const sortedB = [...b].sort();
				return sortedA.every((val, index) => val === sortedB[index]);
			},
			[],
		);

		const updateSelectedValues = React.useCallback(
			(values: string[]) => {
				if (arraysEqual(values, selectedValues)) return;
				if (controlledValue === undefined) {
					setInternalSelectedValues(values);
				}
				onValueChange(values);
			},
			[arraysEqual, controlledValue, onValueChange, selectedValues],
		);

		const [isPopoverOpen, setIsPopoverOpen] = React.useState(false);
		const [isAnimating, setIsAnimating] = React.useState(false);
		const [internalSearchValue, setInternalSearchValue] = React.useState("");

		const searchValue = controlledSearchValue ?? internalSearchValue;
		const setSearchValue = (val: string) => {
			if (controlledSearchValue === undefined) {
				setInternalSearchValue(val);
			}
			onSearchValueChange?.(val);
		};

		const [politeMessage, setPoliteMessage] = React.useState("");
		const [assertiveMessage, setAssertiveMessage] = React.useState("");
		const prevSelectedCount = React.useRef(selectedValues.length);
		const prevIsOpen = React.useRef(isPopoverOpen);
		const prevSearchValue = React.useRef(searchValue);

		const announce = React.useCallback(
			(message: string, priority: "polite" | "assertive" = "polite") => {
				if (priority === "assertive") {
					setAssertiveMessage(message);
					setTimeout(() => setAssertiveMessage(""), 100);
				} else {
					setPoliteMessage(message);
					setTimeout(() => setPoliteMessage(""), 100);
				}
			},
			[]
		);

		const multiSelectId = React.useId();
		const listboxId = `${multiSelectId}-listbox`;
		const triggerDescriptionId = `${multiSelectId}-description`;
		const selectedCountId = `${multiSelectId}-count`;

		const prevDefaultValueRef = React.useRef<string[]>(defaultValue);

		const isGroupedOptions = React.useCallback(
			(
				opts: MultiSelectOption[] | MultiSelectGroup[]
			): opts is MultiSelectGroup[] => {
				return opts.length > 0 && "heading" in opts[0];
			},
			[]
		);

		const resetToDefault = React.useCallback(() => {
			updateSelectedValues(defaultValue);
			setIsPopoverOpen(false);
			setSearchValue("");
		}, [defaultValue, updateSelectedValues]);

		const buttonRef = React.useRef<HTMLButtonElement>(null);

		React.useImperativeHandle(
			ref,
			() => ({
				reset: resetToDefault,
				getSelectedValues: () => selectedValues,
				setSelectedValues: (values: string[]) => updateSelectedValues(values),
				clear: () => updateSelectedValues([]),
				focus: () => {
					if (buttonRef.current) {
						buttonRef.current.focus();
					}
				},
			}),
			[resetToDefault, selectedValues, onValueChange]
		);

		const [screenSize, setScreenSize] = React.useState<
			"mobile" | "tablet" | "desktop"
		>("desktop");

		React.useEffect(() => {
			if (typeof window === "undefined") return;
			const handleResize = () => {
				const width = window.innerWidth;
				if (width < 640) setScreenSize("mobile");
				else if (width < 1024) setScreenSize("tablet");
				else setScreenSize("desktop");
			};
			handleResize();
			window.addEventListener("resize", handleResize);
			return () => window.removeEventListener("resize", handleResize);
		}, []);

		const getResponsiveSettings = () => {
			if (!responsive) return { maxCount, hideIcons: false, compactMode: false };
			if (responsive === true) {
				const defaultResponsive = {
					mobile: { maxCount: 2, hideIcons: false, compactMode: true },
					tablet: { maxCount: 4, hideIcons: false, compactMode: false },
					desktop: { maxCount: 6, hideIcons: false, compactMode: false },
				};
				const currentSettings = defaultResponsive[screenSize];
				return {
					maxCount: currentSettings?.maxCount ?? maxCount,
					hideIcons: currentSettings?.hideIcons ?? false,
					compactMode: currentSettings?.compactMode ?? false,
				};
			}
			const currentSettings = responsive[screenSize] as any;
			return {
				maxCount: currentSettings?.maxCount ?? maxCount,
				hideIcons: currentSettings?.hideIcons ?? false,
				compactMode: currentSettings?.compactMode ?? false,
			};
		};

		const responsiveSettings = getResponsiveSettings();

		const getBadgeAnimationClass = () => {
			if (animationConfig?.badgeAnimation) {
				switch (animationConfig.badgeAnimation) {
					case "bounce": return isAnimating ? "animate-bounce" : "hover:-translate-y-1 hover:scale-110";
					case "pulse": return "hover:animate-pulse";
					case "wiggle": return "hover:animate-wiggle";
					case "fade": return "hover:opacity-80";
					case "slide": return "hover:translate-x-1";
					default: return "";
				}
			}
			return isAnimating ? "animate-bounce" : "";
		};

		const getPopoverAnimationClass = () => {
			if (animationConfig?.popoverAnimation) {
				switch (animationConfig.popoverAnimation) {
					case "scale": return "animate-in zoom-in-95";
					case "slide": return "animate-in slide-in-from-top-2";
					case "fade": return "animate-in fade-in";
					default: return "";
				}
			}
			return "";
		};

		const allOptions = React.useMemo(() => {
			const optionsArray: MultiSelectOption[] = [];
			options.forEach((item) => {
				if ("options" in item) {
					optionsArray.push(...item.options);
				} else {
					optionsArray.push(item);
				}
			});
			if (deduplicateOptions) {
				return Array.from(
					new Map(optionsArray.map((item) => [item.value, item])).values()
				);
			}
			return optionsArray;
		}, [options, deduplicateOptions]);

		const optionsMap = React.useMemo(() => {
			return new Map(allOptions.map((opt) => [opt.value, opt]));
		}, [allOptions]);

		const getOptionByValue = React.useCallback((value: string) => {
			return optionsMap.get(value);
		}, [optionsMap]);

		const filteredOptions = React.useMemo(() => {
			if (!searchable || !searchValue) return options;
			if (options.length === 0) return [];
			if (isGroupedOptions(options)) {
				return options
					.map((group) => ({
						...group,
						options: group.options.filter(
							(option) =>
								option.label.toLowerCase().includes(searchValue.toLowerCase()) ||
								option.value.toLowerCase().includes(searchValue.toLowerCase())
						),
					}))
					.filter((group) => group.options.length > 0);
			}
			return options.filter(
				(option) =>
					option.label.toLowerCase().includes(searchValue.toLowerCase()) ||
					option.value.toLowerCase().includes(searchValue.toLowerCase())
			);
		}, [options, searchValue, searchable, isGroupedOptions]);

		const handleInputKeyDown = (
			event: React.KeyboardEvent<HTMLInputElement>
		) => {
			if (event.key === "Enter") {
				setIsPopoverOpen(true);
			} else if (event.key === "Backspace" && !event.currentTarget.value) {
				const newSelectedValues = [...selectedValues];
				newSelectedValues.pop();
				updateSelectedValues(newSelectedValues);
			}
		};

		const toggleOption = (optionValue: string) => {
			if (disabled) return;
			const option = getOptionByValue(optionValue);
			if (option?.disabled) return;
			const newSelectedValues = selectedValues.includes(optionValue)
				? selectedValues.filter((value) => value !== optionValue)
				: [...selectedValues, optionValue];
			updateSelectedValues(newSelectedValues);
			if (closeOnSelect) setIsPopoverOpen(false);
		};

		const handleClear = () => {
			if (disabled) return;
			updateSelectedValues([]);
		};

		const handleTogglePopover = () => {
			if (disabled) return;
			setIsPopoverOpen((prev) => !prev);
		};

		const clearExtraOptions = () => {
			if (disabled) return;
			const newSelectedValues = selectedValues.slice(0, responsiveSettings.maxCount);
			updateSelectedValues(newSelectedValues);
		};

		const toggleAll = () => {
			if (disabled) return;
			const enabledOptions = allOptions.filter((option) => !option.disabled);
			if (selectedValues.length === enabledOptions.length) {
				handleClear();
			} else {
				updateSelectedValues(enabledOptions.map((option) => option.value));
			}
			if (closeOnSelect) setIsPopoverOpen(false);
		};

		const getWidthConstraints = () => {
			const defaultMinWidth = screenSize === "mobile" ? "0px" : "200px";
			const effectiveMinWidth = minWidth || defaultMinWidth;
			const effectiveMaxWidth = maxWidth || "100%";
			return {
				minWidth: effectiveMinWidth,
				maxWidth: effectiveMaxWidth,
				width: autoSize ? "auto" : "100%",
			};
		};

		const widthConstraints = getWidthConstraints();

		React.useEffect(() => {
			if (!isPopoverOpen) setSearchValue("");
		}, [isPopoverOpen]);

		React.useEffect(() => {
			if (controlledValue !== undefined) return;
			if (!resetOnDefaultValueChange) return;
			const prevDefaultValue = prevDefaultValueRef.current;
			if (!arraysEqual(prevDefaultValue, defaultValue)) {
				if (!arraysEqual(selectedValues, defaultValue)) {
					updateSelectedValues(defaultValue);
				}
				prevDefaultValueRef.current = [...defaultValue];
			}
		}, [
			controlledValue,
			defaultValue,
			selectedValues,
			arraysEqual,
			resetOnDefaultValueChange,
			updateSelectedValues,
		]);

		React.useEffect(() => {
			const selectedCount = selectedValues.length;
			const currentAllOptions = allOptions;
			const totalOptions = currentAllOptions.filter((opt) => !opt.disabled).length;
			if (selectedCount !== prevSelectedCount.current) {
				const diff = selectedCount - prevSelectedCount.current;
				if (diff > 0) {
					const addedItems = selectedValues.slice(-diff);
					const addedLabels = addedItems
						.map(
							(value) => allOptions.find((opt) => opt.value === value)?.label
						)
						.filter(Boolean);

					if (addedLabels.length === 1) {
						announce(
							`${addedLabels[0]} selected. ${selectedCount} of ${totalOptions} options selected.`
						);
					} else {
						announce(
							`${addedLabels.length} options selected. ${selectedCount} of ${totalOptions} total selected.`
						);
					}
				} else if (diff < 0) {
					announce(
						`Option removed. ${selectedCount} of ${totalOptions} options selected.`
					);
				}
				prevSelectedCount.current = selectedCount;
			}

			if (isPopoverOpen !== prevIsOpen.current) {
				if (isPopoverOpen) {
					announce(
						`Dropdown opened. ${totalOptions} options available. Use arrow keys to navigate.`
					);
				} else {
					announce("Dropdown closed.");
				}
				prevIsOpen.current = isPopoverOpen;
			}

			if (
				searchValue !== prevSearchValue.current &&
				searchValue !== undefined
			) {
				if (searchValue && isPopoverOpen) {
					const filteredCount = allOptions.filter(
						(opt) =>
							opt.label.toLowerCase().includes(searchValue.toLowerCase()) ||
							opt.value.toLowerCase().includes(searchValue.toLowerCase())
					).length;

					announce(
						`${filteredCount} option${filteredCount === 1 ? "" : "s"
						} found for "${searchValue}"`
					);
				}
				prevSearchValue.current = searchValue;
			}
		}, [selectedValues, isPopoverOpen, searchValue, announce, allOptions]);

		const flatOptions = React.useMemo(() => {
			if (isGroupedOptions(filteredOptions)) {
				return filteredOptions.flatMap(g => g.options.map(o => ({ ...o, group: g.heading })));
			}
			return filteredOptions;
		}, [filteredOptions, isGroupedOptions]);

		const parentRef = React.useRef<HTMLDivElement>(null);

		const virtualizer = useVirtualizer({
			count: flatOptions.length,
			getScrollElement: () => parentRef.current,
			estimateSize: () => 35,
			overscan: 5,
		});

		return (
			<>
				<div className="sr-only">
					<div aria-live="polite" aria-atomic="true" role="status">{politeMessage}</div>
					<div aria-live="assertive" aria-atomic="true" role="alert">{assertiveMessage}</div>
				</div>

				<Popover
					open={isPopoverOpen}
					onOpenChange={setIsPopoverOpen}
					modal={modalPopover}>
					<PopoverTrigger asChild>
						<Button
							ref={buttonRef}
							onClick={handleTogglePopover}
							disabled={disabled}
							role="combobox"
							aria-expanded={isPopoverOpen}
							className={cn(
								"flex p-1 rounded-xl border min-h-10 h-auto items-center justify-between bg-gray-50 hover:bg-gray-100/80 border-gray-200",
								autoSize ? "w-auto" : "w-full",
								responsiveSettings.compactMode && "min-h-8 text-sm",
								className
							)}
							style={{
								...widthConstraints,
								maxWidth: `min(${widthConstraints.maxWidth}, 100%)`,
							}}
							{...props}
						>
							{selectedValues.length > 0 ? (
								<div className="flex items-center justify-between w-full gap-2 overflow-hidden">
									<div className={cn(
										"flex items-center gap-1",
										singleLine ? "overflow-x-auto scrollbar-hide flex-nowrap py-0.5" : "flex-wrap",
										responsiveSettings.compactMode && "gap-0.5"
									)}>
										{selectedValues
											.slice(0, responsiveSettings.maxCount)
											.map((value) => {
												const option = getOptionByValue(value);
												if (!option) return null;
												return (
													<Badge
														key={value}
														variant={variant as any || "secondary"}
														className={cn(
															getBadgeAnimationClass(),
															"rounded-lg px-2 py-0.5 text-[12px] font-medium gap-1 shrink-0 border-0 whitespace-nowrap",
															variant === "inverted" ? "bg-white text-primary" : "bg-primary/10 text-primary"
														)}
													>
														<span className="truncate max-w-[150px]">{option.label}</span>
														<XCircle
															className="h-3 w-3 cursor-pointer ml-1 hover:text-red-500 transition-colors"
															onClick={(e) => {
																e.stopPropagation();
																toggleOption(value);
															}}
														/>
													</Badge>
												);
											})}
										{selectedValues.length > responsiveSettings.maxCount && (
											<Badge
												variant="secondary"
												className="rounded-lg px-2 py-0.5 text-[12px] font-medium bg-gray-100 text-gray-600 border-0 shrink-0 whitespace-nowrap"
											>
												{`+ ${selectedValues.length - responsiveSettings.maxCount} more`}
											</Badge>
										)}
									</div>
									<div className="flex items-center gap-1 px-1">
										<X
											className="h-4 w-4 cursor-pointer text-muted-foreground hover:text-foreground"
											onClick={(e) => {
												e.stopPropagation();
												handleClear();
											}}
										/>
										<Separator orientation="vertical" className="h-4" />
										<ChevronDown className="h-4 w-4 text-muted-foreground" />
									</div>
								</div>
							) : (
								<div className="flex items-center justify-between w-full px-2">
									<span className="text-[14px] text-gray-400 font-normal">
										{placeholder}
									</span>
									<ChevronDown className="h-4 w-4 text-gray-400" />
								</div>
							)}
						</Button>
					</PopoverTrigger>
					<PopoverContent
						className={cn(
							"w-[var(--radix-popover-trigger-width)] p-0 rounded-xl",
							popoverClassName
						)}
						align="start">
						<Command shouldFilter={false}>
							{searchable && (
								<CommandInput
									placeholder="Search options..."
									onKeyDown={handleInputKeyDown}
									value={searchValue}
									onValueChange={setSearchValue}
								/>
							)}
							<CommandList ref={parentRef} className="max-h-[300px] overflow-y-auto scrollbar-themed p-1">
								<CommandEmpty>{emptyIndicator || "No results found."}</CommandEmpty>
								{!hideSelectAll && !searchValue && options.length > 0 && (
									<CommandGroup>
										<CommandItem
											onSelect={toggleAll}
											className="cursor-pointer rounded-lg text-[13px]">
											<div className={cn(
												"mr-2 flex h-4 w-4 items-center justify-center rounded-sm border border-primary",
												selectedValues.length === allOptions.filter(o => !o.disabled).length
													? "bg-primary text-primary-foreground"
													: "opacity-50"
											)}>
												{selectedValues.length === allOptions.filter(o => !o.disabled).length && <Check className="h-3 w-3" />}
											</div>
											<span>Select All</span>
										</CommandItem>
									</CommandGroup>
								)}
								
								<div
									style={{
										height: `${virtualizer.getTotalSize()}px`,
										width: "100%",
										position: "relative",
									}}
								>
									{virtualizer.getVirtualItems().map((virtualRow) => {
										const option = flatOptions[virtualRow.index];
										const isSelected = selectedValues.includes(option.value);
										return (
											<CommandItem
												key={option.value}
												onSelect={() => toggleOption(option.value)}
												className="cursor-pointer rounded-lg text-[13px] w-full"
												disabled={option.disabled}
												style={{
													position: "absolute",
													top: 0,
													left: 0,
													width: "100%",
													height: `${virtualRow.size}px`,
													transform: `translateY(${virtualRow.start}px)`,
												}}
											>
												<div className={cn(
													"mr-2 flex h-4 w-4 items-center justify-center rounded-sm border border-primary",
													isSelected ? "bg-primary text-primary-foreground" : "opacity-50"
												)}>
													{isSelected && <Check className="h-3 w-3" />}
												</div>
												{option.icon && <option.icon className="mr-2 h-4 w-4" />}
												<span className="flex-1 truncate">{option.label}</span>
												{option.group && (
													<span className="ml-2 text-[10px] text-muted-foreground uppercase opacity-50">
														{option.group}
													</span>
												)}
											</CommandItem>
										);
									})}
								</div>
							</CommandList>
						</Command>
					</PopoverContent>
					{animation > 0 && selectedValues.length > 0 && (
						<WandSparkles
							className={cn(
								"cursor-pointer my-2 text-foreground bg-background w-3 h-3 absolute -right-6 top-0",
								isAnimating ? "" : "text-muted-foreground"
							)}
							onClick={() => setIsAnimating(!isAnimating)}
						/>
					)}
				</Popover>
			</>
		);
	}
);

const MultiSelect = React.memo(MultiSelectComponent);
MultiSelect.displayName = "MultiSelect";

export { MultiSelect };
export type { MultiSelectOption as Option, MultiSelectGroup as Group, MultiSelectProps };
