import {
	type ConditionId,
	getConditionDescription,
	getConditionsForEdition,
} from "@initiative/domain";
import { useLayoutEffect, useRef, useState } from "react";
import { createPortal } from "react-dom";
import { useRulesEditionContext } from "../contexts/rules-edition-context.js";
import { useClickOutside } from "../hooks/use-click-outside.js";
import { cn } from "../lib/utils";
import {
	CONDITION_COLOR_CLASSES,
	CONDITION_ICON_MAP,
} from "./condition-styles.js";
import { Tooltip } from "./ui/tooltip.js";

interface ConditionPickerProps {
	anchorRef: React.RefObject<HTMLElement | null>;
	activeConditions: readonly ConditionId[] | undefined;
	onToggle: (conditionId: ConditionId) => void;
	onClose: () => void;
}

export function ConditionPicker({
	anchorRef,
	activeConditions,
	onToggle,
	onClose,
}: Readonly<ConditionPickerProps>) {
	const ref = useRef<HTMLDivElement>(null);
	const [pos, setPos] = useState<{
		top: number;
		left: number;
		maxHeight: number;
	} | null>(null);

	useLayoutEffect(() => {
		const anchor = anchorRef.current;
		const el = ref.current;
		if (!anchor || !el) return;

		const anchorRect = anchor.getBoundingClientRect();
		const menuHeight = el.scrollHeight;
		const pad = 8;

		const spaceBelow = window.innerHeight - anchorRect.bottom - pad;
		const spaceAbove = anchorRect.top - pad;
		const openBelow = spaceBelow >= menuHeight || spaceBelow >= spaceAbove;

		const top = openBelow
			? anchorRect.bottom + 4
			: Math.max(pad, anchorRect.top - Math.min(menuHeight, spaceAbove) - 4);
		const maxHeight = openBelow ? spaceBelow : Math.min(menuHeight, spaceAbove);

		setPos({ top, left: anchorRect.left, maxHeight });
	}, [anchorRef]);

	useClickOutside(ref, onClose);

	const { edition } = useRulesEditionContext();
	const conditions = getConditionsForEdition(edition);
	const active = new Set(activeConditions ?? []);

	return createPortal(
		<div
			ref={ref}
			className="card-glow fixed z-50 w-fit overflow-y-auto rounded-lg border border-border bg-background p-1"
			style={
				pos
					? { top: pos.top, left: pos.left, maxHeight: pos.maxHeight }
					: { visibility: "hidden" as const }
			}
		>
			{conditions.map((def) => {
				const Icon = CONDITION_ICON_MAP[def.iconName];
				if (!Icon) return null;
				const isActive = active.has(def.id);
				const colorClass =
					CONDITION_COLOR_CLASSES[def.color] ?? "text-muted-foreground";
				return (
					<Tooltip
						key={def.id}
						content={getConditionDescription(def, edition)}
						className="block"
					>
						<button
							type="button"
							className={cn(
								"flex w-full items-center gap-2 rounded px-2 py-1 text-sm transition-colors hover:bg-hover-neutral-bg",
								isActive && "bg-card/50",
							)}
							onClick={() => onToggle(def.id)}
						>
							<Icon
								size={14}
								className={isActive ? colorClass : "text-muted-foreground"}
							/>
							<span
								className={
									isActive ? "text-foreground" : "text-muted-foreground"
								}
							>
								{def.label}
							</span>
						</button>
					</Tooltip>
				);
			})}
		</div>,
		document.body,
	);
}
