'use client';
import { jsx as _jsx } from "react/jsx-runtime";
import React, { createContext, useContext } from 'react';
import { useChatAgent } from '../hooks/useChatAgent';
import { useChatSettings } from './ChatSettingsContext';
import { useChatSessions } from './ChatSessionsContext';
import { useAdditionalTools } from './AdditionalToolsContext';
const ChatContext = createContext(undefined);
export const ChatProvider = ({ children, modelContext, mcpContext }) => {
    const { activeSessionId, sessions, previousSessions, startNewSession, resumeSession, deleteSession, updateSessionMetadata, clearAllSessions } = useChatSessions();
    const { defaultModel } = modelContext;
    const { agentPrompt } = useChatSettings();
    if (!defaultModel) {
        // Return a disabled/no-op version when no model is configured
        const contextValue = {
            chatHistory: [],
            currentAssistantResponse: {
                text: '',
                toolCalls: [],
                reasoningEvents: [],
                messageEvents: [],
                interruptions: []
            },
            isStreaming: false,
            isCancelling: false,
            canCancel: false,
            sendMessage: async () => {
                throw new Error('No model configured for chat');
            },
            cancelMessage: () => false,
            clearHistory: () => { },
            cacheAttachment: () => { },
            removeAttachment: () => { },
            pendingInterruptions: [],
            hasPendingInterruptions: false,
            pendingRunId: null,
            approveInterruption: () => {
                throw new Error('No model configured for chat');
            },
            rejectInterruption: () => {
                throw new Error('No model configured for chat');
            },
            resumePendingRun: async () => {
                throw new Error('No model configured for chat');
            },
            sessionId: activeSessionId,
            sessions,
            previousSessions,
            startNewSession,
            resumeSession,
            deleteSession,
            updateSessionMetadata,
            clearAllSessions
        };
        return (_jsx(ChatContext.Provider, { value: contextValue, children: children }));
    }
    // Extract API key from model connection when provided
    const apiKey = typeof defaultModel.connection?.apiKey === 'string'
        ? defaultModel.connection.apiKey.trim() || undefined
        : undefined;
    const enabledServers = React.useMemo(() => mcpContext.servers.filter((server) => server.options.serverEnabled ?? true), [mcpContext.servers]);
    const trimmedPrompt = React.useMemo(() => agentPrompt.trim(), [agentPrompt]);
    const modelSettings = React.useMemo(() => ({ ...(defaultModel.settings ?? {}) }), [defaultModel.settings]);
    const modelName = typeof defaultModel.model === 'string' && defaultModel.model.trim().length > 0
        ? defaultModel.model.trim()
        : 'gpt-4.1';
    const baseUrl = React.useMemo(() => {
        if (typeof defaultModel.baseUrl === 'string' && defaultModel.baseUrl.trim().length > 0) {
            return defaultModel.baseUrl.trim();
        }
        const connectionValue = defaultModel.connection
            ? (defaultModel.connection['baseUrl'] ?? defaultModel.connection['baseURL'])
            : undefined;
        return typeof connectionValue === 'string' && connectionValue.trim().length > 0
            ? connectionValue.trim()
            : undefined;
    }, [defaultModel.baseUrl, defaultModel.connection]);
    const modelConnection = React.useMemo(() => defaultModel.connection ?? {}, [defaultModel.connection]);
    const { tools: additionalTools } = useAdditionalTools();
    const resolvedAdditionalTools = React.useMemo(() => {
        if (!additionalTools || additionalTools.length === 0) {
            return undefined;
        }
        const resolved = [];
        for (const tool of additionalTools) {
            const { effectivePermission, isPermissionConfigurable, permissionReason, runtimePermission, ...definition } = tool;
            void permissionReason;
            void runtimePermission;
            if (effectivePermission === 'disabled') {
                continue;
            }
            const normalized = { ...definition };
            if (isPermissionConfigurable) {
                if (effectivePermission === 'ask_first') {
                    normalized.needsApproval = true;
                }
                else if (effectivePermission === 'enabled') {
                    if ('needsApproval' in normalized) {
                        delete normalized.needsApproval;
                    }
                }
            }
            resolved.push(normalized);
        }
        return resolved.length > 0 ? resolved : undefined;
    }, [additionalTools]);
    const options = React.useMemo(() => ({
        apiKey,
        providerId: defaultModel.provider,
        modelName,
        baseUrl,
        connection: modelConnection,
        mcpServers: enabledServers,
        modelSettings,
        instructions: trimmedPrompt.length > 0 ? trimmedPrompt : undefined,
        clientHeaders: defaultModel.clientHeaders,
        logLevel: defaultModel.logLevel,
        apiMode: defaultModel.apiMode,
        useLegacyMessages: defaultModel.useLegacyMessages,
        additionalTools: resolvedAdditionalTools
    }), [
        apiKey,
        defaultModel.provider,
        modelName,
        baseUrl,
        modelConnection,
        enabledServers,
        modelSettings,
        trimmedPrompt,
        defaultModel.clientHeaders,
        defaultModel.logLevel,
        defaultModel.apiMode,
        defaultModel.useLegacyMessages,
        resolvedAdditionalTools
    ]);
    const { chatHistory, currentAssistantResponse, isStreaming, isCancelling, canCancel, invokeChatAgent, clearChatHistory, cacheAttachment, removeAttachment, cancel, pendingInterruptions, hasPendingInterruptions, pendingRunId, approveInterruption, rejectInterruption, resumePendingRun } = useChatAgent(activeSessionId, options);
    const metadataSignatureRef = React.useRef();
    React.useEffect(() => {
        metadataSignatureRef.current = undefined;
    }, [activeSessionId]);
    React.useEffect(() => {
        const messageCount = chatHistory.length;
        const lastMessage = messageCount > 0 ? chatHistory[messageCount - 1] : undefined;
        const lastTimestamp = lastMessage?.timestamp;
        const lastContent = lastMessage?.content ?? '';
        const signature = {
            count: messageCount,
            lastTimestamp,
            lastContent
        };
        const previous = metadataSignatureRef.current;
        if (previous &&
            previous.count === signature.count &&
            previous.lastTimestamp === signature.lastTimestamp &&
            previous.lastContent === signature.lastContent) {
            return;
        }
        metadataSignatureRef.current = signature;
        updateSessionMetadata(activeSessionId, {
            messageCount,
            lastMessageAt: lastMessage ? (lastTimestamp ?? Date.now()) : null,
            lastMessagePreview: lastMessage && lastContent.trim().length > 0 ? lastContent.slice(0, 280) : null,
            updatedAt: Date.now()
        });
    }, [chatHistory, activeSessionId, updateSessionMetadata]);
    const sendMessage = async (input, handlers) => {
        return await invokeChatAgent(input, handlers);
    };
    const cancelMessage = () => {
        return cancel();
    };
    const clearHistory = React.useCallback(() => {
        metadataSignatureRef.current = undefined;
        clearChatHistory();
        updateSessionMetadata(activeSessionId, {
            messageCount: 0,
            lastMessageAt: null,
            lastMessagePreview: null,
            updatedAt: Date.now()
        });
    }, [activeSessionId, clearChatHistory, updateSessionMetadata]);
    const contextValue = {
        chatHistory,
        currentAssistantResponse,
        isStreaming,
        isCancelling,
        canCancel,
        sendMessage,
        cancelMessage,
        clearHistory,
        cacheAttachment,
        removeAttachment,
        pendingInterruptions,
        hasPendingInterruptions,
        pendingRunId,
        approveInterruption,
        rejectInterruption,
        resumePendingRun,
        sessionId: activeSessionId,
        sessions,
        previousSessions,
        startNewSession,
        resumeSession,
        deleteSession,
        updateSessionMetadata,
        clearAllSessions
    };
    return (_jsx(ChatContext.Provider, { value: contextValue, children: children }));
};
export const useChatContext = () => {
    const context = useContext(ChatContext);
    if (!context) {
        throw new Error('useChatContext must be used within a ChatProvider');
    }
    return context;
};
