import {
	autoUpdate,
	flip,
	offset,
	shift,
	useDismiss,
	useFloating,
	useHover,
	useInteractions,
} from "@floating-ui/react";
import { type ReactElement, type ReactNode, useState } from "react";

import { twMerge } from "@utils/tailwindMerge";

export const Tooltip = (props: {
	content: ReactElement | string | number;
	children: ReactNode;
	placement?: "top";
	tooltipClassName?: string;
	underline?: boolean;
}) => {
	const [isOpen, setIsOpen] = useState<boolean>(false);

	const { refs, floatingStyles, context } = useFloating({
		open: isOpen,
		onOpenChange: setIsOpen,
		middleware: [offset(3), shift(), flip()],
		whileElementsMounted: autoUpdate,
	});

	const hover = useHover(context, { move: false });
	const dismiss = useDismiss(context);

	const { getReferenceProps, getFloatingProps } = useInteractions([
		hover,
		dismiss,
	]);

	const handleMouseEnter = () => setIsOpen(true);
	const handleMouseLeave = () => setIsOpen(false);

	return (
		<>
			<span
				ref={refs.setReference}
				{...getReferenceProps()}
				onMouseEnter={handleMouseEnter}
				onMouseLeave={handleMouseLeave}
				className={`bn-h-fit bn-inline-flex bn-items-center bn-border-y bn-border-dotted bn-border-t-transparent ${props.underline ? "bn-border-b-text-secondary" : "bn-border-b-transparent"}`}
			>
				{props.children}
			</span>
			{isOpen && (
				<span
					ref={refs.setFloating}
					style={floatingStyles}
					{...getFloatingProps()}
					onMouseOver={handleMouseEnter}
					onFocus={handleMouseEnter}
					onMouseOut={handleMouseLeave}
					onBlur={handleMouseLeave}
					className={twMerge(
						"bn-bg-[#1a1b1e] bn-border bn-border-solid bn-border-[#242629] bn-text-white bn-text-sm bn-font-medium bn-rounded-md bn-px-1.5 bn-py-1 bn-relative bn-z-10",
						props.tooltipClassName,
					)}
				>
					{props.content}
				</span>
			)}
		</>
	);
};
