"use client";

import { motion, AnimatePresence } from "framer-motion";
import { useEffect, useCallback, useRef, type ReactNode } from "react";
import { useFocusTrap } from "~/hooks/useFocusTrap.js";

interface AnimatedModalProps {
  open: boolean;
  onClose: () => void;
  children: ReactNode;
  className?: string;
  overlayClassName?: string;
  maxWidth?: string;
  disableBackdropClose?: boolean;
}

export function AnimatedModal({
  open,
  onClose,
  children,
  className,
  overlayClassName,
  maxWidth = "max-w-xl",
  disableBackdropClose = false,
}: AnimatedModalProps) {
  const panelRef = useRef<HTMLDivElement>(null);

  useFocusTrap(panelRef, open);

  const handleEscape = useCallback(
    (e: KeyboardEvent) => {
      if (e.key === "Escape") onClose();
    },
    [onClose],
  );

  useEffect(() => {
    if (!open) return;
    document.addEventListener("keydown", handleEscape);
    return () => document.removeEventListener("keydown", handleEscape);
  }, [open, handleEscape]);

  return (
    <AnimatePresence>
      {open && (
        <div className="fixed inset-0 z-50 flex items-center justify-center">
          {/* Overlay */}
          <motion.div
            initial={{ opacity: 0 }}
            animate={{ opacity: 1 }}
            exit={{ opacity: 0 }}
            transition={{ duration: 0.2 }}
            className={
              overlayClassName ??
              "absolute inset-0 bg-black/40 backdrop-blur-sm"
            }
            onClick={disableBackdropClose ? undefined : onClose}
            aria-hidden="true"
          />

          {/* Panel */}
          <motion.div
            ref={panelRef}
            role="dialog"
            aria-modal="true"
            initial={{ opacity: 0, scale: 0.97 }}
            animate={{ opacity: 1, scale: 1 }}
            exit={{ opacity: 0, scale: 0.97 }}
            transition={{ duration: 0.2, ease: [0.16, 1, 0.3, 1] }}
            className={[
              "relative z-10 w-full rounded-xl bg-white shadow-2xl dark:bg-gray-800",
              maxWidth,
              className,
            ]
              .filter(Boolean)
              .join(" ")}
          >
            {children}
          </motion.div>
        </div>
      )}
    </AnimatePresence>
  );
}
