import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
import { memo, useState, useCallback, useEffect, useRef, forwardRef, useImperativeHandle, useMemo, } from 'react';
import { useQueryClient } from '@tanstack/react-query';
import { useSendMessage, useMessages } from '../../hooks/useMessages';
import { useSession, useUpdateSession, useDeleteSession, } from '../../hooks/useSessions';
import { useAllModels } from '../../hooks/useConfig';
import { usePreferences } from '../../hooks/usePreferences';
import { useGitStatus, useStageFiles } from '../../hooks/useGit';
import { useGitStore } from '../../stores/gitStore';
import { useFileUpload } from '../../hooks/useFileUpload';
import { useQueueStore } from '../../stores/queueStore';
import { usePendingResearchStore } from '../../stores/pendingResearchStore';
import { formatResearchContextForMessage } from '../../lib/parseResearchContext';
import { useSetuBalance } from '../../hooks/useSetuBalance';
import { useSetuStore } from '../../stores/setuStore';
import { toast } from '../../stores/toastStore';
import { useToastStore } from '../../stores/toastStore';
import { apiClient } from '../../lib/api-client';
import { ChatInput } from './ChatInput';
import { ConfigModal } from './ConfigModal';
export const ChatInputContainer = memo(forwardRef(function ChatInputContainer({ sessionId, userContext, onNewSession, onDeleteSession }, ref) {
    const session = useSession(sessionId);
    const [agent, setAgent] = useState('');
    const [provider, setProvider] = useState('');
    const [model, setModel] = useState('');
    const [isConfigOpen, setIsConfigOpen] = useState(false);
    const [configFocusTarget, setConfigFocusTarget] = useState(null);
    const [inputKey, setInputKey] = useState(0);
    const chatInputRef = useRef(null);
    const sendMessage = useSendMessage(sessionId);
    useMessages(sessionId);
    const updateSession = useUpdateSession(sessionId);
    const deleteSession = useDeleteSession();
    const { data: allModels } = useAllModels();
    const { preferences } = usePreferences();
    const { data: gitStatus } = useGitStatus();
    const stageFiles = useStageFiles();
    const openCommitModalForSession = useGitStore((state) => state.openCommitModalForSession);
    const setActiveSessionId = useGitStore((state) => state.setActiveSessionId);
    const queryClient = useQueryClient();
    const { images, documents, isDragging, removeFile, clearFiles, handlePaste, } = useFileUpload();
    const modelSupportsReasoning = allModels?.[provider]?.models?.find((m) => m.id === model)?.reasoningText;
    const modelSupportsVision = allModels?.[provider]?.models?.find((m) => m.id === model)?.vision;
    const pendingContextsMap = usePendingResearchStore((state) => state.pendingContexts);
    const removeResearchContext = usePendingResearchStore((state) => state.removeContext);
    const consumeResearchContexts = usePendingResearchStore((state) => state.consumeContexts);
    const pendingResearchContexts = pendingContextsMap.get(sessionId) || [];
    const researchContexts = useMemo(() => pendingResearchContexts.map((ctx) => ({
        id: ctx.id,
        label: ctx.label,
    })), [pendingResearchContexts]);
    const handleResearchContextRemove = useCallback((contextId) => {
        removeResearchContext(sessionId, contextId);
    }, [sessionId, removeResearchContext]);
    const providerAuthType = allModels?.[provider]?.authType;
    const { fetchBalance } = useSetuBalance(provider);
    const isBalanceLoading = useSetuStore((s) => s.isLoading);
    useEffect(() => {
        if (session) {
            setAgent(session.agent);
            setProvider(session.provider);
            setModel(session.model);
        }
    }, [session]);
    useEffect(() => {
        setActiveSessionId(sessionId);
        return () => setActiveSessionId(null);
    }, [sessionId, setActiveSessionId]);
    useEffect(() => {
        setInputKey((prev) => prev + 1);
    }, []);
    const pendingRestoreText = useQueueStore((state) => state.pendingRestoreText);
    const consumeRestoreText = useQueueStore((state) => state.consumeRestoreText);
    useEffect(() => {
        if (pendingRestoreText) {
            const text = consumeRestoreText();
            if (text) {
                chatInputRef.current?.setValue(text);
            }
        }
    }, [pendingRestoreText, consumeRestoreText]);
    useImperativeHandle(ref, () => ({
        focus: () => {
            chatInputRef.current?.focus();
        },
    }));
    const handleSendMessage = useCallback(async (content) => {
        try {
            const researchCtxs = consumeResearchContexts(sessionId);
            const researchPrefix = formatResearchContextForMessage(researchCtxs);
            const finalContent = researchPrefix
                ? `${researchPrefix}\n\n${content}`
                : content;
            const imageData = images.length > 0
                ? images.map((img) => ({
                    data: img.data,
                    mediaType: img.mediaType,
                }))
                : undefined;
            const fileData = documents.length > 0
                ? documents.map((f) => ({
                    type: f.type,
                    name: f.name,
                    data: f.data,
                    mediaType: f.mediaType,
                    textContent: f.textContent,
                }))
                : undefined;
            await sendMessage.mutateAsync({
                content: finalContent,
                images: imageData,
                files: fileData,
                agent: agent || undefined,
                provider: provider || undefined,
                model: model || undefined,
                userContext: userContext || undefined,
                reasoningText: modelSupportsReasoning && preferences.reasoningEnabled
                    ? true
                    : undefined,
            });
            clearFiles();
        }
        catch (error) {
            console.error('Failed to send message:', error);
        }
    }, [
        sendMessage,
        documents,
        images,
        clearFiles,
        agent,
        provider,
        model,
        userContext,
        modelSupportsReasoning,
        preferences.reasoningEnabled,
        sessionId,
        consumeResearchContexts,
    ]);
    const handleToggleConfig = useCallback(() => {
        setIsConfigOpen((prev) => !prev);
    }, []);
    const handleCloseConfig = useCallback(() => {
        setIsConfigOpen(false);
        setConfigFocusTarget(null);
    }, []);
    const handleCommand = useCallback(async (commandId) => {
        if (commandId === 'models') {
            setConfigFocusTarget('model');
            setIsConfigOpen(true);
        }
        else if (commandId === 'agents') {
            setConfigFocusTarget('agent');
            setIsConfigOpen(true);
        }
        else if (commandId === 'new') {
            onNewSession?.();
        }
        else if (commandId === 'stage') {
            const unstagedPaths = gitStatus?.unstaged?.map((f) => f.path) ?? [];
            const untrackedPaths = gitStatus?.untracked?.map((f) => f.path) ?? [];
            const allUnstaged = [...unstagedPaths, ...untrackedPaths];
            if (allUnstaged.length > 0) {
                stageFiles.mutate(allUnstaged);
            }
        }
        else if (commandId === 'commit') {
            openCommitModalForSession(sessionId);
        }
        else if (commandId === 'compact') {
            handleSendMessage('/compact');
        }
        else if (commandId === 'delete') {
            deleteSession.mutate(sessionId, {
                onSuccess: () => {
                    onDeleteSession?.();
                },
            });
        }
        else if (commandId === 'share') {
            const toastId = toast.loading('Sharing session...');
            try {
                const result = await apiClient.shareSession(sessionId);
                if (result.shared) {
                    toast.successWithAction(result.message === 'Already shared'
                        ? 'Already shared'
                        : 'Session shared!', { label: 'Open', href: result.url });
                    queryClient.invalidateQueries({
                        queryKey: ['share-status', sessionId],
                    });
                }
            }
            catch (error) {
                toast.error(error instanceof Error ? error.message : 'Failed to share');
            }
            finally {
                useToastStore.getState().removeToast(toastId);
            }
        }
        else if (commandId === 'sync') {
            const toastId = toast.loading('Syncing session...');
            try {
                const result = await apiClient.syncSession(sessionId);
                if (result.synced) {
                    const msg = result.newMessages > 0
                        ? `Synced ${result.newMessages} new messages`
                        : 'Already synced';
                    toast.successWithAction(msg, {
                        label: 'Open',
                        href: result.url,
                    });
                    queryClient.invalidateQueries({
                        queryKey: ['share-status', sessionId],
                    });
                }
            }
            catch (error) {
                toast.error(error instanceof Error ? error.message : 'Failed to sync');
            }
            finally {
                useToastStore.getState().removeToast(toastId);
            }
        }
    }, [
        onNewSession,
        gitStatus,
        stageFiles,
        openCommitModalForSession,
        handleSendMessage,
        deleteSession,
        sessionId,
        onDeleteSession,
        queryClient,
    ]);
    const handleAgentChange = useCallback(async (value) => {
        setAgent(value);
        try {
            await updateSession.mutateAsync({ agent: value });
        }
        catch (error) {
            console.error('Failed to update agent:', error);
        }
    }, [updateSession]);
    const handleModelSelectorChange = useCallback(async (newProvider, newModel) => {
        setProvider(newProvider);
        setModel(newModel);
        try {
            await updateSession.mutateAsync({
                provider: newProvider,
                model: newModel,
            });
        }
        catch (error) {
            console.error('Failed to update model:', error);
        }
    }, [updateSession]);
    const handleProviderChange = useCallback(async (newProvider) => {
        setProvider(newProvider);
        if (model) {
            try {
                await updateSession.mutateAsync({
                    provider: newProvider,
                    model,
                });
            }
            catch (error) {
                console.error('Failed to update provider:', error);
            }
        }
    }, [model, updateSession]);
    const handleModelChange = useCallback(async (newModel) => {
        setModel(newModel);
        try {
            await updateSession.mutateAsync({ provider, model: newModel });
        }
        catch (error) {
            console.error('Failed to update model:', error);
        }
    }, [provider, updateSession]);
    const handlePlanModeToggle = useCallback(async (isPlanMode) => {
        const newAgent = isPlanMode ? 'plan' : 'build';
        setAgent(newAgent);
        try {
            await updateSession.mutateAsync({ agent: newAgent });
        }
        catch (error) {
            console.error('Failed to switch agent:', error);
        }
    }, [updateSession]);
    return (_jsxs(_Fragment, { children: [_jsx(ConfigModal, { isOpen: isConfigOpen, onClose: handleCloseConfig, initialFocus: configFocusTarget, chatInputRef: chatInputRef, agent: agent, provider: provider, model: model, modelSupportsReasoning: modelSupportsReasoning, onAgentChange: handleAgentChange, onProviderChange: handleProviderChange, onModelChange: handleModelChange, onModelSelectorChange: handleModelSelectorChange }), _jsx(ChatInput, { ref: chatInputRef, onSend: handleSendMessage, onCommand: handleCommand, disabled: sendMessage.isPending, onConfigClick: handleToggleConfig, onPlanModeToggle: handlePlanModeToggle, isPlanMode: agent === 'plan', reasoningEnabled: modelSupportsReasoning && preferences.reasoningEnabled, sessionId: sessionId, images: images, documents: documents, onFileRemove: removeFile, isDragging: isDragging, onPaste: handlePaste, visionEnabled: modelSupportsVision, modelName: model, providerName: provider, authType: providerAuthType, researchContexts: researchContexts, onResearchContextRemove: handleResearchContextRemove, onRefreshBalance: provider === 'setu' ? fetchBalance : undefined, isBalanceLoading: isBalanceLoading }, inputKey)] }));
}));
//# sourceMappingURL=ChatInputContainer.js.map