import React, { useEffect, useRef, useState } from 'react';
import { createPortal } from 'react-dom';
import './GameDropdown.css';

interface GameDropdownProps {
    isOpen: boolean;
    onClose: () => void;
    position?: { x: number; y: number }; // Made optional
    children: React.ReactNode;
    className?: string;
    width?: string;
}

// Track last click position globally to avoid passing it every time
let lastClickPos = { x: 0, y: 0 };

if (typeof window !== 'undefined') {
    // Capture usage of mouse down to update position before component renders
    window.addEventListener('mousedown', (e) => {
        lastClickPos = { x: e.clientX, y: e.clientY };
    }, { capture: true });
}

/**
 * GameDropdown
 * 
 * A reusable dropdown component that renders outside the DOM hierarchy 
 * to avoid z-index/overflow issues. 
 * Closes when clicking outside.
 */
export const GameDropdown: React.FC<GameDropdownProps> = ({
    isOpen,
    onClose,
    position,
    children,
    className = '',
    width = '200px'
}) => {
    const dropdownRef = useRef<HTMLDivElement>(null);

    // Capture position ONCE on mount (or first render) if not provided
    // This prevents the menu from jumping if the user clicks inside it (changing lastClickPos)
    const [capturedPos] = useState(() => position || lastClickPos);

    // Handle click outside
    useEffect(() => {
        if (!isOpen) return;

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

        // Use mousedown to catch clicks before they might trigger other things
        document.addEventListener('mousedown', handleClickOutside);

        // Handle scroll to close the dropdown (prevents detached menu and layout shifts)
        const handleScroll = (event: Event) => {
            // Only close if scrolling the main document/window, not a sub-container like combat log
            if (event.target === document || event.target === window || event.target === document.documentElement || event.target === document.body) {
                onClose();
            }
        };
        window.addEventListener('scroll', handleScroll, true);

        return () => {
            document.removeEventListener('mousedown', handleClickOutside);
            window.removeEventListener('scroll', handleScroll, true);
        };
    }, [isOpen, onClose]);

    if (!isOpen) return null;

    // Use passed position (if updated dynamically) or fall back to the captured sticky position
    const target = position || capturedPos;

    // Get zoom factor to adjust coordinates
    const zoom = typeof window !== 'undefined'
        ? (parseFloat(getComputedStyle(document.documentElement).getPropertyValue('--zoom-factor')) || 1)
        : 1;

    const targetX = target.x / zoom;
    const targetY = target.y / zoom;

    // Offset from cursor
    const offsetX = 5;
    const offsetY = 5;

    let x = targetX - offsetX;

    // Determine flip direction first using raw position
    let flipUp = false;
    if (typeof window !== 'undefined') {
        const viewportHeight = window.innerHeight / zoom;
        const estimatedHeight = 200; // Guess for now

        if (targetY + estimatedHeight > viewportHeight) {
            flipUp = true;
        }

        // Adjust width constrained by viewport
        const viewportWidth = window.innerWidth / zoom;
        const estimatedWidth = parseInt(width) || 200;
        if (x + estimatedWidth > viewportWidth) {
            x = viewportWidth - estimatedWidth - 10;
        }
    }

    // Apply offset based on direction
    // If flipping up, we want the bottom to be slightly below the mouse (y + 10)
    // If flipping down, we want the top to be slightly above the mouse (y - 10)
    const y = flipUp ? targetY + offsetY : targetY - offsetY;

    return createPortal(
        <div
            ref={dropdownRef}
            className={`game-dropdown-menu ${className}`}
            style={{
                top: flipUp ? 'auto' : y,
                bottom: flipUp ? ((window.innerHeight / zoom) - y) : 'auto',
                left: x,
                width: width
            }}
            onClick={(e) => e.stopPropagation()} // Prevent clicks inside from closing
        >
            {children}
        </div>,
        document.body
    );
};
