import {useEffect, useRef, useState, createPortal} from "@wordpress/element";
import {__} from "@wordpress/i18n";
import {handleError} from "../../../helpers/notifications";
import {copyToClipboard} from "../../../../components/chatbots/includes/helpers";

export default function Tooltip({className, contentClassName, label, icon = 'info', position = 'top', width, children, copyText}) {
    // When it is a copy tooltip but has no nothing to copy, just return the children
    if (copyText !== undefined && !copyText) {
        return children;
    }

    const [mouseEntered, setMouseEntered] = useState(false);
    const [contentMouseEntered, setContentMouseEntered] = useState(false);
    const [isOpened, setIsOpened] = useState(false);
    const [copied, setCopied] = useState(false);
    const [contentPosition, setContentPosition] = useState({
        top: '',
        right: '',
        left: '',
        bottom: '',
        moveLeft: '',
    });
    const tooltipRef = useRef(null);
    const contentInRef = useRef(null);
    const copiedTimeoutRef = useRef(null);
    const closeTimeoutRef = useRef(null);

    useEffect(() => {
        // Events
        window.addEventListener('resize', setupPosition);
        window.addEventListener('scroll', setupPosition, true);

        return () => {
            window.removeEventListener('resize', setupPosition);
            window.removeEventListener('scroll', setupPosition, true);
            if (copiedTimeoutRef.current) {
                clearTimeout(copiedTimeoutRef.current);
            }
            if (closeTimeoutRef.current) {
                clearTimeout(closeTimeoutRef.current);
            }
        }
    }, []);

    useEffect(() => {
        if (mouseEntered || contentMouseEntered || isOpened) {
            setupPosition();
        }
    }, [mouseEntered, contentMouseEntered, isOpened]);

    const toggle = async (e) => {
        // If copyText is provided, copy to clipboard
        if (copyText) {
            const res = await copyToClipboard(copyText);
            if (res.success) {
                setCopied(true);
                setIsOpened(true);

                // Clear any existing timeouts
                if (copiedTimeoutRef.current) {
                    clearTimeout(copiedTimeoutRef.current);
                }
                if (closeTimeoutRef.current) {
                    clearTimeout(closeTimeoutRef.current);
                    closeTimeoutRef.current = null;
                }

                // Reset copied state after 2 seconds
                copiedTimeoutRef.current = setTimeout(() => {
                    setCopied(false);
                    setIsOpened(false);
                    copiedTimeoutRef.current = null;
                }, 2000);
            } else {
                handleError(res.error);
            }
        } else {
            setIsOpened(!isOpened);
        }
    }

    const setupPosition = () => {
        if (tooltipRef.current && contentInRef.current) {
            const rect = tooltipRef.current.getBoundingClientRect();
            const contentInRect = contentInRef.current.getBoundingClientRect();
            if (position === 'top') {
                const top = Math.max(32, rect.bottom - contentInRect.height - rect.height - 12);
                const left = Math.max(89, rect.left + rect.width / 2);
                const moveLeft = Math.max(0, (left + contentInRect.width / 2) - window.innerWidth);
                setContentPosition({
                    top,
                    right: '',
                    bottom: '',
                    left: left - moveLeft,
                    moveLeft,
                });
            }
        }
    }

    const handleTooltipMouseEnter = () => {
        // Clear any pending close timeout
        if (closeTimeoutRef.current) {
            clearTimeout(closeTimeoutRef.current);
            closeTimeoutRef.current = null;
        }
        setMouseEntered(true);
    }

    const handleTooltipMouseLeave = () => {
        // Don't close if there's a copy operation in progress
        if (copiedTimeoutRef.current) {
            setMouseEntered(false);
            return;
        }

        // Add debounce before closing to allow mouse to move to tooltip content
        // Keep mouseEntered true during the debounce period
        closeTimeoutRef.current = setTimeout(() => {
            setMouseEntered(false);
            setIsOpened(false);
        }, 200);
    }

    const handleContentMouseEnter = () => {
        // Clear any pending close timeout
        if (closeTimeoutRef.current) {
            clearTimeout(closeTimeoutRef.current);
            closeTimeoutRef.current = null;
        }
        setMouseEntered(false);
        setContentMouseEntered(true);
    }

    const handleContentMouseLeave = () => {
        setContentMouseEntered(false);

        // Don't close if there's a copy operation in progress
        if (copiedTimeoutRef.current) {
            return;
        }

        // Add debounce before closing
        closeTimeoutRef.current = setTimeout(() => {
            setIsOpened(false);
        }, 200);
    }

    return <>
        <div className='lbaic-settings-tooltip-wrapper'>
            <div ref={tooltipRef} className={`lbaic-settings-tooltip${className ? ' ' + className : ''}`}
                 onClick={toggle}
                 onMouseEnter={handleTooltipMouseEnter}
                 onMouseLeave={handleTooltipMouseLeave}>
                {children ||
                    <svg className='lbaic-settings-tooltip-i' xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24'>
                        <use href={`#lbaic-settings-${icon}`}/>
                    </svg>}
            </div>
        </div>
        {(mouseEntered || contentMouseEntered || isOpened) && createPortal(
            <div className={`lbaic-settings-tooltip-content lbaic-settings-tooltip-${position}${contentClassName ? ' ' + contentClassName : ''}`}
                 onMouseEnter={handleContentMouseEnter}
                 onMouseLeave={handleContentMouseLeave}
                 style={{
                     '--lbaic-settings-tooltip-t': contentPosition.top + (typeof contentPosition.top === 'number' ? 'px' : undefined),
                     '--lbaic-settings-tooltip-r': contentPosition.right + (typeof contentPosition.right === 'number' ? 'px' : undefined),
                     '--lbaic-settings-tooltip-l': contentPosition.left + (typeof contentPosition.left === 'number' ? 'px' : undefined),
                     '--lbaic-settings-tooltip-b': contentPosition.bottom + (typeof contentPosition.bottom === 'number' ? 'px' : undefined),
                     '--lbaic-settings-tooltip-arrow-l-move': contentPosition.moveLeft + (typeof contentPosition.moveLeft === 'number' ? 'px' : undefined),
                 }}>
                <div ref={contentInRef} className='lbaic-settings-tooltip-content-in'
                     style={{'--lbaic-settings-tooltip-width': width ? width + 'px' : undefined}}>
                    {copyText ? (
                        <>
                            <svg
                                className='lbaic-settings-tooltip-i lbaic-settings-chats-action-i lbaic-settings-chats-action-i-fill lbaic-settings-chats-tooltip-i'
                                xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24'>
                                <use href={`#lbaic-settings-${copied ? 'check' : 'chats-copy'}`}/>
                            </svg>
                            <span
                                className='lbaic-settings-tooltip-content-label'>{copied ? __('Copied!', 'limb-chatbot') : label || __("Click to copy", 'limb-chatbot')}</span>
                        </>
                    ) : (
                        <span className='lbaic-settings-tooltip-content-label' dangerouslySetInnerHTML={{__html: label}}/>
                    )}
                </div>
            </div>
            , document.getElementById('lbaic-settings-field-menu'))}
    </>
}