import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
import { useState, useEffect, useMemo, useCallback } from "react";
import { getAgentsGrouped, getClosedAgentsByProfile, deleteAgent, renameAgent, } from "../editor/services/agentService";
import { parseAgentRunStatusData, shouldIgnoreReplayRunStart, } from "../editor/services/agentStatus";
import { cn } from "../lib/utils";
import { RefreshCw, List, Layers, Plus, ArrowLeft } from "lucide-react";
import { SearchInput } from "../components/SearchInput";
import { PageHeader } from "../components/PageHeader";
import { useEditContext } from "../editor/client/editContext";
import { AgentCard } from "./AgentCard";
import { ProfileAgentsGroup } from "./ProfileAgentsGroup";
import { DateAgentsGroup } from "./DateAgentsGroup";
import { Switch } from "../components/ui/switch";
import { Button } from "../components/ui/button";
import { AgentGalleryView } from "./AgentGalleryView";
import { RenameAgentDialog } from "./RenameAgentDialog";
import { Spinner } from "../editor/ui/Spinner";
/**
 * Unified agents overview: search/filter, active agents and closed history.
 * Creating a new agent happens in a modal accessed from the toolbar.
 */
export function AgentsView({ onSelectAgent, selectedAgentId, compact = false, onRequestCreateAgent, hideNewAgentButton = false, showCompactHeader = false, toolbarActions, showProfileIcons = true, } = {}) {
    const getAgentSortDate = useCallback((agent) => agent.lastMessageDate || agent.updatedDate, []);
    const sortAgentsByRecentActivity = useCallback((agents) => [...agents].sort((a, b) => new Date(getAgentSortDate(b)).getTime() -
        new Date(getAgentSortDate(a)).getTime()), [getAgentSortDate]);
    const sortProfileGroupsAgents = useCallback((groups) => groups.map((group) => ({
        ...group,
        agents: sortAgentsByRecentActivity(group.agents),
    })), [sortAgentsByRecentActivity]);
    const editContext = useEditContext();
    const [activeAgents, setActiveAgents] = useState([]);
    const [profileGroups, setProfileGroups] = useState([]);
    const [expandedProfiles, setExpandedProfiles] = useState(new Set());
    const [collapsedDateBuckets, setCollapsedDateBuckets] = useState(new Set());
    const [loadingMoreForProfile, setLoadingMoreForProfile] = useState(null);
    const [loading, setLoading] = useState(true);
    const [initialLoad, setInitialLoad] = useState(true);
    const [error, setError] = useState(null);
    const [, setRefreshing] = useState(false);
    const [searchTerm, setSearchTerm] = useState("");
    const [debouncedSearchTerm, setDebouncedSearchTerm] = useState("");
    const [showOnlyMyAgents, setShowOnlyMyAgents] = useState(true);
    const [historyViewMode, setHistoryViewMode] = useState("flat");
    const [viewMode, setViewMode] = useState("list");
    const [renameTarget, setRenameTarget] = useState(null);
    const handleNewAgentClick = () => {
        if (onRequestCreateAgent) {
            onRequestCreateAgent();
        }
        else {
            setViewMode("create");
        }
    };
    // Debounce search term
    useEffect(() => {
        const timer = setTimeout(() => {
            setDebouncedSearchTerm(searchTerm);
        }, 400);
        return () => clearTimeout(timer);
    }, [searchTerm]);
    const loadAgents = useCallback(async () => {
        try {
            setLoading(true);
            setError(null);
            const response = await getAgentsGrouped(debouncedSearchTerm || undefined, !showOnlyMyAgents, // includeShared
            true);
            setActiveAgents(sortAgentsByRecentActivity(response.activeAgents));
            setProfileGroups(sortProfileGroupsAgents(response.closedAgentsByProfile));
        }
        catch (err) {
            console.error("Failed to load agents:", err);
            setError(err?.message || "Failed to load agents. Please try again later.");
        }
        finally {
            setLoading(false);
            setRefreshing(false);
            setInitialLoad(false);
        }
    }, [
        debouncedSearchTerm,
        showOnlyMyAgents,
        sortAgentsByRecentActivity,
        sortProfileGroupsAgents,
    ]);
    // Initial load and reload when filters change
    useEffect(() => {
        loadAgents();
    }, [loadAgents]);
    // Subscribe to websocket messages for real-time agent updates
    useEffect(() => {
        if (!editContext?.addSocketMessageListener)
            return;
        const unsubscribe = editContext.addSocketMessageListener((message) => {
            if (message.type === "agent:run:start") {
                const { agentId, agentName, timestamp } = message.payload;
                if (!agentId || !agentName) {
                    console.warn("Invalid agent:run:start message payload:", message.payload);
                    return;
                }
                setActiveAgents((prevAgents) => {
                    const existingAgentIndex = prevAgents.findIndex((agent) => agent.id === agentId);
                    if (existingAgentIndex !== -1) {
                        const updatedAgents = [...prevAgents];
                        const existingAgent = updatedAgents[existingAgentIndex];
                        if (shouldIgnoreReplayRunStart(existingAgent.status, existingAgent.updatedDate, typeof timestamp === "string" ? timestamp : undefined)) {
                            return prevAgents;
                        }
                        updatedAgents[existingAgentIndex] = {
                            ...existingAgent,
                            name: agentName,
                            status: "running",
                            updatedDate: new Date().toISOString(),
                        };
                        return updatedAgents;
                    }
                    else {
                        loadAgents();
                        return prevAgents;
                    }
                });
            }
            else if (message.type === "agent:info:updated") {
                const { agentId, agentName, agentDescription } = message.payload || {};
                if (!agentId)
                    return;
                setActiveAgents((prevAgents) => {
                    const existingIndex = prevAgents.findIndex((a) => a.id === agentId);
                    if (existingIndex === -1)
                        return prevAgents;
                    const updatedAgents = [...prevAgents];
                    const existingAgent = updatedAgents[existingIndex];
                    updatedAgents[existingIndex] = {
                        ...existingAgent,
                        ...(agentName !== undefined && { name: agentName }),
                        ...(agentDescription !== undefined && {
                            description: agentDescription,
                        }),
                        updatedDate: new Date().toISOString(),
                    };
                    return updatedAgents;
                });
            }
            else if (message.type === "agent:run:closed") {
                loadAgents();
            }
            else if (message.type === "agent:run:status") {
                const { agentId, data } = message.payload || {};
                if (!agentId || !data)
                    return;
                const mappedStatus = parseAgentRunStatusData(data);
                if (!mappedStatus)
                    return;
                setActiveAgents((prevAgents) => {
                    const existingIndex = prevAgents.findIndex((a) => a.id === agentId);
                    if (existingIndex === -1)
                        return prevAgents;
                    const updatedAgents = [...prevAgents];
                    const existingAgent = updatedAgents[existingIndex];
                    updatedAgents[existingIndex] = {
                        ...existingAgent,
                        status: mappedStatus,
                        statusMessage: data.statusMessage || existingAgent.statusMessage,
                        updatedDate: new Date().toISOString(),
                    };
                    return updatedAgents;
                });
            }
            else if (message.type === "agent:run:complete" ||
                message.type === "agent:run:error") {
                loadAgents();
            }
        });
        return unsubscribe;
    }, [editContext?.addSocketMessageListener, loadAgents]);
    const sortedActiveAgents = useMemo(() => {
        return sortAgentsByRecentActivity(activeAgents);
    }, [activeAgents, sortAgentsByRecentActivity]);
    const handleRefresh = async () => {
        setRefreshing(true);
        await loadAgents();
    };
    const handleToggleProfile = (profileId) => {
        const key = profileId || "null";
        setExpandedProfiles((prev) => {
            const newSet = new Set(prev);
            if (newSet.has(key)) {
                newSet.delete(key);
            }
            else {
                newSet.add(key);
            }
            return newSet;
        });
    };
    const handleToggleDateBucket = (key) => {
        setCollapsedDateBuckets((prev) => {
            const newSet = new Set(prev);
            if (newSet.has(key)) {
                newSet.delete(key);
            }
            else {
                newSet.add(key);
            }
            return newSet;
        });
    };
    const handleLoadMoreForProfile = async (profileId) => {
        if (!profileId || loadingMoreForProfile)
            return;
        try {
            setLoadingMoreForProfile(profileId);
            const profileGroup = profileGroups.find((g) => g.profileId === profileId);
            if (!profileGroup)
                return;
            const currentCount = profileGroup.agents.length;
            const response = await getClosedAgentsByProfile(profileId, currentCount, 10, debouncedSearchTerm || undefined);
            setProfileGroups((prevGroups) => prevGroups.map((group) => {
                if (group.profileId === profileId) {
                    return {
                        ...group,
                        agents: sortAgentsByRecentActivity([
                            ...group.agents,
                            ...response.agents,
                        ]),
                    };
                }
                return group;
            }));
        }
        catch (err) {
            console.error("Failed to load more agents:", err);
            editContext?.showToast(`Failed to load more agents: ${err?.message || "Unknown error"}`);
        }
        finally {
            setLoadingMoreForProfile(null);
        }
    };
    const handleOpenAgent = (agent, event) => {
        if (onSelectAgent) {
            onSelectAgent(agent, { split: !!event?.altKey });
            return;
        }
        editContext?.setShowAgentsPanel?.(true);
        setTimeout(() => {
            window.dispatchEvent(new CustomEvent("editor:openAgent", {
                detail: { agentId: agent.id },
            }));
        }, 100);
    };
    const handleDeleteAgent = async (agentId, agentName, event) => {
        event.stopPropagation();
        editContext?.confirm({
            header: "Delete Agent",
            message: `Are you sure you want to permanently delete "${agentName}"?`,
            acceptLabel: "Delete Agent",
            accept: async () => {
                try {
                    await deleteAgent(agentId);
                    setActiveAgents((prev) => prev.filter((a) => a.id !== agentId));
                    setProfileGroups((prevGroups) => prevGroups.map((group) => ({
                        ...group,
                        agents: group.agents.filter((a) => a.id !== agentId),
                        totalClosedCount: Math.max(0, group.totalClosedCount - 1),
                    })));
                }
                catch (err) {
                    console.error("Failed to delete agent:", err);
                    editContext?.showToast(`Failed to delete agent: ${err?.message || "Unknown error"}`);
                }
            },
            showCancel: true,
        });
    };
    const handleRenameAgent = (agentId, agentName) => {
        setRenameTarget({ id: agentId, name: agentName });
    };
    const performRename = async (newName) => {
        if (!renameTarget)
            return;
        const agentId = renameTarget.id;
        try {
            await renameAgent(agentId, newName);
            // Optimistic local update; the agent:info:updated WS message reconciles
            // other views.
            setActiveAgents((prev) => prev.map((a) => (a.id === agentId ? { ...a, name: newName } : a)));
            setProfileGroups((prevGroups) => prevGroups.map((group) => ({
                ...group,
                agents: group.agents.map((a) => a.id === agentId ? { ...a, name: newName } : a),
            })));
        }
        catch (err) {
            console.error("Failed to rename agent:", err);
            editContext?.showToast(`Failed to rename chat: ${err?.message || "Unknown error"}`);
        }
    };
    const handleAgentClick = (agent, event) => {
        if (onSelectAgent) {
            onSelectAgent(agent, { split: !!event?.altKey });
            return;
        }
        window.dispatchEvent(new CustomEvent("editor:selectAgent", {
            detail: { agentId: agent.id },
        }));
    };
    const handleCreateAgent = (profile) => {
        setViewMode("list");
        const agentDisplayName = profile.agentName || profile.displayTitle || profile.name;
        const agentId = crypto.randomUUID();
        const newAgent = {
            status: "new",
            id: agentId,
            name: agentDisplayName,
            updatedDate: new Date().toISOString(),
            userId: "",
            profileId: profile.id,
            profileName: profile.name,
            profileSvgIcon: profile.svgIcon,
        };
        if (onSelectAgent) {
            onSelectAgent(newAgent);
            return;
        }
        editContext?.setShowAgentsPanel?.(true);
        setTimeout(() => {
            window.dispatchEvent(new CustomEvent("editor:createAgentWithProfile", {
                detail: { agent: newAgent, profile },
            }));
        }, 100);
    };
    const formatDateTime = (dateString) => {
        try {
            const date = new Date(dateString);
            return date.toLocaleString(undefined, {
                year: "numeric",
                month: "numeric",
                day: "numeric",
                hour: "numeric",
                minute: "numeric",
                hour12: false,
            });
        }
        catch {
            return dateString;
        }
    };
    const totalActiveCount = activeAgents.length;
    const totalClosedCount = profileGroups.reduce((sum, group) => sum + group.totalClosedCount, 0);
    const listDensity = compact ? "compact" : "default";
    // Flatten all closed agents from all profile groups and sort by date (newest first)
    const flatClosedAgents = useMemo(() => {
        const allAgents = [];
        profileGroups.forEach((group) => {
            allAgents.push(...group.agents);
        });
        return allAgents.sort((a, b) => new Date(getAgentSortDate(b)).getTime() -
            new Date(getAgentSortDate(a)).getTime());
    }, [profileGroups, getAgentSortDate]);
    // Bucket flat closed agents by recency. Empty buckets are omitted.
    const dateBuckets = useMemo(() => {
        const startOfToday = new Date();
        startOfToday.setHours(0, 0, 0, 0);
        const startOfYesterday = new Date(startOfToday);
        startOfYesterday.setDate(startOfYesterday.getDate() - 1);
        const sevenDaysAgo = new Date(startOfToday);
        sevenDaysAgo.setDate(sevenDaysAgo.getDate() - 7);
        const thirtyDaysAgo = new Date(startOfToday);
        thirtyDaysAgo.setDate(thirtyDaysAgo.getDate() - 30);
        const buckets = [
            { key: "today", label: "Today", agents: [] },
            { key: "yesterday", label: "Yesterday", agents: [] },
            { key: "last7", label: "Last 7 Days", agents: [] },
            { key: "last30", label: "Last 30 Days", agents: [] },
            { key: "older", label: "Older", agents: [] },
        ];
        for (const agent of flatClosedAgents) {
            const d = new Date(getAgentSortDate(agent));
            if (d >= startOfToday)
                buckets[0].agents.push(agent);
            else if (d >= startOfYesterday)
                buckets[1].agents.push(agent);
            else if (d >= sevenDaysAgo)
                buckets[2].agents.push(agent);
            else if (d >= thirtyDaysAgo)
                buckets[3].agents.push(agent);
            else
                buckets[4].agents.push(agent);
        }
        return buckets.filter((b) => b.agents.length > 0);
    }, [flatClosedAgents, getAgentSortDate]);
    if (initialLoad && loading) {
        return (_jsxs("div", { className: "flex h-full items-center justify-center gap-2", children: [_jsx(Spinner, { size: "sm" }), _jsx("div", { className: "text-neutral-grey-50 text-[12px]", children: "Loading agents..." })] }));
    }
    const newAgentButton = viewMode === "list" && !hideNewAgentButton && (_jsxs(Button, { type: "button", variant: "outline", size: "lg", onClick: handleNewAgentClick, className: cn("border-border-default hover:border-neutral-grey-100 hover:bg-neutral-grey-5 h-[38px] justify-center gap-3 rounded bg-white text-[14px] font-medium shadow-none", toolbarActions ? "min-w-0 flex-1" : "w-full"), "data-testid": "add-agent-button", children: [_jsx("span", { children: "Start new chat" }), _jsx(Plus, { className: "size-5", strokeWidth: 1 })] }));
    return (_jsxs("div", { className: "absolute inset-0 flex flex-col bg-white", children: [(!compact || showCompactHeader) && (_jsx(PageHeader, { title: "AI Agents", description: "Build, run and orchestrate your AI workforce", variant: "workspace", className: "border-border-default border-b bg-white px-6 py-4" })), _jsx("div", { className: "relative flex flex-1 flex-col overflow-hidden", children: viewMode === "create" ? (_jsxs(_Fragment, { children: [_jsx("div", { className: "border-border-default shrink-0 border-b bg-white px-6 py-4", children: _jsxs("div", { className: "flex items-center gap-3", children: [_jsxs("button", { type: "button", onClick: () => setViewMode("list"), className: "text-neutral-grey-50 hover:bg-neutral-grey-5 hover:text-neutral-grey-100 inline-flex items-center gap-1.5 rounded-md px-2 py-1.5 text-[13px] font-medium transition-colors", "data-testid": "agents-create-back-button", children: [_jsx(ArrowLeft, { className: "size-4", strokeWidth: 1 }), "Back"] }), _jsx("span", { className: "text-neutral-grey-50", children: "/" }), _jsx("h2", { className: "text-neutral-grey-100 text-[12px] font-medium tracking-tight", children: "New Agent" }), _jsx("p", { className: "text-neutral-grey-50 ml-1 hidden text-[12px] sm:inline", children: "Pick a profile to start with" })] }) }), _jsx("div", { className: "relative flex-1 overflow-y-auto bg-white", children: _jsx(AgentGalleryView, { variant: "pane", onSelectProfile: handleCreateAgent }) })] })) : (_jsxs(_Fragment, { children: [_jsx("div", { className: cn("border-border-default shrink-0 border-b bg-white", compact ? "px-2 py-2" : "px-4 py-4"), children: _jsxs("div", { className: cn(compact ? "space-y-2" : "space-y-3"), children: [(newAgentButton || toolbarActions) && (_jsxs("div", { className: "flex min-w-0 items-center gap-2", children: [newAgentButton, toolbarActions && (_jsx("div", { className: "flex shrink-0 items-center gap-1", children: toolbarActions }))] })), _jsx("div", { className: "min-w-0", children: _jsx(SearchInput, { value: searchTerm, onChange: setSearchTerm, placeholder: "Search...", loading: loading && !initialLoad, size: "md", inputClassName: "text-[12px] placeholder:text-neutral-grey-50" }) }), _jsxs("div", { className: cn("flex min-w-0 items-center", compact ? "gap-2" : "gap-3"), children: [profileGroups.length > 0 && (_jsxs("div", { className: "border-border-default bg-neutral-grey-5 flex h-8 shrink-0 items-center overflow-hidden rounded border p-0.5", children: [_jsx("button", { type: "button", onClick: () => setHistoryViewMode("grouped"), className: cn("flex size-7 items-center justify-center rounded transition-colors", historyViewMode === "grouped"
                                                            ? "text-neutral-grey-100 bg-white shadow-sm"
                                                            : "text-neutral-grey-50 hover:text-neutral-grey-100"), title: "Grouped by profile", "aria-label": "Grouped by profile", children: _jsx(Layers, { className: "size-4", strokeWidth: 1 }) }), _jsx("button", { type: "button", onClick: () => setHistoryViewMode("flat"), className: cn("flex size-7 items-center justify-center rounded transition-colors", historyViewMode === "flat"
                                                            ? "text-neutral-grey-100 bg-white shadow-sm"
                                                            : "text-neutral-grey-50 hover:text-neutral-grey-100"), title: "Grouped by date", "aria-label": "Grouped by date", children: _jsx(List, { className: "size-4", strokeWidth: 1 }) })] })), _jsxs("label", { className: cn("text-neutral-grey-50 hover:text-neutral-grey-100 ml-auto flex shrink-0 cursor-pointer items-center justify-end gap-2 rounded text-right text-[12px] font-medium transition-colors", compact ? "min-h-8" : "min-h-10"), children: [_jsx("span", { className: "truncate select-none", children: "Show just my agents" }), _jsx(Switch, { checked: showOnlyMyAgents, onCheckedChange: (checked) => setShowOnlyMyAgents(checked === true), className: "data-[state=checked]:bg-neutral-grey-100 data-[state=unchecked]:bg-neutral-grey-15 h-[20px] w-[38px] p-[2px] shadow-none [&_[data-slot=switch-thumb]]:size-[16px] [&_[data-slot=switch-thumb]]:data-[state=checked]:translate-x-[18px]" })] })] })] }) }), _jsxs("div", { className: "relative flex-1 overflow-y-auto bg-white", children: [loading && !initialLoad && (_jsx("div", { className: "absolute top-2 left-1/2 z-10 -translate-x-1/2 rounded-md bg-white px-3 py-1.5 shadow-md", children: _jsxs("div", { className: "text-neutral-grey-50 flex items-center gap-2 text-[12px]", children: [_jsx(RefreshCw, { className: "size-3 animate-spin", strokeWidth: 1 }), _jsx("span", { children: "Loading..." })] }) })), error ? (_jsx("div", { className: "flex h-full items-center justify-center", children: _jsxs("div", { className: "max-w-md text-center", children: [_jsx("div", { className: "text-feedback-red mb-4 text-[12px]", children: error }), _jsx("button", { onClick: handleRefresh, className: "bg-feedback-blue hover:bg-feedback-blue rounded px-4 py-2 text-xs text-white", children: "Retry" })] }) })) : totalActiveCount === 0 &&
                                    totalClosedCount === 0 &&
                                    !loading ? (_jsx("div", { className: "text-neutral-grey-50 flex h-full items-center justify-center text-[12px]", children: searchTerm.trim()
                                        ? "No agents match your search"
                                        : "No agents found" })) : (_jsxs("div", { className: cn(compact ? "space-y-6 px-2 py-4" : "space-y-5 px-4 py-4", loading && "opacity-60"), children: [activeAgents.length > 0 && (_jsxs("div", { className: "space-y-1.5", children: [_jsx("div", { className: cn("text-neutral-grey-50 py-1.5 text-[12px] leading-5 font-medium", listDensity === "compact" ? "px-2" : "px-2.5"), children: "Active" }), _jsx("div", { className: cn(compact ? "space-y-0.5" : "space-y-1"), children: sortedActiveAgents.map((agent) => (_jsx(AgentCard, { agent: agent, onClick: handleAgentClick, onResume: handleOpenAgent, onDelete: handleDeleteAgent, onRename: handleRenameAgent, formatDateTime: formatDateTime, selected: selectedAgentId === agent.id, density: listDensity, showProfileIcon: showProfileIcons }, agent.id))) })] })), profileGroups.length > 0 && (_jsx("div", { className: cn(compact ? "space-y-6" : "space-y-2"), children: historyViewMode === "grouped" ? (_jsx("div", { className: cn("bg-white", compact ? "space-y-0.5" : "space-y-2"), children: profileGroups.map((profileGroup) => {
                                                    const profileKey = profileGroup.profileId || "null";
                                                    const isExpanded = expandedProfiles.has(profileKey);
                                                    const isLoadingMore = loadingMoreForProfile === profileGroup.profileId;
                                                    const hasMore = profileGroup.agents.length <
                                                        profileGroup.totalClosedCount;
                                                    return (_jsx(ProfileAgentsGroup, { profileGroup: profileGroup, isExpanded: isExpanded, isLoadingMore: isLoadingMore, hasMore: hasMore, onToggle: () => handleToggleProfile(profileGroup.profileId), onLoadMore: () => handleLoadMoreForProfile(profileGroup.profileId), onAgentClick: handleAgentClick, onResumeAgent: handleOpenAgent, onDeleteAgent: handleDeleteAgent, onRenameAgent: handleRenameAgent, formatDateTime: formatDateTime, selectedAgentId: selectedAgentId, density: listDensity, showProfileIcons: showProfileIcons }, profileKey));
                                                }) })) : (_jsx("div", { className: cn(compact ? "space-y-6" : "space-y-5"), children: dateBuckets.map((bucket) => (_jsx(DateAgentsGroup, { bucketKey: bucket.key, label: bucket.label, agents: bucket.agents, isExpanded: !collapsedDateBuckets.has(bucket.key), onToggle: () => handleToggleDateBucket(bucket.key), onAgentClick: handleAgentClick, onResumeAgent: handleOpenAgent, onDeleteAgent: handleDeleteAgent, onRenameAgent: handleRenameAgent, formatDateTime: formatDateTime, selectedAgentId: selectedAgentId, density: listDensity, showProfileIcons: showProfileIcons }, bucket.key))) })) }))] }))] })] })) }), _jsx(RenameAgentDialog, { open: renameTarget !== null, initialName: renameTarget?.name ?? "", onOpenChange: (open) => {
                    if (!open)
                        setRenameTarget(null);
                }, onRename: performRename })] }));
}
//# sourceMappingURL=AgentsView.js.map