import { useEffect, useId, useRef } from '@wordpress/element';
import Portal from './Portal';

const FOCUSABLE = 'a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])';

/**
 * The legacy `.ssgs_popup-container` / `.ssgs_popup-content` popup as an accessible dialog:
 * focus moves in and is trapped, Escape and backdrop clicks close it (legacy @click.away),
 * and focus returns to the trigger.
 *
 * @param {Object}   props
 * @param {Function} props.onClose  Close handler.
 * @param {Function} props.renderTitle Renders the title element; receives the id to set on it.
 * @param {Object}   props.children Dialog body.
 */
const Modal = ( { onClose, renderTitle, children } ) => {
	const contentRef = useRef( null );
	const titleId = useId();

	useEffect( () => {
		const previousFocus = document.activeElement;
		const focusable = () => [ ...contentRef.current.querySelectorAll( FOCUSABLE ) ];
		( focusable()[ 0 ] || contentRef.current ).focus();

		const onKeyDown = ( event ) => {
			if ( event.key === 'Escape' ) {
				event.stopPropagation();
				onClose();
				return;
			}
			if ( event.key !== 'Tab' ) {
				return;
			}
			const items = focusable();
			if ( ! items.length ) {
				return;
			}
			const first = items[ 0 ];
			const last = items[ items.length - 1 ];
			if ( event.shiftKey && document.activeElement === first ) {
				event.preventDefault();
				last.focus();
			} else if ( ! event.shiftKey && document.activeElement === last ) {
				event.preventDefault();
				first.focus();
			}
		};

		document.addEventListener( 'keydown', onKeyDown, true );
		return () => {
			document.removeEventListener( 'keydown', onKeyDown, true );
			previousFocus?.focus?.();
		};
	}, [ onClose ] );

	return (
		<Portal>
			<div className="ssgs_popup-container" onMouseDown={ ( event ) => event.target === event.currentTarget && onClose() } role="presentation">
				<div ref={ contentRef } className="ssgs_popup-content" role="dialog" aria-modal="true" aria-labelledby={ titleId } tabIndex={ -1 }>
					{ renderTitle( titleId ) }
					{ children }
				</div>
			</div>
		</Portal>
	);
};

export default Modal;
