'use client';

import React, { useEffect, useRef } from 'react';

export interface ModalProps {
  /** Whether the modal is open */
  isOpen: boolean;
  /** Called when the user requests close (button, Escape, or overlay click) */
  onClose: () => void;
  /** Optional title for the dialog (used for aria-labelledby) */
  title?: string;
  /** Optional id for the title element (must be set if title is set for a11y) */
  titleId?: string;
  /** Dialog content */
  children: React.ReactNode;
  /** Optional footer rendered below scrollable content (e.g. branding or action bars). */
  footer?: React.ReactNode;
  /**
   * Hide the built-in header bar and close button. Use when the content provides its own
   * title and close affordance (e.g. a form with its own header). Escape and overlay click
   * still close the dialog.
   */
  hideHeader?: boolean;
  /** Accessible name for the dialog when no visible title is rendered (i.e. when hideHeader is true). */
  ariaLabel?: string;
  /** Optional className for the overlay (backdrop) */
  overlayClassName?: string;
  /** Optional className for the dialog panel */
  panelClassName?: string;
  /** Optional max width class for the panel (default: max-w-md). Use max-w-lg, max-w-2xl, etc. */
  maxWidth?: 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | '4xl' | '5xl';
}

const MAX_WIDTH_CLASSES: Record<NonNullable<ModalProps['maxWidth']>, string> = {
  sm: 'max-w-sm',
  md: 'max-w-md',
  lg: 'max-w-lg',
  xl: 'max-w-xl',
  '2xl': 'max-w-2xl',
  '3xl': 'max-w-3xl',
  '4xl': 'max-w-4xl',
  '5xl': 'max-w-5xl',
};

/**
 * Shared modal (dialog) component. Escape to close, aria-modal, overlay click to close, scroll lock, focus return on close.
 * Use for detail views, confirmations, and other overlay content. Renders in place (use a portal from the consumer if needed).
 * When `hideHeader` is true, provide an `aria-label` via `panelClassName` or ensure children supply a visible heading.
 */
export function Modal({
  isOpen,
  onClose,
  title,
  titleId = 'modal-title',
  children,
  footer,
  hideHeader = false,
  ariaLabel,
  overlayClassName,
  panelClassName,
  maxWidth = 'md',
}: ModalProps) {
  const overlayRef = useRef<HTMLDivElement>(null);
  const closeButtonRef = useRef<HTMLButtonElement>(null);

  useEffect(() => {
    if (!isOpen) return;
    const previouslyFocused = document.activeElement as HTMLElement | null;
    // When hideHeader is true there is no close button ref; autoFocus on content handles focus.
    closeButtonRef.current?.focus();
    const handleEscape = (e: KeyboardEvent) => {
      if (e.key === 'Escape') onClose();
    };
    document.addEventListener('keydown', handleEscape);
    document.body.style.overflow = 'hidden';
    return () => {
      document.removeEventListener('keydown', handleEscape);
      document.body.style.overflow = '';
      previouslyFocused?.focus();
    };
  }, [isOpen, onClose]);

  if (!isOpen) return null;

  const maxWidthClass = MAX_WIDTH_CLASSES[maxWidth];

  return (
    <div
      ref={overlayRef}
      className={
        overlayClassName ??
        'fixed inset-0 z-[200] flex items-center justify-center p-4 bg-black/50'
      }
      role="dialog"
      aria-modal="true"
      aria-label={ariaLabel}
      aria-labelledby={!ariaLabel && title && !hideHeader ? titleId : undefined}
      onClick={(e) => e.target === overlayRef.current && onClose()}
    >
      <div
        className={
          panelClassName ??
          `bg-primary border border-secondary rounded-lg shadow-xl w-full overflow-hidden ${maxWidthClass} max-h-[90vh] flex flex-col`
        }
        onClick={(e) => e.stopPropagation()}
      >
        {!hideHeader && (
          <div className="flex items-start justify-between gap-4 p-4 md:p-6 border-b border-secondary flex-shrink-0">
            {title ? (
              <h2
                id={titleId}
                className="font-display text-lg font-normal text-fg-primary md:text-xl flex-1 min-w-0"
              >
                {title}
              </h2>
            ) : (
              <span className="flex-1" aria-hidden />
            )}
            <button
              ref={closeButtonRef}
              type="button"
              onClick={onClose}
              className="shrink-0 p-1 text-fg-primary hover:text-brand-accent rounded focus:outline-none focus:ring-2 focus:ring-brand-accent"
              aria-label="Close"
            >
              <svg
                className="w-5 h-5"
                fill="none"
                stroke="currentColor"
                viewBox="0 0 24 24"
                aria-hidden
              >
                <path
                  strokeLinecap="round"
                  strokeLinejoin="round"
                  strokeWidth={2}
                  d="M6 18L18 6M6 6l12 12"
                />
              </svg>
            </button>
          </div>
        )}
        <div className="overflow-y-auto flex-1 p-4 md:p-6">{children}</div>
        {footer && <div className="flex-shrink-0 border-t border-secondary">{footer}</div>}
      </div>
    </div>
  );
}
