import { useEffect, useRef, useState, type ReactNode } from "react";

interface AnimatedPanelProps {
  open: boolean;
  children: ReactNode;
  className?: string;
  /** Duration in ms for the exit animation before unmounting. */
  exitDuration?: number;
}

export function AnimatedPanel({ open, children, className, exitDuration = 140 }: AnimatedPanelProps) {
  const [mounted, setMounted] = useState(open);
  const [visible, setVisible] = useState(open);
  const timerRef = useRef<number | null>(null);

  useEffect(() => {
    if (open) {
      if (timerRef.current) {
        window.clearTimeout(timerRef.current);
        timerRef.current = null;
      }
      setMounted(true);
      requestAnimationFrame(() => {
        requestAnimationFrame(() => {
          setVisible(true);
        });
      });
    } else {
      setVisible(false);
      timerRef.current = window.setTimeout(() => {
        setMounted(false);
        timerRef.current = null;
      }, exitDuration);
    }
  }, [open, exitDuration]);

  useEffect(() => {
    return () => {
      if (timerRef.current) {
        window.clearTimeout(timerRef.current);
      }
    };
  }, []);

  if (!mounted) return null;

  return (
    <div
      className={`${className ?? ""} animated-panel${visible ? " is-visible" : ""}`}
    >
      {children}
    </div>
  );
}