import { useState, useRef, useEffect, createContext, useContext, ReactNode } from "react";
import { cn } from "../utils/cn.ts";

interface DropdownContextValue {
  isOpen: boolean;
  setIsOpen: (isOpen: boolean) => void;
}

const DropdownContext = createContext<DropdownContextValue | null>(null);

function useDropdownContext() {
  const context = useContext(DropdownContext);
  if (!context) {
    throw new Error("Dropdown components must be used within a Dropdown");
  }
  return context;
}

interface DropdownProps {
  children: ReactNode;
}

function DropdownRoot({ children }: DropdownProps) {
  const [isOpen, setIsOpen] = useState(false);
  const dropdownRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    const handleClickOutside = (event: MouseEvent) => {
      if (dropdownRef.current && !dropdownRef.current.contains(event.target as Node)) {
        setIsOpen(false);
      }
    };

    if (isOpen) {
      document.addEventListener("mousedown", handleClickOutside);
    }

    return () => {
      document.removeEventListener("mousedown", handleClickOutside);
    };
  }, [isOpen]);

  return (
    <DropdownContext.Provider value={{ isOpen, setIsOpen }}>
      <div className="relative" ref={dropdownRef}>
        {children}
      </div>
    </DropdownContext.Provider>
  );
}

interface DropdownTriggerProps {
  children: ReactNode;
  className?: string;
}

function DropdownTrigger({ children, className }: DropdownTriggerProps) {
  const { isOpen, setIsOpen } = useDropdownContext();

  return (
    <div onClick={() => setIsOpen(!isOpen)} className={className}>
      {children}
    </div>
  );
}

interface DropdownContentProps {
  children: ReactNode;
  align?: "left" | "right";
  className?: string;
}

function DropdownContent({ children, align = "right", className }: DropdownContentProps) {
  const { isOpen, setIsOpen } = useDropdownContext();

  if (!isOpen) return null;

  return (
    <div
      className={cn(
        "absolute mt-1 w-48 bg-zinc-900 border border-zinc-800 rounded shadow-lg z-20",
        align === "left" ? "left-0" : "right-0",
        className
      )}
      onClick={() => setIsOpen(false)}
    >
      {children}
    </div>
  );
}

interface DropdownItemProps {
  onClick?: () => void;
  children: ReactNode;
  variant?: "default" | "danger";
  className?: string;
}

function DropdownItem({ onClick, children, variant: _variant = "default", className }: DropdownItemProps) {
  const variantClasses = "text-zinc-300 hover:bg-zinc-800";

  return (
    <button
      type="button"
      onClick={onClick}
      className={cn(
        "w-full flex items-center gap-2 px-4 py-2 text-xs transition-colors cursor-pointer",
        variantClasses,
        className
      )}
    >
      {children}
    </button>
  );
}

export const Dropdown = Object.assign(DropdownRoot, {
  Trigger: DropdownTrigger,
  Content: DropdownContent,
  Item: DropdownItem,
});
