import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
import React from 'react';
import { useChatContext } from '../../contexts/ChatContext';
import { useModelContext } from '../../contexts/ModelContext';
import { useChatSettings } from '../../contexts/ChatSettingsContext';
import { useLocalStorageState } from '../../hooks/useLocalStorage';
import { ChatHeader } from './components/ChatHeader';
import { MessageList } from './components/MessageList';
import { ChatInput } from './components/ChatInput';
import { ModelControls } from './components/ModelControls';
import { ChatSettingEditor } from './components/ChatSettingEditor';
import { isChatAgentCancelledError } from '../../hooks/useChatAgent';
import { useTheme } from '../../theme';
import { useMcpServers } from '../../contexts/McpContext';
import { useSlashCommandPromptResolver } from '../../contexts/SlashCommandPromptContext';
import { ChatDialogLayout } from './components/ChatDialogLayout';
import { SessionHistory } from './components/SessionHistory';
import { useAttachmentManager } from './hooks/useAttachmentManager';
import { useSlashCommands } from './hooks/useSlashCommands';
import { useModelSettingsEditor } from './hooks/useModelSettingsEditor';
import { useChatInputState } from './hooks/useChatInputState';
import { useStreamingStatus } from './hooks/useStreamingStatus';
import { useProviderMetadata } from './hooks/useProviderMetadata';
import { formatStatusLabel, summarizeValue } from './utils/formatting';
import { Drawer } from '../core/Drawer';
import { useChatSessions } from '../../contexts/ChatSessionsContext';
import { useCustomPrompts } from '../../contexts/customPrompts/useCustomPrompts';
export const ChatDialog = ({ placeholder = 'Type your message...', disabled = false, className = '', emptyStateMessage = 'No messages yet. Start the conversation!', onToggleSettings, isSettingsOpen, activeView, onSelectView }) => {
    void activeView;
    void onSelectView;
    const theme = useTheme();
    const { servers } = useMcpServers();
    const { resolvePrompt: resolveSlashCommandPrompt } = useSlashCommandPromptResolver();
    const { combinedPrompts } = useCustomPrompts();
    const { chatHistory: messages, currentAssistantResponse, isStreaming, isCancelling, canCancel, sendMessage, cancelMessage, cacheAttachment, removeAttachment, pendingInterruptions, pendingRunId, approveInterruption, rejectInterruption, resumePendingRun, startNewSession } = useChatContext();
    const { previousSessions, activeSessionId, resumeSession, deleteSession } = useChatSessions();
    const [isSessionHistoryOpen, setSessionHistoryOpen] = React.useState(false);
    const closeSessionHistory = React.useCallback(() => {
        setSessionHistoryOpen(false);
    }, []);
    const handleToggleSessionHistory = React.useCallback(() => {
        setSessionHistoryOpen((prev) => !prev);
    }, []);
    const handleResumeSessionFromHistory = React.useCallback((sessionId) => {
        resumeSession(sessionId);
        closeSessionHistory();
    }, [closeSessionHistory, resumeSession]);
    const handleDeleteSessionFromHistory = React.useCallback((sessionId) => {
        deleteSession(sessionId);
    }, [deleteSession]);
    React.useEffect(() => {
        if (previousSessions.length === 0) {
            closeSessionHistory();
        }
    }, [closeSessionHistory, previousSessions.length]);
    const { defaultModel, models, setDefaultModel, updateModel } = useModelContext();
    const providerId = defaultModel?.provider;
    const { providerMetadata, providerDisplayBase, providerBadgeLabel, isProviderComingSoon, isProviderImplemented } = useProviderMetadata(providerId);
    const { value: showToolCalls, setValue: setShowToolCalls } = useLocalStorageState('chat-tool-calls-visible', true);
    const { attachmentCallback } = useChatSettings();
    const { pendingAttachments, chatInputAttachments, isAttachmentCallbackPending, addAttachments, removeAttachment: removePendingAttachment, clearAttachments, restoreAttachments, createUploads } = useAttachmentManager({ cacheAttachment, removeAttachment, attachmentCallback });
    const [activeSlashCommand, setActiveSlashCommand] = React.useState(null);
    const resolvePromptFromServer = React.useCallback(async (serverId, promptName, args) => {
        return await resolveSlashCommandPrompt(serverId, promptName, args);
    }, [resolveSlashCommandPrompt]);
    const { slashCommandOptions, resolveForSubmission } = useSlashCommands({
        servers,
        additionalPrompts: combinedPrompts,
        resolvePromptFromServer
    });
    const { settingEditor, settingInputValue, settingError, openSettingEditor, closeSettingEditor, handleSettingInputChange, handleSettingSubmit } = useModelSettingsEditor({
        defaultModel,
        updateModel
    });
    const { streamingContent, streamingToolCalls, streamingInterruptions, activeReasoningEvents, activeMessageEvents, expandedToolCalls, toggleToolCallExpansion, isShowingStream } = useStreamingStatus({
        currentAssistantResponse,
        pendingInterruptions,
        showToolCalls
    });
    const [configError, setConfigError] = React.useState(null);
    const onSendMessage = React.useCallback(async ({ content, attachments, slashCommand }) => {
        await sendMessage({
            content,
            attachments,
            slashCommand
        });
    }, [sendMessage]);
    const { inputValue, setInputValue, inputHistory, isSendingMessage, setIsSendingMessage, handleSubmit, resetStateAfterNewSession } = useChatInputState({
        onSendMessage,
        isAttachmentCallbackPending,
        isProviderComingSoon,
        activeSlashCommand,
        setActiveSlashCommand,
        createUploads,
        clearAttachments,
        restoreAttachments,
        resolveSlashCommand: resolveForSubmission,
        pendingAttachments
    });
    const previousStreamingRef = React.useRef(isStreaming);
    React.useEffect(() => {
        if (previousStreamingRef.current && !isStreaming && isSendingMessage) {
            setIsSendingMessage(false);
        }
        previousStreamingRef.current = isStreaming;
    }, [isStreaming, isSendingMessage, setIsSendingMessage]);
    const availableModels = React.useMemo(() => models.filter((model) => !model.disabled), [models]);
    const layoutClassName = React.useMemo(() => ['flex-1', className].filter(Boolean).join(' '), [className]);
    const handleModelSelectChange = React.useCallback((event) => {
        const nextModelId = event.target.value;
        if (!nextModelId) {
            return;
        }
        setDefaultModel(nextModelId);
    }, [setDefaultModel]);
    const handleToggleToolCalls = React.useCallback(() => {
        setShowToolCalls((prev) => !prev);
    }, [setShowToolCalls]);
    const handleCancelSend = React.useCallback(() => {
        cancelMessage();
    }, [cancelMessage]);
    const handleApproveInterruption = React.useCallback(async (interruptionId) => {
        try {
            approveInterruption(interruptionId);
            if (pendingRunId && !isCancelling) {
                await resumePendingRun();
            }
        }
        catch (error) {
            if (isChatAgentCancelledError(error) || (error instanceof Error && error.name === 'AbortError')) {
                console.debug('Tool approval ignored because the chat run was cancelled', {
                    interruptionId,
                    error
                });
                return;
            }
            console.error('Failed to approve tool permission request', error);
            throw error;
        }
    }, [approveInterruption, isCancelling, pendingRunId, resumePendingRun]);
    const handleDenyInterruption = React.useCallback(async (interruptionId) => {
        try {
            rejectInterruption(interruptionId, 'User denied this tool permission request from the chat UI.');
            if (pendingRunId && !isCancelling) {
                await resumePendingRun();
            }
        }
        catch (error) {
            if (isChatAgentCancelledError(error) || (error instanceof Error && error.name === 'AbortError')) {
                console.debug('Tool denial ignored because the chat run was cancelled', {
                    interruptionId,
                    error
                });
                return;
            }
            console.error('Failed to deny tool permission request', error);
            throw error;
        }
    }, [isCancelling, pendingRunId, rejectInterruption, resumePendingRun]);
    const handleAttachmentsAdd = React.useCallback((files) => {
        if (files.length === 0)
            return;
        addAttachments(files);
    }, [addAttachments]);
    const handleAttachmentRemove = React.useCallback((attachmentId) => {
        removePendingAttachment(attachmentId);
    }, [removePendingAttachment]);
    const handleNewSession = React.useCallback(() => {
        startNewSession();
        resetStateAfterNewSession();
        setConfigError(null);
        clearAttachments();
        closeSessionHistory();
    }, [clearAttachments, closeSessionHistory, resetStateAfterNewSession, startNewSession]);
    const handleFormSubmit = React.useCallback(async (event) => {
        event.preventDefault();
        setConfigError(null);
        try {
            await handleSubmit(event);
        }
        catch (error) {
            const wasCancelled = isChatAgentCancelledError(error) || (error instanceof Error && error.name === 'AbortError');
            if (wasCancelled) {
                return;
            }
            console.error('Error sending message:', error);
            if (error instanceof Error) {
                setConfigError(error.message);
            }
        }
    }, [handleSubmit]);
    const temperature = defaultModel?.settings?.temperature;
    const topP = defaultModel?.settings?.topP;
    const maxTokens = defaultModel?.settings?.maxTokens;
    const providerDisplayLabel = providerBadgeLabel;
    const isInputDisabled = disabled || isStreaming || isCancelling;
    const isSubmissionDisabled = isAttachmentCallbackPending || !isProviderImplemented;
    return (_jsxs("div", { className: 'flex h-full min-h-[32rem]', children: [_jsx(Drawer, { isOpen: isSessionHistoryOpen, onClose: closeSessionHistory, side: 'left', closeLabel: 'Close session history', role: 'navigation', children: _jsx(SessionHistory, { id: 'chat-session-history', sessions: previousSessions, activeSessionId: activeSessionId, onResume: handleResumeSessionFromHistory, onDelete: handleDeleteSessionFromHistory, emptyStateMessage: 'No previous sessions yet.', title: 'Session history' }) }), _jsxs("div", { className: 'flex flex-1 flex-col', children: [_jsx(ChatDialogLayout, { className: layoutClassName, shellClassName: theme.chatDialog.shell, scrollContainerClassName: theme.chatDialog.scrollContainer, messageListSectionClassName: theme.chatDialog.messageListSection, inputOverlayClassName: theme.chatDialog.inputOverlay, inputCardClassName: theme.chatDialog.inputCard, onSubmit: handleFormSubmit, header: (_jsx(ChatHeader, { onNewSession: handleNewSession, onToggleSettings: onToggleSettings, isSettingsOpen: isSettingsOpen, onToggleSessions: handleToggleSessionHistory, isSessionsOpen: isSessionHistoryOpen })), messageList: (_jsx(MessageList, { messages: messages, configError: configError, emptyStateMessage: emptyStateMessage, isShowingStream: isShowingStream, streamingContent: streamingContent, streamingToolCalls: streamingToolCalls, reasoningEvents: activeReasoningEvents, messageEvents: activeMessageEvents, showToolCalls: showToolCalls, expandedToolCalls: expandedToolCalls, onToggleToolCallExpansion: toggleToolCallExpansion, formatStatusLabel: formatStatusLabel, summarizeValue: summarizeValue, interruptions: streamingInterruptions, onApproveInterruption: handleApproveInterruption, onDenyInterruption: handleDenyInterruption })), formContent: (_jsxs(_Fragment, { children: [_jsx(ModelControls, { availableModels: availableModels, defaultModel: defaultModel, providerDisplayLabel: providerDisplayLabel, isStreaming: isStreaming, temperature: temperature, topP: topP, maxTokens: maxTokens, showToolCalls: showToolCalls, onModelChange: handleModelSelectChange, onSettingEdit: openSettingEditor, onToggleToolCalls: handleToggleToolCalls }), isProviderComingSoon && (_jsx("div", { className: theme.chatDialog.sendingToast, children: _jsxs("div", { children: [_jsxs("div", { className: theme.chatDialog.sendingToastTitle, children: [(providerMetadata?.name ?? providerDisplayBase) || 'Selected provider', " support is coming soon"] }), _jsx("div", { className: theme.chatDialog.sendingToastBody, children: "Configure credentials now, then switch back to an implemented provider to continue chatting until this integration is ready." })] }) })), _jsx(ChatInput, { inputValue: inputValue, inputHistory: inputHistory, placeholder: placeholder, isInputDisabled: isInputDisabled, isStreaming: isStreaming, isSubmissionDisabled: isSubmissionDisabled, isSending: isSendingMessage, isCancelling: isCancelling, canCancel: canCancel, onCancelSend: handleCancelSend, attachments: chatInputAttachments, onAttachmentsAdd: handleAttachmentsAdd, onAttachmentRemove: handleAttachmentRemove, onInputChange: setInputValue, slashCommandOptions: slashCommandOptions, activeSlashCommand: activeSlashCommand, onSlashCommandStateChange: setActiveSlashCommand })] })) }), _jsx(ChatSettingEditor, { settingEditor: settingEditor, settingInputValue: settingInputValue, settingError: settingError, defaultModel: defaultModel, onSubmit: handleSettingSubmit, onInputChange: handleSettingInputChange, onClose: closeSettingEditor })] })] }));
};
export default ChatDialog;
