"use client";

import * as React from "react";
import { Check } from "lucide-react";

import { cn } from "@/lib/utils";
import {
	Command,
	CommandEmpty,
	CommandGroup,
	CommandInput,
	CommandItem,
	CommandList,
} from "@/components/ui/command";
import {
	Popover,
	PopoverContent,
	PopoverTrigger,
} from "@/components/ui/popover";
import { useState } from "react";

interface ComboBoxProps<T> {
	elements: T[];
	trigger: (value?: string) => React.ReactNode;
	onSubmit?: (value: string) => void;
	value: string;
	setValue: React.Dispatch<React.SetStateAction<string>>;
	children: (
		ItemComponent: (
			props: React.ComponentProps<typeof CommandItem> & { label: string },
		) => React.JSX.Element,
		element: T,
	) => React.ReactNode;
}

const ComboBox = <T,>({
	elements,
	trigger,
	children,
	onSubmit,
	value,
	setValue,
}: ComboBoxProps<T>) => {
	const [open, setOpen] = useState(false);
	const [searchValue, setSearchValue] = useState("");

	const handleSubmit = (e: React.KeyboardEvent<HTMLInputElement>) => {
		if (e.key !== "Enter") return;
		e.preventDefault();
		setValue(searchValue);
		onSubmit?.(searchValue);
	};

	return (
		<Popover open={open} onOpenChange={setOpen}>
			<PopoverTrigger asChild>
				{trigger(value.length > 0 ? value : undefined)}
			</PopoverTrigger>
			<PopoverContent className="w-[200px] p-0">
				<Command>
					<CommandInput
						onKeyDown={handleSubmit}
						onInput={(e) =>
							setSearchValue((e.target as HTMLInputElement).value)
						}
						placeholder="Search framework..."
					/>
					<CommandList>
						<CommandEmpty>
							Créer une nouvelle catégorie
						</CommandEmpty>
						<CommandGroup>
							{elements.map((element, index) =>
								children(
									({
										value: elementValue,
										label,
										onSelect,
										...props
									}) => (
										<CommandItem
											key={index}
											value={elementValue ?? ""}
											onSelect={(_value) => {
												setValue(_value);
												console.log(elementValue);
												setOpen(false);
												onSelect?.(_value);
											}}
											{...props}
										>
											{label}
											<Check
												className={cn(
													"mr-2 h-4 w-4",
													value === elementValue
														? "opacity-100"
														: "opacity-0",
												)}
											/>
										</CommandItem>
									),
									element,
								),
							)}
						</CommandGroup>
					</CommandList>
				</Command>
			</PopoverContent>
		</Popover>
	);
};

export default ComboBox;
