"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ContextMenu = void 0;
const jsx_runtime_1 = require("react/jsx-runtime");
/**
 * ContextMenu Component
 *
 * A context menu for the workflow builder that appears on right-click
 */
const react_1 = require("react");
const prop_types_1 = __importDefault(require("prop-types"));
/**
 * ContextMenu component for workflow builder
 * @param {Object} props - Component props
 * @param {boolean} props.visible - Whether the context menu is visible
 * @param {Object} props.position - Position of the context menu
 * @param {Object} props.target - The target element that was right-clicked
 * @param {Array} props.items - Menu items to display
 * @param {Function} props.onItemClick - Callback when a menu item is clicked
 * @param {Function} props.onClose - Callback when the menu is closed
 * @param {string} props.className - Additional CSS classes
 * @param {Object} props.style - Additional inline styles
 * @returns {React.ReactElement} ContextMenu component
 */
const ContextMenu = ({ visible = false, position = { x: 0, y: 0 }, target = null, items = [], onItemClick, onClose, className = '', style = {}, ...rest }) => {
    // State for keeping track of which submenus are open
    const [openSubMenus, setOpenSubMenus] = (0, react_1.useState)({});
    // Ref for the context menu element
    const menuRef = (0, react_1.useRef)(null);
    // Generate dynamic menu items based on the target
    const getContextMenuItems = () => {
        // Default items if none provided
        if (!items || items.length === 0) {
            if (!target)
                return [];
            const isNode = target.type === 'node';
            const isEdge = target.type === 'edge';
            const isCanvas = target.type === 'canvas';
            if (isNode) {
                return [
                    { id: 'edit-node', label: 'Edit Node', icon: 'pen-to-square', action: 'edit-node' },
                    { id: 'duplicate-node', label: 'Duplicate', icon: 'copy', action: 'duplicate-node' },
                    { id: 'delete-node', label: 'Delete', icon: 'trash', action: 'delete-node', danger: true },
                    { type: 'divider' },
                    { id: 'node-connect', label: 'Connect To...', icon: 'link', action: 'start-connection' },
                    { type: 'divider' },
                    {
                        id: 'align-node',
                        label: 'Align',
                        icon: 'align-center',
                        subItems: [
                            { id: 'align-left', label: 'Left', icon: 'align-left', action: 'align-node', value: 'left' },
                            { id: 'align-center', label: 'Center', icon: 'align-center', action: 'align-node', value: 'center' },
                            { id: 'align-right', label: 'Right', icon: 'align-right', action: 'align-node', value: 'right' },
                            { type: 'divider' },
                            { id: 'align-top', label: 'Top', icon: 'align-left', action: 'align-node', value: 'top' },
                            { id: 'align-middle', label: 'Middle', icon: 'align-center', action: 'align-node', value: 'middle' },
                            { id: 'align-bottom', label: 'Bottom', icon: 'align-right', action: 'align-node', value: 'bottom' }
                        ]
                    },
                    {
                        id: 'style-node',
                        label: 'Style',
                        icon: 'paint-brush',
                        subItems: [
                            { id: 'color-node', label: 'Color', icon: 'palette', action: 'style-node', value: 'color' },
                            { id: 'size-node', label: 'Size', icon: 'expand', action: 'style-node', value: 'size' },
                            { id: 'shape-node', label: 'Shape', icon: 'shapes', action: 'style-node', value: 'shape' }
                        ]
                    }
                ];
            }
            else if (isEdge) {
                return [
                    { id: 'edit-edge', label: 'Edit Connection', icon: 'pen-to-square', action: 'edit-edge' },
                    { id: 'delete-edge', label: 'Delete Connection', icon: 'trash', action: 'delete-edge', danger: true },
                    { type: 'divider' },
                    {
                        id: 'style-edge',
                        label: 'Style',
                        icon: 'paint-brush',
                        subItems: [
                            { id: 'line-type', label: 'Line Type', icon: 'minus', action: 'style-edge', value: 'line-type' },
                            { id: 'color-edge', label: 'Color', icon: 'palette', action: 'style-edge', value: 'color' },
                            { id: 'thickness', label: 'Thickness', icon: 'text-height', action: 'style-edge', value: 'thickness' }
                        ]
                    }
                ];
            }
            else if (isCanvas) {
                return [
                    { id: 'add-node', label: 'Add Node', icon: 'plus', action: 'add-node' },
                    { id: 'paste', label: 'Paste', icon: 'paste', action: 'paste' },
                    { type: 'divider' },
                    { id: 'fit-view', label: 'Fit View', icon: 'expand', action: 'fit-view' },
                    { id: 'select-all', label: 'Select All', icon: 'object-group', action: 'select-all' },
                    { type: 'divider' },
                    {
                        id: 'canvas-options',
                        label: 'Canvas Options',
                        icon: 'cog',
                        subItems: [
                            { id: 'show-grid', label: 'Show Grid', icon: 'border-all', action: 'toggle-grid' },
                            { id: 'snap-to-grid', label: 'Snap to Grid', icon: 'magnet', action: 'toggle-snap' }
                        ]
                    }
                ];
            }
        }
        return items;
    };
    // Menu items to render
    const menuItems = getContextMenuItems();
    // Close context menu when clicking outside
    (0, react_1.useEffect)(() => {
        const handleClickOutside = (event) => {
            if (menuRef.current && !menuRef.current.contains(event.target) && visible) {
                if (onClose)
                    onClose();
            }
        };
        const handleScroll = () => {
            if (visible && onClose)
                onClose();
        };
        const handleKeyDown = (event) => {
            if (event.key === 'Escape' && visible) {
                if (onClose)
                    onClose();
            }
        };
        document.addEventListener('mousedown', handleClickOutside);
        document.addEventListener('scroll', handleScroll);
        document.addEventListener('keydown', handleKeyDown);
        return () => {
            document.removeEventListener('mousedown', handleClickOutside);
            document.removeEventListener('scroll', handleScroll);
            document.removeEventListener('keydown', handleKeyDown);
        };
    }, [visible, onClose]);
    // Position adjustment to keep menu in viewport
    const getAdjustedPosition = () => {
        if (!menuRef.current)
            return position;
        const menuRect = menuRef.current.getBoundingClientRect();
        const viewportWidth = window.innerWidth;
        const viewportHeight = window.innerHeight;
        let x = position.x;
        let y = position.y;
        // Adjust x position if menu goes beyond right edge of viewport
        if (x + menuRect.width > viewportWidth) {
            x = viewportWidth - menuRect.width - 8;
        }
        // Adjust y position if menu goes beyond bottom edge of viewport
        if (y + menuRect.height > viewportHeight) {
            y = viewportHeight - menuRect.height - 8;
        }
        return { x, y };
    };
    // Toggle submenu
    const toggleSubMenu = (itemId) => {
        setOpenSubMenus(prev => ({
            ...prev,
            [itemId]: !prev[itemId]
        }));
    };
    // Handle menu item click
    const handleItemClick = (item) => {
        if (item.subItems) {
            toggleSubMenu(item.id);
            return;
        }
        if (onItemClick) {
            onItemClick(item, target);
        }
        if (onClose) {
            onClose();
        }
    };
    // Render icon
    const renderIcon = (icon) => {
        // This is a placeholder for icon rendering
        // In a real implementation, you would use an icon library or SVG icons
        if (!icon)
            return null;
        return ((0, jsx_runtime_1.jsx)("span", { className: `bf-context-menu__icon bf-icon-${icon}`, style: { marginRight: '8px' }, children: icon.charAt(0).toUpperCase() }));
    };
    // Render a menu item
    const renderMenuItem = (item) => {
        if (item.type === 'divider') {
            return ((0, jsx_runtime_1.jsx)("div", { className: "bf-context-menu__divider", style: {
                    height: '1px',
                    backgroundColor: '#D1D5DB',
                    margin: '4px 0'
                } }, `divider-${Math.random().toString(36).substr(2, 9)}`));
        }
        const hasSubItems = item.subItems && item.subItems.length > 0;
        const isSubMenuOpen = openSubMenus[item.id];
        return ((0, jsx_runtime_1.jsxs)("div", { className: `bf-context-menu__item ${item.danger ? 'bf-context-menu__item--danger' : ''}`, style: { position: 'relative' }, children: [(0, jsx_runtime_1.jsxs)("button", { className: "bf-context-menu__button", onClick: () => handleItemClick(item), onMouseEnter: () => hasSubItems && toggleSubMenu(item.id), style: {
                        display: 'flex',
                        alignItems: 'center',
                        justifyContent: 'space-between',
                        width: '100%',
                        padding: '6px 12px',
                        backgroundColor: 'transparent',
                        border: 'none',
                        borderRadius: '4px',
                        cursor: 'pointer',
                        color: item.danger ? '#EF4444' : '#374151',
                        textAlign: 'left',
                        fontSize: '14px'
                    }, children: [(0, jsx_runtime_1.jsxs)("div", { style: { display: 'flex', alignItems: 'center' }, children: [renderIcon(item.icon), (0, jsx_runtime_1.jsx)("span", { children: item.label })] }), hasSubItems && ((0, jsx_runtime_1.jsx)("span", { style: { marginLeft: '24px' }, children: "\u25B6" }))] }), hasSubItems && isSubMenuOpen && ((0, jsx_runtime_1.jsx)("div", { className: "bf-context-menu__submenu", style: {
                        position: 'absolute',
                        top: 0,
                        left: '100%',
                        backgroundColor: 'white',
                        border: '1px solid #D1D5DB',
                        borderRadius: '4px',
                        boxShadow: '0 2px 5px rgba(0, 0, 0, 0.1)',
                        zIndex: 1000,
                        minWidth: '160px',
                        padding: '4px 0'
                    }, children: item.subItems.map(subItem => renderMenuItem(subItem)) }))] }, item.id));
    };
    // Don't render if not visible
    if (!visible)
        return null;
    // Calculate adjusted position
    const adjustedPosition = getAdjustedPosition();
    // Classes
    const contextMenuClasses = [
        'bf-context-menu',
        className
    ].filter(Boolean).join(' ');
    // Styles
    const contextMenuStyle = {
        position: 'fixed',
        left: `${adjustedPosition.x}px`,
        top: `${adjustedPosition.y}px`,
        backgroundColor: 'white',
        border: '1px solid #D1D5DB',
        borderRadius: '4px',
        boxShadow: '0 2px 5px rgba(0, 0, 0, 0.1)',
        zIndex: 1000,
        minWidth: '160px',
        padding: '4px 0',
        ...style
    };
    return ((0, jsx_runtime_1.jsx)("div", { ref: menuRef, className: contextMenuClasses, style: contextMenuStyle, ...rest, children: menuItems.map(item => renderMenuItem(item)) }));
};
exports.ContextMenu = ContextMenu;
exports.ContextMenu.propTypes = {
    visible: prop_types_1.default.bool,
    position: prop_types_1.default.shape({
        x: prop_types_1.default.number.isRequired,
        y: prop_types_1.default.number.isRequired
    }),
    target: prop_types_1.default.shape({
        id: prop_types_1.default.string,
        type: prop_types_1.default.oneOf(['node', 'edge', 'canvas']),
        data: prop_types_1.default.any
    }),
    items: prop_types_1.default.arrayOf(prop_types_1.default.oneOfType([
        // Regular menu item
        prop_types_1.default.shape({
            id: prop_types_1.default.string.isRequired,
            label: prop_types_1.default.string.isRequired,
            icon: prop_types_1.default.string,
            action: prop_types_1.default.string.isRequired,
            value: prop_types_1.default.any,
            danger: prop_types_1.default.bool
        }),
        // Submenu item
        prop_types_1.default.shape({
            id: prop_types_1.default.string.isRequired,
            label: prop_types_1.default.string.isRequired,
            icon: prop_types_1.default.string,
            subItems: prop_types_1.default.array.isRequired
        }),
        // Divider
        prop_types_1.default.shape({
            type: prop_types_1.default.oneOf(['divider']).isRequired
        })
    ])),
    onItemClick: prop_types_1.default.func,
    onClose: prop_types_1.default.func,
    className: prop_types_1.default.string,
    style: prop_types_1.default.object
};
exports.default = exports.ContextMenu;
//# sourceMappingURL=ContextMenu.js.map