import { useEffect, useRef } from 'react';
import { createRoot, type Root } from 'react-dom/client';
import { MODAL_OVERLAY_CLASS } from '../replay';

interface ModalProps {
  isOpen: boolean;
  onClose: () => void;
  children: React.ReactNode;
  title?: string;
}

export function Modal({ isOpen, onClose, children, title }: ModalProps) {
  const overlayRef = useRef<HTMLDivElement | null>(null);
  const bodyRef = useRef<HTMLDivElement | null>(null);
  const rootRef = useRef<Root | null>(null);
  const onCloseRef = useRef(onClose);
  onCloseRef.current = onClose;

  // Create/destroy modal DOM shell using vanilla DOM (HTML namespace guaranteed)
  useEffect(() => {
    if (!isOpen) return;

    // Overlay
    const overlay = document.createElement('div');
    // Shared with the recorder: this class IS the boundary of what a session
    // replay may contain, so the two must never be able to drift apart.
    overlay.className = MODAL_OVERLAY_CLASS;
    overlay.addEventListener('click', () => onCloseRef.current());

    // Content container (stops propagation)
    const content = document.createElement('div');
    content.className = 'aisthetix-modal-content';
    content.setAttribute('role', 'dialog');
    content.setAttribute('aria-modal', 'true');
    content.addEventListener('click', (e) => e.stopPropagation());

    // Header
    const header = document.createElement('div');
    header.className = 'aisthetix-modal-header';

    if (title) {
      const h2 = document.createElement('h2');
      h2.id = 'modal-title';
      h2.className = 'aisthetix-modal-title';
      h2.textContent = title;
      content.setAttribute('aria-labelledby', 'modal-title');
      header.appendChild(h2);
    }

    // Close button
    const closeBtn = document.createElement('button');
    closeBtn.type = 'button';
    closeBtn.className = 'aisthetix-modal-close';
    closeBtn.setAttribute('aria-label', 'Close');
    closeBtn.innerHTML =
      '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">' +
      '<line x1="18" y1="6" x2="6" y2="18"></line>' +
      '<line x1="6" y1="6" x2="18" y2="18"></line></svg>';
    closeBtn.addEventListener('click', () => onCloseRef.current());
    header.appendChild(closeBtn);

    // Body (React renders children here)
    const body = document.createElement('div');
    body.className = 'aisthetix-modal-body';

    content.appendChild(header);
    content.appendChild(body);
    overlay.appendChild(content);
    document.body.appendChild(overlay);
    document.body.style.overflow = 'hidden';

    overlayRef.current = overlay;
    bodyRef.current = body;
    rootRef.current = createRoot(body);

    return () => {
      const root = rootRef.current;
      const el = overlayRef.current;
      rootRef.current = null;
      overlayRef.current = null;
      bodyRef.current = null;
      document.body.style.overflow = '';
      if (root) {
        setTimeout(() => {
          root.unmount();
          el?.remove();
        }, 0);
      }
    };
  }, [isOpen]);

  // Update title when it changes
  useEffect(() => {
    if (!overlayRef.current) return;
    const h2 = overlayRef.current.querySelector('#modal-title');
    if (h2 && title) h2.textContent = title;
  }, [title]);

  // Render React children into the body div
  useEffect(() => {
    if (rootRef.current && isOpen) {
      rootRef.current.render(<>{children}</>);
    }
  });

  // Close on Escape key
  useEffect(() => {
    if (!isOpen) return;
    const handler = (e: KeyboardEvent) => {
      if (e.key === 'Escape') onClose();
    };
    document.addEventListener('keydown', handler);
    return () => document.removeEventListener('keydown', handler);
  }, [isOpen, onClose]);

  return null;
}
