import { useState, useEffect, useRef } from "react";
import { getActiveAgents } from "../services/agentService";
import { isActiveSidebarAgentStatus, isTerminalAgentStatus, parseAgentStatus, shouldIgnoreReplayRunStart, } from "../services/agentStatus";
import { useEditContext } from "../client/editContext";
import { toast } from "sonner";
import { DIALOG_TYPES } from "./dialogs/agentDialogTypes";
function isAutomaticDialogType(dialogType) {
    return (dialogType === DIALOG_TYPES.CAPTURE_PAGE_SCREENSHOT ||
        dialogType === DIALOG_TYPES.CAPTURE_PAGE_DOM);
}
/**
 * Hook to track the status of all active agents
 * Uses WebSocket messages for real-time updates instead of polling
 */
export function useAgentStatus(enabled = true) {
    const [agents, setAgents] = useState([]);
    const editContext = useEditContext();
    // Track which agents we've shown "input required" toast for to avoid duplicates
    const inputRequiredToastShownRef = useRef(new Set());
    useEffect(() => {
        if (!enabled) {
            setAgents([]);
            return;
        }
        // Create an AbortController to cancel the fetch when the component unmounts
        const abortController = new AbortController();
        const fetchAgentStatus = async () => {
            try {
                const response = await getActiveAgents({
                    limit: 1000,
                    includeShared: false, // Only show user's own agents in status
                    includeOwned: true,
                    excludeClosed: true,
                    signal: abortController.signal,
                });
                const activeAgents = response.agents;
                const filteredAgents = (activeAgents || []).filter((agent) => !isTerminalAgentStatus(agent.status));
                setAgents(filteredAgents);
            }
            catch (error) {
                // Ignore abort errors - these are expected when the component unmounts
                if (error instanceof Error && error.name === "AbortError") {
                    return;
                }
                console.error("Failed to fetch agent status:", error);
                // Don't update agents on error to keep showing last known state
            }
        };
        // Initial fetch to populate state, and refetch on WebSocket reconnect
        fetchAgentStatus();
        return () => {
            abortController.abort();
        };
    }, [enabled, editContext?.socketConnectionVersion]);
    useEffect(() => {
        if (!enabled || !editContext?.addSocketMessageListener)
            return;
        // Subscribe to WebSocket messages for agent status updates
        const handleMessage = (message) => {
            if (message.type === "agent:run:start") {
                // Update agent status in real-time from WebSocket message
                const { agentId, status, name, agentName, timestamp } = message.payload || {};
                if (!agentId)
                    return;
                // For agent:run:start messages, default status to "running"
                const effectiveStatus = parseAgentStatus(status) ?? "running";
                const effectiveName = name || agentName || "Agent";
                setAgents((prevAgents) => {
                    // Check if agent exists in current list
                    const existingIndex = prevAgents.findIndex((a) => a.id === agentId);
                    if (existingIndex !== -1) {
                        // Update existing agent status
                        const updatedAgents = [...prevAgents];
                        const existingAgent = updatedAgents[existingIndex];
                        if (shouldIgnoreReplayRunStart(existingAgent.status, existingAgent.updatedDate, typeof timestamp === "string" ? timestamp : undefined)) {
                            return prevAgents;
                        }
                        updatedAgents[existingIndex] = {
                            id: existingAgent.id,
                            name: effectiveName,
                            userId: existingAgent.userId,
                            updatedDate: existingAgent.updatedDate,
                            status: effectiveStatus,
                        };
                        // Remove agent from list if status is completed, error, or closed
                        if (isTerminalAgentStatus(effectiveStatus)) {
                            return updatedAgents.filter((a) => a.id !== agentId);
                        }
                        return updatedAgents;
                    }
                    else if (isActiveSidebarAgentStatus(effectiveStatus)) {
                        // Add new agent to the list if it's in an active state
                        const newAgent = {
                            id: agentId,
                            name: effectiveName,
                            userId: "",
                            status: effectiveStatus,
                            updatedDate: new Date().toISOString(),
                        };
                        return [...prevAgents, newAgent];
                    }
                    return prevAgents;
                });
            }
            else if (message.type === "agent:run:status") {
                // Unified status updates with data.state
                const { agentId, data } = message.payload || {};
                if (!agentId)
                    return;
                const mappedStatus = parseAgentStatus(data?.state);
                if (!mappedStatus)
                    return;
                const dialogType = data?.dialogType ||
                    data?.DialogType;
                if (mappedStatus === "waitingForInput" &&
                    isAutomaticDialogType(dialogType)) {
                    return;
                }
                // Show toast notification for WaitingForInput status (once per agent)
                if (mappedStatus === "waitingForInput") {
                    if (!inputRequiredToastShownRef.current.has(agentId)) {
                        inputRequiredToastShownRef.current.add(agentId);
                        const agentName = data?.name || "Agent";
                        const dialogTitle = data?.title || "";
                        toast.info(dialogTitle
                            ? `${agentName}: ${dialogTitle}`
                            : `${agentName} needs your input`, {
                            description: "An agent is waiting for your response",
                            duration: 8000,
                            action: {
                                label: "View",
                                onClick: () => {
                                    // Navigate to agents view - this will be handled by the parent component
                                    window.dispatchEvent(new CustomEvent("navigate-to-agent", { detail: { agentId } }));
                                },
                            },
                        });
                    }
                }
                else {
                    // Clear the toast tracking when agent moves to another status
                    inputRequiredToastShownRef.current.delete(agentId);
                }
                setAgents((prevAgents) => {
                    const existingIndex = prevAgents.findIndex((a) => a.id === agentId);
                    const isTerminal = isTerminalAgentStatus(mappedStatus);
                    if (existingIndex !== -1) {
                        if (isTerminal) {
                            // Remove terminal states from active list
                            return prevAgents.filter((a) => a.id !== agentId);
                        }
                        const updated = [...prevAgents];
                        updated[existingIndex] = {
                            ...updated[existingIndex],
                            status: mappedStatus,
                            updatedDate: new Date().toISOString(),
                        };
                        return updated;
                    }
                    // Add new if active state
                    if (isActiveSidebarAgentStatus(mappedStatus)) {
                        const newAgent = {
                            id: agentId,
                            name: data?.name || "Agent",
                            userId: "",
                            status: mappedStatus,
                            updatedDate: new Date().toISOString(),
                        };
                        return [...prevAgents, newAgent];
                    }
                    return prevAgents;
                });
            }
            else if (message.type === "agent:run:complete") {
                const { agentId } = message.payload || {};
                if (!agentId)
                    return;
                setAgents((prevAgents) => prevAgents.filter((a) => a.id !== agentId));
            }
            else if (message.type === "agent:run:error") {
                const { agentId } = message.payload || {};
                if (!agentId)
                    return;
                setAgents((prevAgents) => prevAgents.filter((a) => a.id !== agentId));
            }
            else if (message.type === "agent:run:closed") {
                // Remove agent from list when it's closed
                const { agentId } = message.payload || {};
                if (!agentId)
                    return;
                setAgents((prevAgents) => prevAgents.filter((a) => a.id !== agentId));
            }
        };
        // Register the listener and get cleanup function
        const unsubscribe = editContext.addSocketMessageListener(handleMessage);
        // Cleanup
        return () => {
            unsubscribe();
        };
    }, [enabled, editContext]);
    const running = agents.filter((a) => a.status === "running").length;
    const waitingForApproval = agents.filter((a) => a.status === "waitingForApproval").length;
    const costLimitReached = agents.filter((a) => a.status === "costLimitReached").length;
    const waitingForInput = agents.filter((a) => a.status === "waitingForInput").length;
    return {
        total: agents.length,
        running,
        waitingForApproval,
        costLimitReached,
        waitingForInput,
        hasActivity: agents.length > 0,
        agents,
    };
}
//# sourceMappingURL=useAgentStatus.js.map