import { Button } from "./components/ui/button";
import { AppNode, AppState, Message, nodeLabel, useMessages, useProjectId } 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";
import { CircleAlert, CircleX } from "lucide-react";

export function Messages() {
	const nodes = useNodes<AppNode>();
	const projectId = useProjectId();
	const [nodeMap, setNodeMap] = useState<Map<string, AppNode>>(new Map());
	useEffect(() => {
		setNodeMap(new Map(nodes.map((n) => [n.id, n])));
	}, [nodes, setNodeMap]);
	const onClick = useCallback((_?: (state: AppState) => void) => {
		return () => {
			// TODO(gio): visual hints
			// if (fn) {
			// 	fn(store);
			// }
		};
	}, []);
	const messages = useMessages();
	const [grouped, setGrouped] = useState<Map<string, Message[]>>(new Map());
	useEffect(() => {
		const g = new Map<string, Message[]>();
		if (projectId == null) {
			g.set("global", [
				{
					id: "global",
					nodeId: undefined,
					message: "Create a new project or select existing one to get started",
					type: "FATAL",
				},
			]);
		} else {
			messages.forEach((m) => {
				const id = m.nodeId || "global";
				const existing: Message[] = g.get(id) || [];
				existing.push(m);
				g.set(id, existing);
			});
		}
		setGrouped(g);
	}, [projectId, 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 className="h-5 min-w-5 rounded-full px-2 font-mono tabular-nums">
							{messages.length}
						</Badge>
						<div>{id === "global" ? "Global" : nodeLabel(nodeMap.get(id)!)}</div>
					</AccordionTrigger>
					<AccordionContent className="flex flex-col !px-1">
						{messages.map((m) => (
							<Button
								key={m.id}
								variant="ghost"
								className="justify-start !h-fit !py-0 flex flex-row gap-1 items-center"
								onMouseOver={onClick(m.onHighlight)}
								onMouseLeave={onClick(m.onLooseHighlight)}
								onClick={onClick(m.onClick)}
							>
								{m.type === "WARNING" && <CircleAlert className="w-4 h-4" color="brown" />}
								{m.type === "FATAL" && <CircleX className="w-4 h-4" color="red" />}
								{m.type === "INFO" && <div className="w-4 h-4" />}
								<div>{m.message}</div>
							</Button>
						))}
					</AccordionContent>
				</AccordionItem>
			))}
		</Accordion>
	);
}
