import { Button } from "./components/ui/button";
import { AppNode, AppState, Message, nodeLabel, useMessages, useStateStore } from "./lib/state";
import { useCallback, useEffect, useState } from "react";
import { useNodes } from "@xyflow/react";
import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from "./components/ui/accordion";
import { Badge } from "./components/ui/badge";

export function Messages() {
	const store = useStateStore();
	const nodes = useNodes<AppNode>();
	const [nodeMap, setNodeMap] = useState<Map<string, AppNode>>(new Map());
	useEffect(() => {
		setNodeMap(new Map(nodes.map((n) => [n.id, n])));
	}, [nodes, setNodeMap]);
	const onClick = useCallback(
		(fn?: (state: AppState) => void) => {
			return () => {
				if (fn) {
					fn(store);
				}
			};
		},
		[store],
	);
	const messages = useMessages();
	const [grouped, setGrouped] = useState<Map<string, Message[]>>(new Map());
	useEffect(() => {
		const g = new Map<string, Message[]>();
		messages.forEach((m) => {
			const id = m.nodeId || "global";
			const existing: Message[] = g.get(id) || [];
			existing.push(m);
			g.set(id, existing);
		});
		setGrouped(g);
	}, [messages, setGrouped]);
	const [open, setOpen] = useState<string[]>([...grouped.keys()]);
	useEffect(() => {
		// TODO(gio): do not reopen closed ones
		setOpen([...grouped.keys()]);
	}, [grouped, setOpen]);
	return (
		<Accordion type="multiple" value={open} onValueChange={(v) => setOpen(v)} className="h-full max-h-full">
			{[...grouped.entries()].map(([id, messages]) => (
				<AccordionItem key={id} value={id}>
					<AccordionTrigger className="flex flex-row-reverse !gap-1 !justify-end !h-fit !py-0">
						<Badge>{messages.length}</Badge>
						<div>{id === "global" ? "Global" : nodeLabel(nodeMap.get(id)!)}</div>
					</AccordionTrigger>
					<AccordionContent>
						<div className="flex flex-col !px-4">
							{messages.map((m) => (
								<Button
									key={m.id}
									variant="ghost"
									className="justify-start !h-fit !py-0"
									onMouseOver={onClick(m.onHighlight)}
									onMouseLeave={onClick(m.onLooseHighlight)}
									onClick={onClick(m.onClick)}
								>
									{m.message}
								</Button>
							))}
						</div>
					</AccordionContent>
				</AccordionItem>
			))}
		</Accordion>
	);
}
