import { useState, useRef, useEffect } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
import clsx from '../../../utils/clsx';

const Tooltip = ( {
	title = __( 'Tooltip', 'rewind-form-bridge-for-brevo' ),
	component,
	style,
	className,
	placement = 'top',
	arrow = false,
	arrowSize = 5,
	openStyle = 'fade',
	trigger = 'hover',
	width = 'auto',
	maxWidth,
	wrap = 'wrap',
	background = 'gray-800',
	color = 'white',
	border,
	shadow = false,
	visible = true,
	disabled = false,
	children,
} ) => {
	const [ actualPlacement, setActualPlacement ] = useState( placement );
	const [ isVisible, setIsVisible ] = useState( false );
	const tooltipRef = useRef( null );
	const triggerRef = useRef( null );

	useEffect( () => {
		const handleClickOutside = ( event ) => {
			if (
				trigger === 'click' &&
				tooltipRef.current &&
				! tooltipRef.current.contains( event.target ) &&
				triggerRef.current &&
				! triggerRef.current.contains( event.target )
			) {
				setIsVisible( false );
			}
		};
		document.addEventListener( 'mousedown', handleClickOutside );
		return () =>
			document.removeEventListener( 'mousedown', handleClickOutside );
	}, [ trigger ] );

	useEffect( () => {
		if (
			placement !== 'auto' ||
			! isVisible ||
			! tooltipRef.current ||
			! triggerRef.current
		)
			return;
		const triggerBox = triggerRef.current.getBoundingClientRect();
		const windowWidth = window.innerWidth;
		const windowHeight = window.innerHeight;
		const spaces = {
			top: triggerBox.top,
			bottom: windowHeight - triggerBox.bottom,
			left: triggerBox.left,
			right: windowWidth - triggerBox.right,
		};
		const bestSide = Object.entries( spaces ).sort(
			( a, b ) => b[ 1 ] - a[ 1 ]
		)[ 0 ][ 0 ];
		setActualPlacement( bestSide );
	}, [ isVisible, placement ] );

	const wrapperClasses = clsx(
		'rbfb-tooltip',
		isVisible && 'rbfb-tooltip--show',
		placement === 'auto'
			? `rbfb-tooltip--${ actualPlacement }`
			: `rbfb-tooltip--${ placement }`
	);

	const textClasses = clsx(
		'rbfb-tooltip__text',
		arrow && 'rbfb-tooltip__text--has-arrow',
		`rbfb-tooltip__text--open-${ openStyle }`,
		`rbfb-tooltip__text--wrap-${ wrap }`,
		`text-${ color }`,
		`bg-${ background }`,
		border && `border border-solid border-${ border }`,
		shadow && 'rbfb-tooltip__text--shadow'
	);

	if ( disabled ) return <>{ children }</>;

	return (
		<div
			ref={ triggerRef }
			style={ style }
			className={ clsx( wrapperClasses, className ) }
			onMouseEnter={
				trigger === 'hover'
					? () => setIsVisible( visible ? true : false )
					: undefined
			}
			onMouseLeave={
				trigger === 'hover' ? () => setIsVisible( false ) : undefined
			}
			onClick={
				trigger === 'click'
					? () =>
							setIsVisible( ( prev ) =>
								visible ? ! prev : false
							)
					: undefined
			}
		>
			<div
				ref={ tooltipRef }
				className={ textClasses }
				style={ {
					'--rbfb-tooltip-width': width,
					'--rbfb-tooltip-max-width': maxWidth,
					'--rbfb-tooltip-arrow-size': `${ arrowSize }px`,
					'--rbfb-tooltip-arrow-color': `var(--rbfb-${ background })`,
				} }
			>
				{ component ? component : title }
			</div>

			{ children }
		</div>
	);
};

export default Tooltip;
