import React, {ReactNode, useEffect, useRef, useState} from "react";
import {LucideIcon} from "lucide-react";

interface DropdownItem {
    label: string;
    icon?: LucideIcon;
    onClick: () => void;
    variant?: 'default' | 'danger';
}

interface DropdownProps {
    trigger: ReactNode;
    items: DropdownItem[];
    align?: 'left' | 'right';
}

export default function Dropdown(
    {
        trigger,
        items,
        align = 'left',
    }: DropdownProps): React.JSX.Element {
    const [isOpen, setIsOpen] = useState<boolean>(false);
    const dropdownRef: React.RefObject<HTMLDivElement | null> = useRef<HTMLDivElement>(null);

    useEffect(function handleClickOutside() {
        function onClickOutside(event: MouseEvent): void {
            if (dropdownRef.current && event.target instanceof Node && !dropdownRef.current.contains(event.target)) {
                setIsOpen(false);
            }
        }

        document.addEventListener('mousedown', onClickOutside);
        return (): void => document.removeEventListener('mousedown', onClickOutside);
    }, []);

    function handleItemClick(item: DropdownItem): void {
        item.onClick();
        setIsOpen(false);
    }
    
    return (
        <div ref={dropdownRef} className="relative">
            <div onClick={(): void => setIsOpen(!isOpen)}>
                {trigger}
            </div>
            
            {isOpen && (
                <div
                    className={`
                        absolute top-full mt-2 z-50 min-w-48
                        bg-tertiary rounded-xl py-2
                        border border-secondary backdrop-blur-sm animate-fadeIn
                        ${align === 'right' ? 'right-0' : 'left-0'}
                    `}
                >
                    {items.map(function renderDropdownItem(item: DropdownItem, index: number) {
                        const isDanger: boolean = item.variant === 'danger';
                        const ItemIcon: LucideIcon | undefined = item.icon;
                        return (
                            <button
                                key={index}
                                onClick={(): void => handleItemClick(item)}
                                className={`
                                    group w-full flex items-center gap-3 px-4 py-2.5
                                    transition-all hover:pl-5
                                    ${isDanger
                                    ? 'text-error hover:bg-error/10'
                                    : 'text-text-primary hover:bg-secondary'
                                }
                                    ${index === 0 ? 'rounded-t-xl' : ''}
                                    ${index === items.length - 1 ? 'rounded-b-xl' : ''}
                                `}
                            >
                                {ItemIcon && (
                                    <ItemIcon
                                        className={`w-4 h-4 ${isDanger ? 'text-error' : 'text-muted group-hover:text-primary'}`}
                                        strokeWidth={1.75}
                                    />
                                )}
                                <span className="font-medium text-sm">{item.label}</span>
                            </button>
                        );
                    })}
                </div>
            )}
        </div>
    );
}
