import * as React from "react";
import { cn } from "@/lib/utils";

export interface TagInputProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'value' | 'onChange'> {
    value?: string[];
    onChange?: (tags: string[]) => void;
    placeholder?: string;
    maxTags?: number;
    allowDuplicates?: boolean;
    onTagAdd?: (tag: string) => void;
    onTagRemove?: (tag: string, index: number) => void;
}

const TagInput = React.forwardRef<HTMLInputElement, TagInputProps>(
    ({
        className,
        value = [],
        onChange,
        placeholder = "Type and press Enter to add tags...",
        maxTags,
        allowDuplicates = false,
        onTagAdd,
        onTagRemove,
        ...props
    }, ref) => {
        const [inputValue, setInputValue] = React.useState("");
        const [tags, setTags] = React.useState<string[]>(value);
        const inputRef = React.useRef<HTMLInputElement>(null);

        React.useImperativeHandle(ref, () => inputRef.current!, []);

        React.useEffect(() => {
            setTags(value);
        }, [value]);

        const addTag = (tagText: string) => {
            const trimmedTag = tagText.trim();
            if (!trimmedTag) return;

            if (maxTags && tags.length >= maxTags) return;

            if (!allowDuplicates && tags.includes(trimmedTag)) return;

            const newTags = [...tags, trimmedTag];
            setTags(newTags);
            onChange?.(newTags);
            onTagAdd?.(trimmedTag);
            setInputValue("");
        };

        const removeTag = (index: number) => {
            const tagToRemove = tags[index];
            const newTags = tags.filter((_, i) => i !== index);
            setTags(newTags);
            onChange?.(newTags);
            onTagRemove?.(tagToRemove, index);
        };

        const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
            if (e.key === "Enter") {
                e.preventDefault();
                addTag(inputValue);
            } else if (e.key === "Backspace" && !inputValue && tags.length > 0) {
                removeTag(tags.length - 1);
            }
        };

        const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
            setInputValue(e.target.value);
        };

        return (
            <div
                className={cn(
                    "flex min-h-12 w-full flex-wrap items-center gap-2 rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm transition-colors focus-within:ring-1 focus-within:ring-ring",
                    className
                )}
                onClick={() => inputRef.current?.focus()}
            >
                {tags.map((tag, index) => (
                    <span
                        key={index}
                        className="inline-flex items-center gap-1 rounded-md bg-secondary px-2 py-1 text-xs font-medium text-secondary-foreground"
                    >
                        {tag}
                        <button
                            type="button"
                            onClick={(e) => {
                                e.stopPropagation();
                                removeTag(index);
                            }}
                            className="ml-1 inline-flex h-4 w-4 items-center justify-center rounded-full hover:bg-secondary-foreground/20 focus:outline-none focus:ring-1 focus:ring-ring"
                        >
                            <svg
                                className="h-3 w-3"
                                xmlns="http://www.w3.org/2000/svg"
                                viewBox="0 0 24 24"
                                fill="none"
                                stroke="currentColor"
                                strokeWidth="2"
                                strokeLinecap="round"
                                strokeLinejoin="round"
                            >
                                <path d="M18 6L6 18M6 6l12 12" />
                            </svg>
                        </button>
                    </span>
                ))}
                <input
                    ref={inputRef}
                    type="text"
                    value={inputValue}
                    onChange={handleInputChange}
                    onKeyDown={handleKeyDown}
                    placeholder={tags.length === 0 ? placeholder : ""}
                    className="flex-1 bg-transparent outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50"
                    {...props}
                />
            </div>
        );
    }
);

TagInput.displayName = "TagInput";

export { TagInput };