import { jsx as _jsx } from "react/jsx-runtime";
import BashProgress from '../components/bash-progress.js';
import { ErrorMessage, InfoMessage } from '../components/message-box.js';
import { setCurrentMode as setCurrentModeContext } from '../context/mode-context.js';
import { getToolManager, processToolUse } from '../message-handler.js';
import { executeBashCommand, formatBashResultForLLM } from '../tools/execute-bash.js';
import { MessageBuilder } from '../utils/message-builder.js';
import { parseToolArguments } from '../utils/tool-args-parser.js';
import { createCancellationResults } from '../utils/tool-cancellation.js';
import { displayToolResult } from '../utils/tool-result-display.js';
import { getVSCodeServerSync } from '../vscode/index.js';
export function useToolHandler({ pendingToolCalls, currentToolIndex, completedToolResults, currentConversationContext, setPendingToolCalls, setCurrentToolIndex, setCompletedToolResults, setCurrentConversationContext, setIsToolConfirmationMode, setIsToolExecuting, setMessages, addToChatQueue, setLiveComponent, getNextComponentKey, resetToolConfirmationState, onProcessAssistantResponse, client: _client, currentProvider: _currentProvider, setDevelopmentMode, }) {
    // Continue conversation with tool results - maintains the proper loop
    const continueConversationWithToolResults = async (toolResults) => {
        if (!currentConversationContext) {
            resetToolConfirmationState();
            return;
        }
        // Use passed results or fallback to state (for backwards compatibility)
        const resultsToUse = toolResults || completedToolResults;
        const { messagesBeforeToolExecution, systemMessage } = currentConversationContext;
        // Build updated messages with tool results
        const builder = new MessageBuilder(messagesBeforeToolExecution);
        builder.addToolResults(resultsToUse);
        const updatedMessagesWithTools = builder.build();
        setMessages(updatedMessagesWithTools);
        // Reset tool confirmation state since we're continuing the conversation
        resetToolConfirmationState();
        // Continue the main conversation loop with tool results as context
        await onProcessAssistantResponse(systemMessage, updatedMessagesWithTools);
    };
    // Handle tool confirmation
    const handleToolConfirmation = (confirmed) => {
        if (!confirmed) {
            // User cancelled - close all VS Code diffs
            const vscodeServer = getVSCodeServerSync();
            if (vscodeServer?.hasConnections()) {
                vscodeServer.closeAllDiffs();
            }
            // User cancelled - show message
            addToChatQueue(_jsx(InfoMessage, { message: "Tool execution cancelled by user", hideBox: true }, `tool-cancelled-${getNextComponentKey()}`));
            if (!currentConversationContext) {
                resetToolConfirmationState();
                return;
            }
            // Create cancellation results for all pending tools
            // This is critical to maintain conversation state integrity
            const cancellationResults = createCancellationResults(pendingToolCalls);
            const { messagesBeforeToolExecution } = currentConversationContext;
            // Build updated messages with cancellation results
            const builder = new MessageBuilder(messagesBeforeToolExecution);
            builder.addToolResults(cancellationResults);
            const updatedMessagesWithCancellation = builder.build();
            setMessages(updatedMessagesWithCancellation);
            // Reset state to allow user to type a new message
            // Do NOT continue the conversation - let the user provide instructions
            resetToolConfirmationState();
            return;
        }
        // Move to tool execution state - this allows UI to update immediately
        setIsToolConfirmationMode(false);
        setIsToolExecuting(true);
        // Execute tools asynchronously
        setImmediate(() => {
            void executeCurrentTool();
        });
    };
    // Execute the current tool asynchronously
    const executeCurrentTool = async () => {
        const currentTool = pendingToolCalls[currentToolIndex];
        // Check if this is an MCP tool and show appropriate messaging
        const toolManager = getToolManager();
        if (toolManager) {
            const mcpInfo = toolManager.getMCPToolInfo(currentTool.function.name);
            if (mcpInfo.isMCPTool) {
                addToChatQueue(_jsx(InfoMessage, { message: `Executing MCP tool "${currentTool.function.name}" from server "${mcpInfo.serverName}"`, hideBox: true }, `mcp-tool-executing-${getNextComponentKey()}-${Date.now()}`));
            }
            // Run validator if available
            const validator = toolManager.getToolValidator(currentTool.function.name);
            if (validator) {
                try {
                    const parsedArgs = parseToolArguments(currentTool.function.arguments);
                    const validationResult = await validator(parsedArgs);
                    if (!validationResult.valid) {
                        // Validation failed - show error and skip execution
                        const errorResult = {
                            tool_call_id: currentTool.id,
                            role: 'tool',
                            name: currentTool.function.name,
                            content: validationResult.error,
                        };
                        const newResults = [...completedToolResults, errorResult];
                        setCompletedToolResults(newResults);
                        // Display the error
                        addToChatQueue(_jsx(ErrorMessage, { message: validationResult.error, hideBox: true }, `tool-validation-error-${getNextComponentKey()}-${Date.now()}`));
                        // Move to next tool or complete the process
                        if (currentToolIndex + 1 < pendingToolCalls.length) {
                            setCurrentToolIndex(currentToolIndex + 1);
                            // Return to confirmation mode for next tool
                            setIsToolExecuting(false);
                            setIsToolConfirmationMode(true);
                        }
                        else {
                            // All tools processed, continue conversation loop with the results
                            setIsToolExecuting(false);
                            await continueConversationWithToolResults(newResults);
                        }
                        return;
                    }
                }
                catch (validationError) {
                    // Validation threw an error - treat as validation failure
                    const errorResult = {
                        tool_call_id: currentTool.id,
                        role: 'tool',
                        name: currentTool.function.name,
                        content: `Validation error: ${validationError instanceof Error
                            ? validationError.message
                            : String(validationError)}`,
                    };
                    const newResults = [...completedToolResults, errorResult];
                    setCompletedToolResults(newResults);
                    addToChatQueue(_jsx(ErrorMessage, { message: `Validation error: ${String(validationError)}`, hideBox: true }, `tool-validation-error-${getNextComponentKey()}-${Date.now()}`));
                    // Move to next tool or complete the process
                    if (currentToolIndex + 1 < pendingToolCalls.length) {
                        setCurrentToolIndex(currentToolIndex + 1);
                        setIsToolExecuting(false);
                        setIsToolConfirmationMode(true);
                    }
                    else {
                        setIsToolExecuting(false);
                        await continueConversationWithToolResults(newResults);
                    }
                    return;
                }
            }
        }
        try {
            // Special handling for switch_mode tool
            if (currentTool.function.name === 'switch_mode' && setDevelopmentMode) {
                const parsedArgs = parseToolArguments(currentTool.function.arguments);
                // Actually switch the mode
                // Sync both React state AND global context synchronously
                // to prevent race conditions where tools check global context
                // before the useEffect in App.tsx has a chance to sync it
                const requestedMode = parsedArgs.mode;
                setDevelopmentMode(requestedMode);
                setCurrentModeContext(requestedMode);
                addToChatQueue(_jsx(InfoMessage, { message: `Development mode switched to: ${requestedMode.toUpperCase()}`, hideBox: true }, `mode-switched-${getNextComponentKey()}-${Date.now()}`));
            }
            // Check if tool has a streaming formatter (for real-time progress)
            const streamingFormatter = toolManager?.getStreamingFormatter(currentTool.function.name);
            let result;
            if (streamingFormatter) {
                // Streaming tool (e.g., execute_bash) - handle specially
                const parsedArgs = parseToolArguments(currentTool.function.arguments);
                const commandStr = parsedArgs.command;
                // Start execution first to get execution ID
                const { executionId, promise } = executeBashCommand(commandStr);
                // Set as live component (renders outside Static for real-time updates)
                setLiveComponent(_jsx(BashProgress, { executionId: executionId, command: commandStr, isLive: true }, `streaming-tool-${currentTool.id}-${getNextComponentKey()}-${Date.now()}`));
                // Wait for execution to complete
                const bashResult = await promise;
                const llmContent = formatBashResultForLLM(bashResult);
                result = {
                    tool_call_id: currentTool.id,
                    role: 'tool',
                    name: currentTool.function.name,
                    content: llmContent,
                };
                // Clear live component and add static completed result to chat queue
                setLiveComponent(null);
                addToChatQueue(_jsx(BashProgress, { executionId: executionId, command: commandStr, completedState: bashResult }, `streaming-tool-complete-${currentTool.id}-${getNextComponentKey()}-${Date.now()}`));
            }
            else {
                // Regular tool - use standard flow
                result = await processToolUse(currentTool);
                // Display the tool result
                await displayToolResult(currentTool, result, toolManager, addToChatQueue, getNextComponentKey);
            }
            const newResults = [...completedToolResults, result];
            setCompletedToolResults(newResults);
            // Move to next tool or complete the process
            if (currentToolIndex + 1 < pendingToolCalls.length) {
                setCurrentToolIndex(currentToolIndex + 1);
                // Return to confirmation mode for next tool
                setIsToolExecuting(false);
                setIsToolConfirmationMode(true);
            }
            else {
                // All tools executed, continue conversation loop with the updated results
                setIsToolExecuting(false);
                await continueConversationWithToolResults(newResults);
            }
        }
        catch (error) {
            setIsToolExecuting(false);
            addToChatQueue(_jsx(ErrorMessage, { message: `Tool execution error: ${String(error)}` }, `tool-exec-error-${getNextComponentKey()}`));
            resetToolConfirmationState();
        }
    };
    // Handle tool confirmation cancel
    const handleToolConfirmationCancel = () => {
        // Close all VS Code diffs when user cancels
        const vscodeServer = getVSCodeServerSync();
        if (vscodeServer?.hasConnections()) {
            vscodeServer.closeAllDiffs();
        }
        addToChatQueue(_jsx(InfoMessage, { message: "Tool execution cancelled by user", hideBox: true }, `tool-cancelled-${getNextComponentKey()}`));
        if (!currentConversationContext) {
            resetToolConfirmationState();
            return;
        }
        // Create cancellation results for all pending tools
        // This is critical to maintain conversation state integrity
        const cancellationResults = createCancellationResults(pendingToolCalls);
        const { messagesBeforeToolExecution } = currentConversationContext;
        // Build updated messages with cancellation results
        const builder = new MessageBuilder(messagesBeforeToolExecution);
        builder.addToolResults(cancellationResults);
        const updatedMessagesWithCancellation = builder.build();
        setMessages(updatedMessagesWithCancellation);
        // Reset state to allow user to type a new message
        // Do NOT continue the conversation - let the user provide instructions
        resetToolConfirmationState();
    };
    // Start tool confirmation flow
    const startToolConfirmationFlow = (toolCalls, messagesBeforeToolExecution, assistantMsg, systemMessage) => {
        setPendingToolCalls(toolCalls);
        setCurrentToolIndex(0);
        setCompletedToolResults([]);
        setCurrentConversationContext({
            messagesBeforeToolExecution,
            assistantMsg,
            systemMessage,
        });
        setIsToolConfirmationMode(true);
    };
    return {
        handleToolConfirmation,
        handleToolConfirmationCancel,
        startToolConfirmationFlow,
        continueConversationWithToolResults,
        executeCurrentTool,
    };
}
//# sourceMappingURL=useToolHandler.js.map