import { useEffect, useRef, type ReactNode } from 'react';

interface MenuItem {
  label: string;
  icon?: ReactNode;
  onClick: () => void;
  variant?: 'default' | 'danger';
  checked?: boolean;
  separator?: false;
}

interface SeparatorItem {
  separator: true;
}

export type ContextMenuEntry = MenuItem | SeparatorItem;

interface ContextMenuProps {
  x: number;
  y: number;
  items: ContextMenuEntry[];
  onClose: () => void;
}

export function ContextMenu({ x, y, items, onClose }: ContextMenuProps) {
  const menuRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    function handleMouseDown(e: MouseEvent) {
      if (menuRef.current && !menuRef.current.contains(e.target as Node)) {
        onClose();
      }
    }
    function handleKeyDown(e: KeyboardEvent) {
      if (e.key === 'Escape') onClose();
    }
    document.addEventListener('mousedown', handleMouseDown);
    document.addEventListener('keydown', handleKeyDown);
    return () => {
      document.removeEventListener('mousedown', handleMouseDown);
      document.removeEventListener('keydown', handleKeyDown);
    };
  }, [onClose]);

  // Clamp so menu doesn't overflow right/bottom edge
  const menuWidth = 192;
  const menuHeight = items.length * 34;
  const clampedX = Math.min(x, window.innerWidth - menuWidth - 8);
  const clampedY = Math.min(y, window.innerHeight - menuHeight - 8);

  return (
    <div
      ref={menuRef}
      style={{ top: clampedY, left: clampedX, zIndex: 9999 }}
      className="fixed min-w-[192px] bg-slate-800 border border-slate-600 rounded-lg shadow-2xl py-1 text-sm"
    >
      {items.map((item, i) => {
        if ('separator' in item && item.separator) {
          return <div key={i} className="my-1 border-t border-slate-700" />;
        }
        const mi = item as MenuItem;
        return (
          <button
            key={i}
            className={`w-full text-left flex items-center gap-2 px-3 py-1.5 transition-colors hover:bg-slate-700 ${
              mi.variant === 'danger'
                ? 'text-red-400 hover:text-red-300'
                : 'text-slate-200'
            }`}
            onClick={() => {
              mi.onClick();
              onClose();
            }}
          >
            {mi.icon && <span className="shrink-0 w-4 text-slate-400">{mi.icon}</span>}
            <span className="flex-1">{mi.label}</span>
            {mi.checked !== undefined && (
              <span className={`text-xs ${mi.checked ? 'text-blue-400' : 'text-slate-600'}`}>
                {mi.checked ? '✓' : ''}
              </span>
            )}
          </button>
        );
      })}
    </div>
  );
}
