"use client";

import {
  createContext,
  useContext,
  useEffect,
  useRef,
  useState,
  type ReactNode,
} from "react";
import { createPortal } from "react-dom";
import { cn } from "@/lib/utils";

interface DropdownContextValue {
  open: boolean;
  setOpen: (open: boolean) => void;
  triggerRef: React.RefObject<HTMLButtonElement | null>;
}

const DropdownContext = createContext<DropdownContextValue>({
  open: false,
  setOpen: () => {},
  triggerRef: { current: null },
});

export function Dropdown({ children }: { children: ReactNode }) {
  const [open, setOpen] = useState(false);
  const containerRef = useRef<HTMLDivElement>(null);
  const triggerRef = useRef<HTMLButtonElement>(null);

  useEffect(() => {
    function handleClick(e: MouseEvent) {
      if (containerRef.current && !containerRef.current.contains(e.target as Node)) {
        // Also check if the click is inside a portal dropdown
        const portalEl = document.getElementById("dropdown-portal");
        if (portalEl && portalEl.contains(e.target as Node)) return;
        setOpen(false);
      }
    }
    document.addEventListener("mousedown", handleClick);
    return () => document.removeEventListener("mousedown", handleClick);
  }, []);

  return (
    <DropdownContext.Provider value={{ open, setOpen, triggerRef }}>
      <div ref={containerRef} className="relative">
        {children}
      </div>
    </DropdownContext.Provider>
  );
}

export function DropdownTrigger({
  children,
  className,
}: {
  children: ReactNode;
  className?: string;
}) {
  const { open, setOpen, triggerRef } = useContext(DropdownContext);
  return (
    <button
      ref={triggerRef}
      onClick={() => setOpen(!open)}
      className={cn("cursor-pointer", className)}
      type="button"
    >
      {children}
    </button>
  );
}

export function DropdownContent({
  children,
  className,
  align = "end",
  portal = false,
}: {
  children: ReactNode;
  className?: string;
  align?: "start" | "end";
  portal?: boolean;
}) {
  const { open, triggerRef } = useContext(DropdownContext);
  const [coords, setCoords] = useState<{ top: number; left?: number; right?: number } | null>(null);

  useEffect(() => {
    if (!open || !portal || !triggerRef.current) return;
    const rect = triggerRef.current.getBoundingClientRect();
    const viewportWidth = window.innerWidth;
    if (align === "end") {
      setCoords({
        top: rect.bottom + 6,
        right: viewportWidth - rect.right,
      });
    } else {
      setCoords({
        top: rect.bottom + 6,
        left: rect.left,
      });
    }
  }, [open, portal, align, triggerRef]);

  if (!open) return null;

  const content = (
    <div
      className={cn(
        "min-w-[180px] rounded-xl border border-white/[0.08] bg-[#111116] shadow-2xl shadow-black/60",
        portal ? "fixed z-[9999]" : `absolute top-full z-50 mt-1 ${align === "end" ? "right-0" : "left-0"}`,
        className
      )}
      style={portal && coords ? {
        top: coords.top,
        ...(coords.right !== undefined ? { right: coords.right } : { left: coords.left }),
      } : undefined}
    >
      {children}
    </div>
  );

  if (portal && typeof document !== "undefined") {
    let portalEl = document.getElementById("dropdown-portal");
    if (!portalEl) {
      portalEl = document.createElement("div");
      portalEl.id = "dropdown-portal";
      document.body.appendChild(portalEl);
    }
    return createPortal(content, portalEl);
  }

  return content;
}

export function DropdownItem({
  children,
  className,
  onClick,
  destructive,
}: {
  children: ReactNode;
  className?: string;
  onClick?: () => void;
  destructive?: boolean;
}) {
  const { setOpen } = useContext(DropdownContext);
  return (
    <button
      onClick={() => {
        onClick?.();
        setOpen(false);
      }}
      className={cn(
        "flex w-full items-center gap-2.5 rounded-lg px-2.5 py-2 text-sm transition-colors cursor-pointer",
        destructive
          ? "text-red-400 hover:bg-red-500/10"
          : "text-white/60 hover:bg-white/[0.06] hover:text-white",
        className
      )}
      type="button"
    >
      {children}
    </button>
  );
}
