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>>();
    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)}>
                {[...grouped.entries()].map(([id, messages]) => (
                    <AccordionItem key={id} value={id}>
                        <AccordionTrigger className="flex flex-row-reverse !space-x-4 !justify-end">
                            <Badge>{messages.length}</Badge>
                            <div>{id === "global" ? "Global" : nodeLabel(nodeMap?.get(id)!)}</div>
                        </AccordionTrigger>
                        <AccordionContent>
                            <div className="flex flex-col space-y-1">
                                {messages.map((m) => (
                                    <Button key={m.id} variant="ghost" style={{ justifyContent: "flex-start" }} onMouseOver={onClick(m.onHighlight)} onMouseLeave={onClick(m.onLooseHighlight)} onClick={onClick(m.onClick)}>{m.message}</Button>
                                ))}
                            </div>
                        </AccordionContent>
                    </AccordionItem>
                ))}
            </Accordion>
    )
}