import {createPortal, useRef, useState} from "@wordpress/element";
import {__} from '@wordpress/i18n';
import useClickOutside from "../../../../components/hooks/use-click-outside";
import {KEBAB_MENU} from "./_data";

export default function KebabMenu({actions = [], disabled, className, itemClass, iconClass, icon = 'kebab-vertical'}) {
    const [opened, setOpened] = useState(false);
    const [position, setPosition] = useState({
        top: 0,
        right: 0,
        bottom: 'unset',
    });

    // Elements refs
    const menuRef = useRef(null);
    const openerRef = useRef(null);
    const metaBoxRef = useRef(document.getElementById('chatbot-meta-box'));
    const fieldMenuRef = useRef(document.getElementById('lbaic-settings-field-menu'));

    const inCloseTimeout = useRef(null);

    useClickOutside([menuRef, openerRef], () => setOpened(false));

    const toggleMenu = (e) => {
        if (disabled || !actions?.length || !openerRef.current) {
            return;
        }
        if (opened) {
            setOpened(false);
            return;
        }

        const rect = openerRef.current.getBoundingClientRect();
        const metaBoxRect = metaBoxRef.current ? metaBoxRef.current.getBoundingClientRect() : null;
        const topMenuHeight = document.getElementById('wpadminbar').offsetHeight;

        // Menu position
        let top = rect.top - (metaBoxRect ? -2 : (topMenuHeight ? topMenuHeight - 36 : 0)) - (metaBoxRect?.top || 0);
        // Calculate the right position more precisely - use document width to avoid scrollbar issues
        let right = metaBoxRect ? (metaBoxRect.right - rect.right) : (document.documentElement.clientWidth - rect.right);
        let bottom = 'unset';
        if (top + (KEBAB_MENU.lineHeight * actions.length) + rect.height > window.innerHeight) {
            top = 'unset';
            bottom = 0;
        }

        setPosition({
            top: typeof top === 'number' ? top + 'px' : top,
            right: typeof right === 'number' ? right + 'px' : right,
            bottom: typeof bottom === 'number' ? bottom + 'px' : bottom,
        });

        // Open menu
        setOpened(true);
    };

    /**
     * Keep the menu opened if intend to close it within 400 ms
     */
    const inMouseEnter = () => {
        if (inCloseTimeout.current) {
            clearTimeout(inCloseTimeout.current);
            inCloseTimeout.current = null;
        }
    }

    /**
     * Close menu on mouse leave after 400 ms
     */
    const inMouseLeave = () => {
        inCloseTimeout.current = setTimeout(() => {
            setOpened(false);
        }, 400);
    }

    const handleActionClick = (action) => {
        if (!action?.disabled && typeof action?.onClick === 'function') {
            action.onClick();
            if (action.closeOnClick) {
                setOpened(false);
            }
        }
    };

    if (actions.length === 0) {
        return null;
    }

    return <>
        <div className={`lbaic-settings-kebab-menu${className ? ' ' + className : ''}`}>
            <button
                ref={openerRef}
                type="button"
                className={`lbaic-settings-button-reset lbaic-settings-kebab-menu-toggle${itemClass ? ' ' + itemClass : ''}${disabled ? ' lbaic-settings-button-disabled' : ''}`}
                onClick={toggleMenu}
                tabIndex='-1'
                title={__("Actions", 'limb-chatbot')}
            >
                <svg className={`lbaic-settings-kebab-menu-toggle-i${iconClass ? ' ' + iconClass : ''}`}
                     xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24'>
                    <use href={`#lbaic-settings-${icon}`}/>
                </svg>
            </button>
        </div>
        {opened && createPortal(
            <div ref={menuRef} className='lbaic-settings-kebab-menu-dropdown active'
                 style={{
                     '--lbaic-settings-kebab-menu-top': position.top,
                     '--lbaic-settings-kebab-menu-right': position.right,
                     '--lbaic-settings-kebab-menu-bottom': position.bottom,
                 }}
                 onMouseEnter={inMouseEnter}
                 onMouseLeave={inMouseLeave}>
                {actions.map((action, index) => (
                    <button
                        key={index}
                        tabIndex='-1'
                        onClick={(e) => {
                            e.stopPropagation();
                            handleActionClick(action);
                        }}
                        className={`lbaic-settings-button lbaic-settings-button-left lbaic-settings-button-h-30 lbaic-settings-button-kebab-menu lbaic-settings-kebab-menu-action${action.className ? ' ' + action.className : ''}${action.disabled ? ' lbaic-settings-button-disabled' : ''}`}
                    >
                        {action.beforeLabel ?
                            action.beforeLabel
                            :
                            action.loading ?
                                <svg className='lbaic-settings-button-i lbaic-settings-loading-circle lbaic-settings-button-loading-circle'
                                     xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24'>
                                    <use href='#lbaic-settings-circle'/>
                                </svg>
                                :
                                action.icon && (
                                    <svg className='lbaic-settings-button-i'
                                         xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24'>
                                        <use href={`#lbaic-settings-${action.icon}`}/>
                                    </svg>
                                )
                        }
                        <span className='lbaic-settings-button-label'>{action.label}</span>
                    </button>
                ))}
            </div>
            , fieldMenuRef.current || document.body)}
    </>
}
