import React, { useEffect } from 'react';

export interface ModalProps {
  open: boolean;
  onClose: () => void;
  title?: string;
  children: React.ReactNode;
  width?: number | string;
  /** Override the backdrop's own inline styles (e.g. a different overlay
   *  opacity/z-index). Merged on top of the shared defaults. */
  backdropStyle?: React.CSSProperties;
  /** Escape key closes the modal. Default true — set false to preserve a
   *  modal that never handled Escape before this component existed. */
  closeOnEscape?: boolean;
  /** Clicking the backdrop (outside the modal content) closes the modal.
   *  Default true — set false to preserve a modal that never handled
   *  backdrop clicks before this component existed. */
  closeOnBackdropClick?: boolean;
  /** Extra attributes spread onto the backdrop div (e.g. role="dialog",
   *  aria-modal) for a modal that previously set those directly. */
  backdropProps?: React.HTMLAttributes<HTMLDivElement>;
}

const defaultBackdropStyle: React.CSSProperties = {
  position: 'fixed',
  top: 0,
  left: 0,
  right: 0,
  bottom: 0,
  backgroundColor: 'rgba(0, 0, 0, 0.65)',
  display: 'flex',
  alignItems: 'center',
  justifyContent: 'center',
  /* z-index comes from the `.modal-backdrop` class (--z-modal in the
     shared layer scale, editor.css) rather than an inline value, so every
     Modal consumer -- including ones that pass a custom `backdropStyle`
     without a zIndex, like SitesmithModal -- lands on the same layer. */
};

/* ---------- Shared modal chrome ----------
   Backdrop + centered panel wrapper + Escape-to-close + scroll-lock, extracted
   from TemplateModal / HeadCodeModal / SitesmithModal (task E4.3). Each
   modal's own content — including its own header, close button, and panel
   styling (background, radius, shadow, dimensions) — stays in that modal's
   own file and is passed in as `children`, since those visuals differ across
   the three. `closeOnEscape` / `closeOnBackdropClick` default to true (the
   behavior TemplateModal and HeadCodeModal already had); SitesmithModal had
   neither before this extraction, so it opts out of both to keep its exact
   prior behavior. */
export const Modal: React.FC<ModalProps> = ({
  open,
  onClose,
  title,
  children,
  width,
  backdropStyle,
  closeOnEscape = true,
  closeOnBackdropClick = true,
  backdropProps,
}) => {
  useEffect(() => {
    if (!open || !closeOnEscape) return;
    const handler = (e: KeyboardEvent) => {
      if (e.key === 'Escape') onClose();
    };
    window.addEventListener('keydown', handler);
    return () => window.removeEventListener('keydown', handler);
  }, [open, closeOnEscape, onClose]);

  useEffect(() => {
    if (!open) return;
    const prevOverflow = document.body.style.overflow;
    document.body.style.overflow = 'hidden';
    return () => {
      document.body.style.overflow = prevOverflow;
    };
  }, [open]);

  if (!open) return null;

  return (
    <div
      className="modal-backdrop"
      {...backdropProps}
      style={backdropStyle ? { ...defaultBackdropStyle, ...backdropStyle } : defaultBackdropStyle}
      onClick={(e) => {
        if (closeOnBackdropClick && e.target === e.currentTarget) onClose();
      }}
    >
      <div style={width !== undefined ? { width } : undefined}>
        {title !== undefined && (
          <div style={{ fontSize: 15, fontWeight: 600, marginBottom: 8 }}>{title}</div>
        )}
        {children}
      </div>
    </div>
  );
};
