import { useEffect } from 'react';

export function AppModal({ title, icon, onClose, children, overlay, className }) {
  // Escape does exactly what the X in the corner does. Every consumer wires
  // onClose to the safe direction (TrustServerModal -> decline,
  // DeviceLimitModal -> cancel the login), so this never commits anything.
  //
  // Bubble phase on purpose: FileDialogs' DialogShell registers its own Escape
  // handler in the CAPTURE phase and stops propagation, so a confirm/prompt
  // dialog stacked on top of a modal closes itself and leaves the modal open.
  // ConnectionsModal's join-code field relies on the same rule — it calls
  // stopPropagation so Escape cancels the code entry rather than the modal.
  useEffect(() => {
    const onKey = (e) => {
      if (e.key === 'Escape') onClose();
    };
    document.addEventListener('keydown', onKey);
    return () => document.removeEventListener('keydown', onKey);
  }, [onClose]);

  return (
    <div className="app-modal-overlay" onMouseDown={onClose}>
      <div
        className={`app-modal${className ? ` ${className}` : ''}`}
        role="dialog"
        aria-modal="true"
        aria-label={title}
        onMouseDown={(e) => e.stopPropagation()}
      >
        <button type="button" className="app-modal-close" onClick={onClose} aria-label="Close">
          <img src="assets/close.svg" alt="" />
        </button>
        <header className="app-modal-header">
          <h2 className="app-modal-title">{title}</h2>
          <img src={icon} alt="" className="app-modal-icon" />
        </header>
        <div className="app-modal-body">{children}</div>
        {overlay}
      </div>
    </div>
  );
}
