"use client";
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { useCallback, useEffect, useMemo, useState } from "react";
import { ExternalLink } from "lucide-react";
import { getProject, getTasks, } from "../../../../task-board/services/taskService";
import { useEditContext } from "../../../client/editContext";
import { useParheliaSettings } from "../../../hooks/useParheliaSettings";
import { getAgent as fetchAgent, } from "../../../services/agentService";
const REFRESH_INTERVAL_MS = 10_000;
function asRecord(value) {
    return value && typeof value === "object" && !Array.isArray(value)
        ? value
        : undefined;
}
function getString(record, ...keys) {
    if (!record)
        return undefined;
    for (const key of keys) {
        const value = record[key];
        if (typeof value === "string" && value.trim())
            return value;
    }
    return undefined;
}
function getTrackedProjectFromAdditionalData(additionalData) {
    const data = asRecord(additionalData);
    const projectId = getString(data, "createdProjectId", "CreatedProjectId");
    if (!projectId)
        return null;
    return {
        projectId,
        title: getString(data, "createdProjectTitle", "CreatedProjectTitle"),
    };
}
function getTrackedProjectFromAgentContext(agentContext) {
    if (!agentContext)
        return null;
    try {
        const context = typeof agentContext === "string"
            ? JSON.parse(agentContext)
            : agentContext;
        const record = asRecord(context);
        return getTrackedProjectFromAdditionalData(record?.additionalData ?? record?.AdditionalData);
    }
    catch {
        return null;
    }
}
function getTrackedProjectFromMessages(messages) {
    if (!messages?.length)
        return null;
    for (let messageIndex = messages.length - 1; messageIndex >= 0; messageIndex -= 1) {
        const toolCalls = messages[messageIndex]?.toolCalls;
        if (!toolCalls?.length)
            continue;
        for (let callIndex = toolCalls.length - 1; callIndex >= 0; callIndex -= 1) {
            const toolCall = toolCalls[callIndex];
            if (toolCall?.functionName !== "create-project" ||
                toolCall.functionError ||
                !toolCall.functionResult) {
                continue;
            }
            try {
                const result = JSON.parse(toolCall.functionResult);
                const record = asRecord(result);
                const projectId = getString(record, "projectId", "ProjectId");
                if (projectId) {
                    return {
                        projectId,
                        title: getString(record, "title", "Title"),
                    };
                }
            }
            catch {
                // Ignore non-JSON results; the context fallback can still find the project.
            }
        }
    }
    return null;
}
function ProjectProgressBar({ done, total, className, }) {
    const percent = total > 0 ? Math.min((done / total) * 100, 100) : 0;
    return (_jsx("div", { className: `bg-neutral-grey-10 h-2 w-full overflow-hidden rounded-full ${className || ""}`, children: _jsx("div", { className: "bg-feedback-green h-full rounded-full transition-all duration-300", style: { width: `${percent}%` } }) }));
}
/**
 * Progress header for the taskboard project created by this agent (tracked in
 * the agent context as additionalData.createdProjectId). Rendered directly
 * above the prompt composer; the expand button opens the project in the
 * taskboard workspace.
 */
