import { useCallback } from "react";
import { extractToolCallFields } from "../agentMessageConversion";
import { applyToolResultForMessageInTranscript } from "./agentSessionState";
import { contextWindowStatusFromStreamCost, hasNonZeroLiveTotals, liveTotalsFromStreamCost, liveTotalsFromToolResultData, } from "./agentSessionLiveTotals";
const isScreenshotCaptureTool = (functionName) => {
    const normalized = functionName.trim().toLowerCase();
    return (normalized === "capture-page-screenshot" ||
        normalized === "capture-parhelia-ui-screenshot");
};
export function useAgentToolResultHandler(input) {
    const { agent, actions, messagesRef, shouldCreateNewMessageRef, appendToolUiEvent, onTruncatedScreenshotToolResult, } = input;
    return useCallback((message, agentData) => {
        const extractedToolCall = extractToolCallFields(message.data);
        const resultToolCallId = extractedToolCall.toolCallId;
        const resultMessageId = message.data?.messageId;
        if (!resultMessageId) {
            console.error("[AgentTerminal] Backend invariant violation: tool result arrived without messageId. Dropping.", {
                agentId: agentData?.id,
                toolCallId: resultToolCallId,
                toolName: message.data?.functionName || message.data?.displayName,
            });
            return;
        }
        if (!resultToolCallId) {
            // Never synthesize an id here: applying the result under an invented
            // id appends a phantom completed tool call that can never match the
            // persisted toolCallId, so the call would render twice after merge.
            console.error("[AgentTerminal] Backend invariant violation: tool result arrived without toolCallId. Dropping.", {
                agentId: agentData?.id,
                messageId: resultMessageId,
                toolName: message.data?.functionName || message.data?.displayName,
            });
            appendToolUiEvent("ui:tool-result-dropped", `${extractedToolCall.functionName || "unknown"} targetMessageId=${resultMessageId} reason=no-tool-call-id`);
            return;
        }
        const cost = message.cost;
        const nextTotals = liveTotalsFromStreamCost(cost);
        if (nextTotals) {
            if (hasNonZeroLiveTotals(nextTotals)) {
                actions.replaceLiveTotals(nextTotals);
            }
            const contextWindowStatus = contextWindowStatusFromStreamCost(cost, agentData?.model || agent?.model || "");
            if (contextWindowStatus) {
                actions.replaceContextWindowStatus(contextWindowStatus);
            }
        }
        else {
            const dataTotals = liveTotalsFromToolResultData(message.data);
            if (dataTotals && hasNonZeroLiveTotals(dataTotals)) {
                actions.replaceLiveTotals(dataTotals);
            }
        }
        appendToolUiEvent("ui:tool-result-targeted", `${extractedToolCall.functionName || "unknown"} toolCallId=${resultToolCallId} targetMessageId=${resultMessageId}`);
        if (!message.data) {
            return;
        }
        const targetIndex = messagesRef.current.findIndex((message) => message.id === resultMessageId);
        if (targetIndex < 0) {
            appendToolUiEvent("ui:tool-result-dropped", `${extractedToolCall.functionName || "unknown"} toolCallId=${resultToolCallId} reason=no-target-row`);
            return;
        }
        // Live frames are size-capped on the backend (ToolResultStreamPayloadLimiter)
        // and flagged `truncated`. Never let a truncated stream copy replace a
        // longer result already in the transcript (e.g. the optimistic
        // questionnaire result applied on submit); the full result arrives with
        // the next snapshot from the DB.
        const incomingFunctionResult = message.data.functionResult || message.data.result || "";
        const existingToolCall = messagesRef.current[targetIndex]?.toolCalls?.find((toolCall) => toolCall.toolCallId === resultToolCallId);
        const functionResult = message.data.truncated === true &&
            typeof existingToolCall?.functionResult === "string" &&
            existingToolCall.functionResult.length > incomingFunctionResult.length
            ? existingToolCall.functionResult
            : incomingFunctionResult;
        const fallbackToolCallCreatedDate = message.data.createdDate ||
            message.timestamp ||
            new Date().toISOString();
        const fallbackToolCall = {
            id: resultToolCallId,
            messageId: resultMessageId,
            toolCallId: resultToolCallId,
            functionName: extractedToolCall.functionName,
            functionArguments: extractedToolCall.functionArguments,
            functionResult,
            functionResultRichContent: message.data.richContent || undefined,
            functionError: message.data.functionError || message.data.error || "",
            isCompleted: true,
            responseTimeMs: message.data.responseTimeMs,
            createdDate: fallbackToolCallCreatedDate,
        };
        const appliedToolResult = applyToolResultForMessageInTranscript(messagesRef.current, {
            messageId: resultMessageId,
            toolCallId: resultToolCallId,
            fallbackToolCall,
        });
        if (appliedToolResult.allToolCallsCompleted) {
            shouldCreateNewMessageRef.current = true;
        }
        messagesRef.current = appliedToolResult.transcript;
        actions.toolResult({
            messageId: resultMessageId,
            toolCallId: resultToolCallId,
            fallbackToolCall,
        });
        const messageWithToolResult = messagesRef.current[targetIndex];
        const matchingToolCall = messageWithToolResult?.toolCalls?.find((tc) => tc.toolCallId === resultToolCallId);
        appendToolUiEvent("ui:tool-result-applied", `${extractedToolCall.functionName || "unknown"} toolCallId=${resultToolCallId} targetMessageId=${messageWithToolResult?.id || resultMessageId} completed=${matchingToolCall?.isCompleted ? "yes" : "no"} messageToolCalls=${messageWithToolResult?.toolCalls?.length || 0}`);
        if (message.data.truncated === true &&
            isScreenshotCaptureTool(extractedToolCall.functionName)) {
            onTruncatedScreenshotToolResult?.({
                messageId: resultMessageId,
                toolCallId: resultToolCallId,
                functionName: extractedToolCall.functionName,
                originalLength: typeof message.data.originalLength === "number"
                    ? message.data.originalLength
                    : undefined,
            });
        }
    }, [
        actions,
        agent?.model,
        appendToolUiEvent,
        messagesRef,
        onTruncatedScreenshotToolResult,
        shouldCreateNewMessageRef,
    ]);
}
//# sourceMappingURL=useAgentToolResultHandler.js.map