"use client";
import { jsx as _jsx } from "react/jsx-runtime";
import { useCallback, useEffect, useMemo, useRef } from "react";
import { create } from "@bufbuild/protobuf";
import { AgentMessageSchema } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/message_pb";
import { ExecutionPhase, MessageType, } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
import { cn } from "@stigmer/theme";
import { isTerminalPhase } from "./execution-phases";
import { MessageEntry } from "./MessageEntry";
import { ToolCallGroup } from "./ToolCallGroup";
import { SubAgentSection } from "./SubAgentSection";
import { ExecutionPhaseBadge } from "./ExecutionPhaseBadge";
import { SetupProgress } from "./SetupProgress";
import { ApprovalCard } from "./ApprovalCard";
import { FilePathContext } from "./FilePathContext";
import { SandboxContext } from "./SandboxContext";
const AUTO_SCROLL_THRESHOLD_PX = 80;
function hasAiMessages(execution) {
    const messages = execution.status?.messages;
    if (!messages || messages.length === 0)
        return false;
    return messages.some((m) => m.type === MessageType.MESSAGE_AI && (m.content.trim() || m.toolCalls.length > 0));
}
function buildThreadItems(executions, activeStreamExecution, pendingUserMessage, includeApprovals, workspaceEntries) {
    const items = [];
    const allExecutions = activeStreamExecution
        ? [...executions, activeStreamExecution]
        : executions;
    for (let ei = 0; ei < allExecutions.length; ei++) {
        const exec = allExecutions[ei];
        const messages = exec.status?.messages ?? [];
        const subAgents = exec.status?.subAgentExecutions ?? [];
        const specMessage = exec.spec?.message;
        if (specMessage && specMessage !== "execute") {
            const syntheticHumanMsg = create(AgentMessageSchema);
            syntheticHumanMsg.type = MessageType.MESSAGE_HUMAN;
            syntheticHumanMsg.content = specMessage;
            items.push({
                kind: "message",
                message: syntheticHumanMsg,
                key: `e${ei}-spec-msg`,
            });
        }
        for (let mi = 0; mi < messages.length; mi++) {
            const msg = messages[mi];
            // MESSAGE_TOOL messages are not rendered — tool calls are attached
            // to their parent MESSAGE_AI and rendered via ToolCallGroup.
            if (msg.type === MessageType.MESSAGE_TOOL)
                continue;
            const isEmptyAi = msg.type === MessageType.MESSAGE_AI && !msg.content.trim();
            if (!isEmptyAi) {
                items.push({
                    kind: "message",
                    message: msg,
                    key: `e${ei}-m${mi}`,
                });
            }
            if (msg.type === MessageType.MESSAGE_AI &&
                msg.toolCalls.length > 0) {
                const regularTools = [];
                const taskTools = [];
                for (const tc of msg.toolCalls) {
                    if (tc.name === "task") {
                        taskTools.push(tc);
                    }
                    else {
                        regularTools.push(tc);
                    }
                }
                if (regularTools.length > 0) {
                    items.push({
                        kind: "tool-group",
                        toolCalls: regularTools,
                        subAgentExecutions: subAgents,
                        key: `e${ei}-m${mi}-tc`,
                    });
                }
                for (let ti = 0; ti < taskTools.length; ti++) {
                    const matched = subAgents.find((sa) => sa.id === taskTools[ti].id);
                    if (matched) {
                        items.push({
                            kind: "sub-agent",
                            subAgentExecution: matched,
                            key: `e${ei}-m${mi}-sa${ti}`,
                        });
                    }
                }
            }
        }
    }
    const lastExec = allExecutions[allExecutions.length - 1];
    const lastPhase = lastExec?.status?.phase ?? ExecutionPhase.EXECUTION_PHASE_UNSPECIFIED;
    if (activeStreamExecution &&
        (lastPhase === ExecutionPhase.EXECUTION_PENDING ||
            lastPhase === ExecutionPhase.EXECUTION_PHASE_UNSPECIFIED) &&
        !hasAiMessages(activeStreamExecution)) {
        const serverPhase = activeStreamExecution.status?.setupProgress?.currentPhase || undefined;
        items.push({
            kind: "setup-progress",
            workspaceEntries: workspaceEntries ?? [],
            serverPhase,
            key: "setup-progress",
        });
    }
    if (isTerminalPhase(lastPhase) &&
        lastPhase !== ExecutionPhase.EXECUTION_COMPLETED) {
        items.push({
            kind: "phase-badge",
            phase: lastPhase,
            key: `phase-${lastPhase}`,
        });
    }
    if (includeApprovals) {
        const allApprovals = lastExec?.status?.pendingApprovals ?? [];
        for (let ai = 0; ai < allApprovals.length; ai++) {
            const approval = allApprovals[ai];
            items.push({
                kind: "approval-request",
                pendingApproval: approval,
                key: `approval-${approval.toolCallId || ai}`,
            });
        }
    }
    if (pendingUserMessage) {
        const alreadySynthesized = lastExec?.spec?.message === pendingUserMessage;
        if (!alreadySynthesized) {
            items.push({
                kind: "pending-message",
                content: pendingUserMessage,
                key: "pending-user-message",
            });
        }
    }
    return items;
}
/**
 * Renders a continuous conversation thread from one or more
 * {@link AgentExecution} snapshots.
 *
 * Composes {@link MessageEntry}, {@link ToolCallGroup}, and
 * {@link ExecutionPhaseBadge} into a scrollable, auto-scrolling log
 * that follows new content when the user is near the bottom.
 *
 * Renders nothing when no executions are provided.
 *
 * All visual properties flow through `--stgm-*` tokens.
 *
 * @example
 * ```tsx
 * const { executions } = useSessionExecutions(sessionId);
 * const stream = useExecutionStream(activeId);
 *
 * <MessageThread
 *   executions={executions ?? []}
 *   activeStreamExecution={stream.execution}
 * />
 * ```
 */