export function AgentProjectProgress({ agent, agentMetadata, messages, }) {
    const additionalData = agentMetadata?.additionalData;
    const metadataTrackedProject = getTrackedProjectFromAdditionalData(additionalData);
    const messageTrackedProject = useMemo(() => getTrackedProjectFromMessages(messages), [messages]);
    const [loadedTrackedProject, setLoadedTrackedProject] = useState(null);
    const agentId = agent?.id;
    const metadataProjectId = metadataTrackedProject?.projectId;
    const messageProjectId = messageTrackedProject?.projectId;
    const loadedProjectId = loadedTrackedProject?.projectId;
    const projectId = metadataProjectId ?? messageProjectId ?? loadedProjectId;
    const trackedTitle = metadataTrackedProject?.title ??
        messageTrackedProject?.title ??
        loadedTrackedProject?.title;
    const editContext = useEditContext();
    const parheliaSettings = useParheliaSettings();
    const currency = parheliaSettings?.currency || "USD";
    const [project, setProject] = useState(null);
    const [tasks, setTasks] = useState(null);
    useEffect(() => {
        setLoadedTrackedProject(null);
    }, [agentId]);
    useEffect(() => {
        if (projectId || !agentId)
            return;
        let disposed = false;
        const loadTrackedProject = async () => {
            try {
                const details = await fetchAgent(agentId);
                const trackedProject = getTrackedProjectFromAgentContext(details.agentContext) ??
                    getTrackedProjectFromMessages(details.messages);
                if (!disposed && trackedProject?.projectId) {
                    setLoadedTrackedProject(trackedProject);
                }
            }
            catch {
                // The regular interval will retry; absence of this header is non-fatal.
            }
        };
        void loadTrackedProject();
        const interval = window.setInterval(() => void loadTrackedProject(), REFRESH_INTERVAL_MS);
        return () => {
            disposed = true;
            window.clearInterval(interval);
        };
    }, [agentId, projectId]);
    const refresh = useCallback(async () => {
        if (!projectId)
            return;
        try {
            const [projectResult, tasksResult] = await Promise.all([
                getProject(projectId),
                getTasks(projectId),
            ]);
            if (projectResult.type === "success" && projectResult.data) {
                const data = projectResult.data;
                setProject(data.project ?? data);
            }
            if (tasksResult.type === "success" && Array.isArray(tasksResult.data)) {
                setTasks(tasksResult.data);
            }
        }
        catch {
            // Keep the last known data; the next poll may succeed again.
        }
    }, [projectId]);
    useEffect(() => {
        setProject(null);
        setTasks(null);
        if (!projectId)
            return;
        void refresh();
        const interval = setInterval(() => void refresh(), REFRESH_INTERVAL_MS);
        return () => clearInterval(interval);
    }, [projectId, refresh]);
    const openInTaskboard = useCallback(() => {
        if (!projectId || typeof window === "undefined")
            return;
        if (editContext?.workspaceId !== "taskboard") {
            editContext?.switchWorkspace?.("taskboard", {
                skipNavigationHistory: true,
            });
        }
        // Mirror the notification-route deep link: workspace + tbProjectId, with
        // editor/task params cleared (see config/notificationRoutes.ts).
        const params = new URLSearchParams(window.location.search);
        params.set("workspace", "taskboard");
        params.set("tbProjectId", projectId);
        for (const key of [
            "tbTaskId",
            "tbView",
            "tbWizard",
            "itemid",
            "lang",
            "language",
            "version",
            "reviewId",
        ]) {
            params.delete(key);
        }
        const queryString = params.toString();
        window.history.replaceState(null, "", queryString
            ? `${window.location.pathname}?${queryString}`
            : window.location.pathname);
        window.dispatchEvent(new PopStateEvent("popstate"));
    }, [editContext, projectId]);
    if (!projectId)
        return null;
    const title = project?.title || trackedTitle || "Project";
    const total = tasks?.length ?? 0;
    const done = tasks?.filter((t) => t.status === "Done").length ?? 0;
    const costUsed = project?.costUsed ?? null;
    const costLimit = project?.costLimit ?? null;
    return (_jsxs("div", { "data-testid": "agent-project-progress", className: "shrink-0 px-4 pt-3 pb-2", children: [_jsxs("div", { className: "flex items-center gap-3", children: [_jsx("span", { className: "text-neutral-grey-100 truncate text-sm font-medium", title: title, children: title }), costUsed != null && (_jsxs("span", { className: "text-neutral-grey-50 hidden truncate text-xs sm:block", children: ["Current total cost:", " ", _jsxs("span", { className: "font-medium", children: [costUsed.toFixed(2), " ", currency] }), costLimit != null &&
                                costLimit > 0 &&
                                ` / ${costLimit.toFixed(2)} ${currency}`] })), _jsxs("div", { className: "ml-auto flex shrink-0 items-center gap-1.5", children: [_jsx("span", { "data-testid": "agent-project-progress-counts", className: "bg-neutral-grey-5 text-neutral-grey-100 rounded-md px-2 py-0.5 text-xs font-medium tabular-nums", children: tasks ? `${done}/${total} done` : "..." }), _jsx("button", { type: "button", "data-testid": "agent-project-progress-expand", title: "Open in Workflow Projects", "aria-label": "Open in Workflow Projects", onClick: openInTaskboard, className: "text-neutral-grey-50 hover:text-neutral-grey-100 hover:bg-neutral-grey-5 rounded-md p-1.5 transition-colors", children: _jsx(ExternalLink, { className: "h-4 w-4" }) })] })] }), _jsx(ProjectProgressBar, { done: done, total: total, className: "mt-2" })] }));
}
//# sourceMappingURL=AgentProjectProgress.js.map