import { useEffect, type ReactNode } from 'react';
import { createPortal } from 'react-dom';
import { X } from 'lucide-react';
import { cn } from '../../lib/cn';

export type ModalWidth = 'sm' | 'md' | 'lg' | 'xl';


export interface ModalProps {
  open: boolean;
  onClose: () => void;
  title?: ReactNode;
  subtitle?: ReactNode;
  /** @default "md" */
  width?: ModalWidth;
  actions?: ReactNode;
  children?: ReactNode;
}

const WIDTH_CLASSES: Record<ModalWidth, string> = {
  sm: 'sm:w-[30vw]',
  md: 'sm:w-[50vw]',
  lg: 'sm:w-[70vw]',
  xl: 'sm:w-[90vw]',
};

/** Portal modal host — backdrop, Esc / click-out close, scroll-locked body. */
export function Modal({ open, onClose, title, subtitle, width = 'md', actions, children }: ModalProps) {
  useEffect(() => {
    if (!open) return;
    const onKey = (e: KeyboardEvent) => {
      if (e.key === 'Escape') onClose();
    };
    document.addEventListener('keydown', onKey);
    const prev = document.body.style.overflow;
    document.body.style.overflow = 'hidden';
    return () => {
      document.removeEventListener('keydown', onKey);
      document.body.style.overflow = prev;
    };
  }, [open, onClose]);

  if (!open) return null;

  return createPortal(
    <div
      className="fixed inset-0 z-[10000] flex items-start justify-end overflow-hidden bg-black/10 transition-opacity"
      onMouseDown={(e) => {
        if (e.target === e.currentTarget) onClose();
      }}
    >
      <style>{`
        @keyframes slideInRight {
          from { transform: translateX(100%); }
          to { transform: translateX(0); }
        }
        .animate-slide-in-right {
          animation: slideInRight 0.3s cubic-bezier(0.16, 1, 0.3, 1) forwards;
        }
      `}</style>
      <div
        role="dialog"
        aria-modal="true"
        className={cn(
          'w-full bg-[var(--z-block-bg)] shadow-[auto_0_30px_rgba(0,0,0,0.1)] my-0',
          WIDTH_CLASSES[width],
          'flex flex-col h-[100dvh] rounded-l-2xl rounded-r-none animate-slide-in-right border-l border-[var(--z-border-default)]',
        )}
      >
        <header className="shrink-0 flex items-start justify-between gap-3 px-5 py-4 border-b border-[var(--z-border-default)]">
          <div className="min-w-0">
            {title && <h3 className="m-0 text-md font-semibold text-strong truncate">{title}</h3>}
            {subtitle && <div className="text-xs text-faint mt-0.5">{subtitle}</div>}
          </div>
          <div className="flex items-center gap-2">
            {actions && <div className="flex items-center gap-2 mr-2">{actions}</div>}
            <button
              onClick={onClose}
              aria-label="Close"
              className="shrink-0 -mr-1 -mt-1 p-1.5 rounded-md text-faint hover:text-strong hover:bg-black/5"
            >
              <X size={18} />
            </button>
          </div>
        </header>
        <div className="flex-1 min-h-0 overflow-y-auto p-5 scrollbar-slim">{children}</div>
      </div>
    </div>,
    document.body,
  );
}