export function MessageThread({ executions, activeStreamExecution, pendingUserMessage, className, formatToolCallSummary, onApprovalSubmit, submittingApprovalIds, workspaceEntries, onFilePathClick, sandboxWorkspaceRoot, }) {
    const scrollRef = useRef(null);
    const isNearBottomRef = useRef(true);
    const includeApprovals = onApprovalSubmit != null;
    const items = useMemo(() => buildThreadItems(executions, activeStreamExecution, pendingUserMessage, includeApprovals, workspaceEntries), [executions, activeStreamExecution, pendingUserMessage, includeApprovals, workspaceEntries]);
    const handleScroll = useCallback(() => {
        const el = scrollRef.current;
        if (!el)
            return;
        isNearBottomRef.current =
            el.scrollHeight - el.scrollTop - el.clientHeight < AUTO_SCROLL_THRESHOLD_PX;
    }, []);
    useEffect(() => {
        if (!isNearBottomRef.current)
            return;
        const el = scrollRef.current;
        if (!el)
            return;
        el.scrollTop = el.scrollHeight;
    }, [items]);
    const filePathCtx = useMemo(() => ({
        workspaceEntries: workspaceEntries ?? [],
        onFilePathClick,
    }), [workspaceEntries, onFilePathClick]);
    const sandboxCtx = useMemo(() => ({ sandboxWorkspaceRoot: sandboxWorkspaceRoot ?? "" }), [sandboxWorkspaceRoot]);
    return (_jsx("div", { ref: scrollRef, role: "log", "aria-live": "polite", "aria-relevant": "additions", onScroll: handleScroll, className: cn("flex flex-col gap-4 overflow-y-auto pt-6 pb-4", "[scrollbar-width:thin] [scrollbar-color:var(--color-border)_transparent]", "[&::-webkit-scrollbar]:w-1.5", "[&::-webkit-scrollbar-track]:bg-transparent", "[&::-webkit-scrollbar-thumb]:rounded-full [&::-webkit-scrollbar-thumb]:bg-border/40", className), children: _jsx(SandboxContext.Provider, { value: sandboxCtx, children: _jsx(FilePathContext.Provider, { value: filePathCtx, children: items.map((item) => {
                    switch (item.kind) {
                        case "message":
                            return _jsx(MessageEntry, { message: item.message }, item.key);
                        case "tool-group":
                            return (_jsx(ToolCallGroup, { toolCalls: item.toolCalls, subAgentExecutions: item.subAgentExecutions, formatSummary: formatToolCallSummary, className: "mx-4" }, item.key));
                        case "sub-agent":
                            return (_jsx(SubAgentSection, { subAgentExecution: item.subAgentExecution, className: "mx-4" }, item.key));
                        case "phase-badge":
                            return (_jsx("div", { className: "flex justify-center py-3", children: _jsx(ExecutionPhaseBadge, { phase: item.phase }) }, item.key));
                        case "approval-request":
                            return (_jsx(ApprovalCard, { pendingApproval: item.pendingApproval, onSubmit: (action, comment) => onApprovalSubmit(item.pendingApproval.toolCallId, action, comment), isSubmitting: submittingApprovalIds?.has(item.pendingApproval.toolCallId) ?? false, className: "mx-4" }, item.key));
                        case "setup-progress":
                            return (_jsx(SetupProgress, { workspaceEntries: item.workspaceEntries, serverPhase: item.serverPhase }, item.key));
                        case "pending-message":
                            return (_jsx("div", { role: "article", "aria-label": "Sending message", className: "ms-[20%] rounded-lg bg-muted-subtle px-4 py-3 opacity-70", children: _jsx("p", { className: "text-sm text-foreground whitespace-pre-wrap", children: item.content }) }, item.key));
                    }
                }) }) }) }));
}
//# sourceMappingURL=MessageThread.js.map