import { AnimatePresence, motion } from "framer-motion";
import { type ReactNode, useEffect } from "react";

import { useTheme } from "@hooks/useTheme";
import { getBorderRadius } from "@utils/getBorderRadius";
import { twMerge } from "@utils/tailwindMerge";

export type SlideInPanelProps = {
	children: ReactNode;
	isVisible: boolean;
	closePanel: () => void;
	cardClasses?: string;
	trayClasses?: string;
	animationDirection?: "bottom" | "right";
	minHeight?: number;
};

export const SlideInPanel = ({
	children,
	isVisible,
	closePanel,
	cardClasses,
	trayClasses,
	animationDirection = "bottom",
	minHeight = 0,
}: SlideInPanelProps) => {
	const theme = useTheme();
	const cardStyle = twMerge(
		"bn-bg-layer-1 bn-max-h-full bn-flex bn-flex-col bn-absolute bn-bottom-0 bn-left-0 bn-w-full bn-overflow-y-auto bn-border bn-border-solid bn-border-b-none bn-border-subtle",
		cardClasses,
	);

	const trayStyle = twMerge(
		"bn-backdrop-blur-md bn-absolute bn-w-full bn-top-0 bn-left-0 bn-border bn-border-solid bn-border-strong !bn-z-10",
		// Only add bn-h-full if minHeight is not provided
		!minHeight && "bn-h-full",
		trayClasses,
	);

	// @fixme: multiple effects are being called on escape
	useEffect(() => {
		const handleKeyDown = (event: { key: string }) => {
			if (event.key === "Escape") {
				closePanel();
			}
		};

		document.addEventListener("keydown", handleKeyDown);

		return () => {
			document.removeEventListener("keydown", handleKeyDown);
		};
	}, [closePanel]);

	// Animation variants based on direction
	const getAnimationVariants = () => {
		if (animationDirection === "right") {
			return {
				initial: { opacity: 0, x: 50, zIndex: "auto" },
				animate: { opacity: 1, x: 0, zIndex: "auto" },
				exit: { opacity: 0, x: 50, zIndex: -1 },
			};
		}
		// Default bottom animation
		return {
			initial: { opacity: 0, y: 50, zIndex: "auto" },
			animate: { opacity: 1, y: 0, zIndex: "auto" },
			exit: { opacity: 0, y: 50, zIndex: -1 },
		};
	};

	const variants = getAnimationVariants();

	return (
		<AnimatePresence>
			{isVisible && (
				<motion.div
					// TODO: zIndex is not working as expected (Specifically on the recipient address modal after connecting a new wallet)
					initial={variants.initial}
					animate={variants.animate}
					exit={variants.exit}
					transition={{
						duration: 0.2,
					}}
					className={trayStyle}
					style={{
						borderRadius: getBorderRadius(theme.borderRadius),
						...(minHeight ? { height: `${minHeight}px` } : {}),
					}}
					onClick={closePanel}
				>
					{/* biome-ignore lint/a11y/useKeyWithClickEvents: <explanation> */}
					<div
						onClick={(e) => e.stopPropagation()}
						className={cardStyle}
						style={{ borderRadius: getBorderRadius(theme.borderRadius) }}
					>
						{children}
					</div>
				</motion.div>
			)}
		</AnimatePresence>
	);
};
