/**
 * Confirm dialog for destructive / committing actions.
 * Shared across admin, Gutenberg, and frontend editor.
 */
import { Button } from '@wordpress/components';
import { createPortal, useEffect } from '@wordpress/element';
import { __ } from '@wordpress/i18n';

/**
 * @param {object}   props
 * @param {boolean}  props.open
 * @param {string}   props.title
 * @param {string}   [props.description]
 * @param {import('@wordpress/element').WPElement|string} [props.children]
 * @param {string}   [props.confirmLabel]
 * @param {string}   [props.cancelLabel]
 * @param {string}   [props.icon]         Dashicon slug
 * @param {string}   [props.tone]         primary | danger | warning
 * @param {boolean}  [props.busy]
 * @param {boolean}  [props.confirmDisabled]
 * @param {Function} props.onConfirm
 * @param {Function} props.onCancel
 */
export default function ConfirmModal( {
	open,
	title,
	description,
	children,
	confirmLabel,
	cancelLabel,
	icon = 'yes-alt',
	tone = 'primary',
	busy = false,
	confirmDisabled = false,
	onConfirm,
	onCancel,
} ) {
	useEffect( () => {
		if ( ! open ) {
			return undefined;
		}
		const onKey = ( e ) => {
			if ( e.key === 'Escape' && ! busy ) {
				e.stopPropagation();
				onCancel?.();
			}
		};
		window.addEventListener( 'keydown', onKey, true );
		return () => window.removeEventListener( 'keydown', onKey, true );
	}, [ open, busy, onCancel ] );

	if ( ! open ) {
		return null;
	}

	const portalTarget =
		document.getElementById( 'joc-blockora-morph-app' ) || document.body;

	const toneClass =
		tone === 'danger'
			? 'bm-confirm-modal__icon is-danger'
			: tone === 'warning'
			? 'bm-confirm-modal__icon is-warning'
			: 'bm-confirm-modal__icon is-primary';

	const rootTone =
		tone === 'danger'
			? ' bm-confirm-modal-root--danger'
			: tone === 'warning'
			? ' bm-confirm-modal-root--warning'
			: '';

	return createPortal(
		<div
			className={ `bm-modal-root bm-confirm-modal-root${ rootTone }` }
			role="alertdialog"
			aria-modal="true"
			aria-labelledby="bm-confirm-title"
			aria-describedby={ description ? 'bm-confirm-desc' : undefined }
		>
			<div
				className="bm-modal-backdrop bm-confirm-modal__backdrop"
				onClick={ busy ? undefined : onCancel }
			/>
			<div className="bm-confirm-modal">
				<div className="bm-confirm-modal__glow" aria-hidden="true" />
				<div className="bm-confirm-modal__body">
					<div className={ toneClass } aria-hidden="true">
						<span className={ `dashicons dashicons-${ icon }` } />
					</div>
					<h2 id="bm-confirm-title" className="bm-confirm-modal__title">
						{ title }
					</h2>
					{ description ? (
						<p id="bm-confirm-desc" className="bm-confirm-modal__desc">
							{ description }
						</p>
					) : null }
					{ children ? (
						<div className="bm-confirm-modal__children">{ children }</div>
					) : null }
				</div>
				<div className="bm-confirm-modal__actions">
					<Button
						variant="tertiary"
						onClick={ onCancel }
						disabled={ busy }
						className="bm-confirm-modal__btn"
					>
						{ cancelLabel || __( 'Cancel', 'joc-blockora-morph' ) }
					</Button>
					<Button
						variant={ tone === 'danger' ? 'primary' : 'primary' }
						isDestructive={ tone === 'danger' }
						onClick={ onConfirm }
						disabled={ busy || confirmDisabled }
						className={
							'bm-confirm-modal__btn' +
							( tone === 'warning' ? ' is-warning' : '' )
						}
					>
						{ busy
							? __( 'Working…', 'joc-blockora-morph' )
							: confirmLabel ||
							  __( 'Confirm', 'joc-blockora-morph' ) }
					</Button>
				</div>
			</div>
		</div>,
		portalTarget
	);
}
