import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
import { memo, useState, useEffect, useCallback, useRef, useMemo } from 'react';
import { ChevronRight, FlaskConical, Plus, History, Loader2, ArrowUp, ArrowDownToLine, ExternalLink, ChevronDown, Check, X, } from 'lucide-react';
import { useResearchStore } from '../../stores/researchStore';
import { useResearchSessions, useCreateResearchSession, useInjectContext, useExportToSession, } from '../../hooks/useResearch';
import { useUpdateSession } from '../../hooks/useSessions';
import { useAllModels } from '../../hooks/useConfig';
import { useMessages } from '../../hooks/useMessages';
import { useSessionStream } from '../../hooks/useSessionStream';
import { useMutation, useQueryClient } from '@tanstack/react-query';
import { apiClient } from '../../lib/api-client';
import { Button } from '../ui/Button';
import { Textarea } from '../ui/Textarea';
import { Modal } from '../ui/Modal';
import { UnifiedModelSelector } from '../chat/UnifiedModelSelector';
import { AssistantMessageGroup } from '../messages/AssistantMessageGroup';
import { UserMessageGroup } from '../messages/UserMessageGroup';
export const ResearchSidebar = memo(function ResearchSidebar({ parentSessionId, onNavigateToSession, }) {
    const isExpanded = useResearchStore((state) => state.isExpanded);
    const collapseSidebar = useResearchStore((state) => state.collapseSidebar);
    const activeResearchSessionId = useResearchStore((state) => state.activeResearchSessionId);
    const selectResearchSession = useResearchStore((state) => state.selectResearchSession);
    const [showHistory, setShowHistory] = useState(false);
    const [inputValue, setInputValue] = useState('');
    const [showModelSelector, setShowModelSelector] = useState(false);
    const [injectionStatus, setInjectionStatus] = useState('idle');
    const textareaRef = useRef(null);
    const messagesEndRef = useRef(null);
    const { data: researchData, isLoading, refetch, } = useResearchSessions(parentSessionId);
    const createMutation = useCreateResearchSession();
    const injectMutation = useInjectContext();
    const exportMutation = useExportToSession();
    const { data: allModels } = useAllModels();
    const { data: messagesData } = useMessages(activeResearchSessionId ?? undefined);
    const { data: parentMessagesData } = useMessages(parentSessionId ?? undefined);
    // Enable streaming for the active research session
    useSessionStream(activeResearchSessionId ?? undefined);
    const updateSession = useUpdateSession(activeResearchSessionId ?? '');
    const queryClient = useQueryClient();
    const sendMessage = useMutation({
        mutationFn: async ({ sessionId, content, }) => apiClient.sendMessage(sessionId, { content }),
        onSuccess: (_, { sessionId }) => {
            queryClient.invalidateQueries({ queryKey: ['messages', sessionId] });
        },
    });
    useEffect(() => {
        if (parentSessionId) {
            useResearchStore.getState().setParentSessionId(parentSessionId);
        }
    }, [parentSessionId]);
    useEffect(() => {
        if (researchData?.sessions?.length) {
            const currentIsValid = researchData.sessions.some((s) => s.id === activeResearchSessionId);
            if (!currentIsValid) {
                selectResearchSession(researchData.sessions[0].id);
            }
        }
        else if (researchData?.sessions?.length === 0) {
            selectResearchSession(null);
        }
    }, [researchData, activeResearchSessionId, selectResearchSession]);
    useEffect(() => {
        messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });
    }, []);
    const adjustTextareaHeight = useCallback(() => {
        const textarea = textareaRef.current;
        if (!textarea)
            return;
        textarea.style.height = 'auto';
        textarea.style.height = `${Math.min(textarea.scrollHeight, 120)}px`;
    }, []);
    useEffect(() => {
        adjustTextareaHeight();
    }, [adjustTextareaHeight]);
    const handleCreateNew = useCallback(async () => {
        if (!parentSessionId)
            return;
        try {
            const result = await createMutation.mutateAsync({
                parentSessionId,
                data: {},
            });
            // Wait for query to refetch before selecting
            await refetch();
            selectResearchSession(result.session.id);
            setShowHistory(false);
        }
        catch (err) {
            console.error('Failed to create research session:', err);
        }
    }, [parentSessionId, createMutation, selectResearchSession, refetch]);
    const handleSelectSession = useCallback((session) => {
        selectResearchSession(session.id);
        setShowHistory(false);
    }, [selectResearchSession]);
    const handleInject = useCallback(async () => {
        if (!parentSessionId || !activeResearchSessionId)
            return;
        // Check if already injected
        const alreadyInjected = parentMessagesData?.some((m) => m.role === 'system' &&
            m.parts?.some((p) => typeof p.content === 'string' &&
                p.content.includes(`from="${activeResearchSessionId}"`)));
        if (alreadyInjected) {
            setInjectionStatus('error');
            setTimeout(() => setInjectionStatus('idle'), 3000);
            return;
        }
        // Generate a descriptive label with timestamp
        const now = new Date();
        const timeStr = now.toLocaleTimeString([], {
            hour: '2-digit',
            minute: '2-digit',
        });
        const label = `Research ${timeStr}`;
        try {
            await injectMutation.mutateAsync({
                parentSessionId,
                researchSessionId: activeResearchSessionId,
                label,
            });
            setInjectionStatus('success');
            setTimeout(() => setInjectionStatus('idle'), 5000);
            // Invalidate parent messages to update the UI
            queryClient.invalidateQueries({
                queryKey: ['messages', parentSessionId],
            });
        }
        catch (err) {
            console.error('Failed to inject context:', err);
            setInjectionStatus('error');
            setTimeout(() => setInjectionStatus('idle'), 3000);
        }
    }, [
        parentSessionId,
        activeResearchSessionId,
        injectMutation,
        parentMessagesData,
        queryClient,
    ]);
    const handleExport = useCallback(async () => {
        if (!activeResearchSessionId)
            return;
        try {
            const result = await exportMutation.mutateAsync({
                researchId: activeResearchSessionId,
            });
            if (onNavigateToSession && result.newSession?.id) {
                onNavigateToSession(result.newSession.id);
            }
        }
        catch (err) {
            console.error('Failed to export to session:', err);
        }
    }, [activeResearchSessionId, exportMutation, onNavigateToSession]);
    const handleSendMessage = useCallback(async () => {
        if (!inputValue.trim() || !parentSessionId)
            return;
        try {
            let sessionId = activeResearchSessionId;
            if (!sessionId) {
                const result = await createMutation.mutateAsync({
                    parentSessionId,
                    data: {},
                });
                sessionId = result.session.id;
                selectResearchSession(sessionId);
            }
            await sendMessage.mutateAsync({
                sessionId,
                content: inputValue,
            });
            setInputValue('');
            if (textareaRef.current) {
                textareaRef.current.style.height = 'auto';
            }
        }
        catch (err) {
            console.error('Failed to send message:', err);
        }
    }, [
        inputValue,
        parentSessionId,
        activeResearchSessionId,
        createMutation,
        selectResearchSession,
        sendMessage,
    ]);
    const handleKeyDown = useCallback((e) => {
        if (e.key === 'Enter' && !e.shiftKey) {
            e.preventDefault();
            handleSendMessage();
        }
    }, [handleSendMessage]);
    const isGenerating = useMemo(() => messagesData?.some((m) => m.role === 'assistant' && m.status === 'pending') ?? false, [messagesData]);
    const isAlreadyInjected = useMemo(() => {
        if (!activeResearchSessionId || !parentMessagesData)
            return false;
        return parentMessagesData.some((m) => m.role === 'system' &&
            m.parts?.some((p) => typeof p.content === 'string' &&
                p.content.includes(`from="${activeResearchSessionId}"`)));
    }, [activeResearchSessionId, parentMessagesData]);
    const handleModelChange = useCallback(async (newProvider, newModel) => {
        if (!activeResearchSessionId)
            return;
        try {
            await updateSession.mutateAsync({
                provider: newProvider,
                model: newModel,
            });
            setShowModelSelector(false);
        }
        catch (err) {
            console.error('Failed to update research session model:', err);
        }
    }, [activeResearchSessionId, updateSession]);
    if (!isExpanded)
        return null;
    const sessions = researchData?.sessions ?? [];
    const activeSession = sessions.find((s) => s.id === activeResearchSessionId);
    const messages = messagesData ?? [];
    const currentProviderLabel = allModels?.[activeSession?.provider ?? '']?.label ??
        activeSession?.provider;
    const currentModelLabel = allModels?.[activeSession?.provider ?? '']?.models.find((m) => m.id === activeSession?.model)?.label ?? activeSession?.model;
    return (_jsxs("div", { className: "w-96 border-l border-border bg-background flex flex-col h-full", children: [_jsxs("div", { className: "h-14 border-b border-border px-3 flex items-center justify-between", children: [_jsxs("div", { className: "flex items-center gap-2 flex-1", children: [_jsx(FlaskConical, { className: "w-4 h-4 text-teal-500" }), _jsx("span", { className: "font-medium text-foreground text-sm", children: "Research" })] }), _jsxs("div", { className: "flex items-center gap-0.5", children: [_jsx(Button, { variant: "ghost", size: "icon", onClick: () => setShowHistory(!showHistory), title: "Research history", className: "h-8 w-8", children: _jsx(History, { className: "w-4 h-4" }) }), _jsx(Button, { variant: "ghost", size: "icon", onClick: handleCreateNew, disabled: !parentSessionId || createMutation.isPending, title: "New research session", className: "h-8 w-8", children: createMutation.isPending ? (_jsx(Loader2, { className: "w-4 h-4 animate-spin" })) : (_jsx(Plus, { className: "w-4 h-4" })) }), _jsx(Button, { variant: "ghost", size: "icon", onClick: collapseSidebar, title: "Close sidebar", className: "h-8 w-8", children: _jsx(ChevronRight, { className: "w-4 h-4" }) })] })] }), showHistory ? (_jsxs("div", { className: "flex-1 overflow-y-auto", children: [_jsx("div", { className: "p-2 border-b border-border", children: _jsx("div", { className: "text-xs font-medium text-muted-foreground px-2 py-1", children: "Research Sessions" }) }), isLoading ? (_jsx("div", { className: "p-4 text-sm text-muted-foreground", children: "Loading..." })) : sessions.length === 0 ? (_jsx("div", { className: "p-4 text-sm text-muted-foreground", children: "No research sessions yet" })) : (_jsx("div", { className: "p-2 space-y-1", children: sessions.map((session) => (_jsxs("button", { type: "button", onClick: () => handleSelectSession(session), className: `w-full text-left p-2 rounded-md text-sm transition-colors ${session.id === activeResearchSessionId
                                ? 'bg-teal-500/10 border border-teal-500/30 text-foreground'
                                : 'hover:bg-muted'}`, children: [_jsx("div", { className: "font-medium truncate", children: session.title || 'Untitled' }), _jsxs("div", { className: "text-xs text-muted-foreground", children: [session.messageCount, " messages \u2022", ' ', formatRelativeTime(session.lastActiveAt ?? session.createdAt)] })] }, session.id))) }))] })) : (_jsxs(_Fragment, { children: [_jsx("div", { className: "flex-1 overflow-y-auto px-3 py-3 research-messages text-[13px]", children: !activeResearchSessionId ? (_jsxs("div", { className: "text-xs text-muted-foreground text-center py-8", children: [_jsx(FlaskConical, { className: "w-8 h-8 mx-auto mb-2 text-muted-foreground/50" }), _jsx("p", { children: "Start researching by asking a question below." })] })) : messages.length === 0 ? (_jsx("div", { className: "text-xs text-muted-foreground text-center py-8", children: _jsx("p", { children: "Ask a question to start researching." }) })) : (_jsxs("div", { className: "space-y-1.5", children: [messages.map((msg, index) => {
                                    if (msg.role === 'user') {
                                        const nextMsg = messages[index + 1];
                                        return (_jsx(UserMessageGroup, { sessionId: activeResearchSessionId, message: msg, isFirst: index === 0, nextAssistantMessageId: nextMsg?.role === 'assistant' ? nextMsg.id : undefined }, msg.id));
                                    }
                                    if (msg.role === 'assistant') {
                                        const prevMsg = index > 0 ? messages[index - 1] : null;
                                        const nextMsg = messages[index + 1];
                                        const showHeader = prevMsg?.role !== 'assistant';
                                        const hasNextAssistant = nextMsg?.role === 'assistant';
                                        return (_jsx(AssistantMessageGroup, { sessionId: activeResearchSessionId, message: msg, showHeader: showHeader, hasNextAssistantMessage: hasNextAssistant, isLastMessage: index === messages.length - 1, compact: true, onNavigateToSession: onNavigateToSession }, msg.id));
                                    }
                                    return null;
                                }), _jsx("div", { ref: messagesEndRef })] })) }), _jsxs("div", { className: "p-3 border-t border-border", children: [_jsx("div", { className: "relative flex flex-col rounded-3xl bg-card border border-border focus-within:border-teal-500/60 focus-within:ring-1 focus-within:ring-teal-500/40 p-1", children: _jsxs("div", { className: "flex items-end gap-1", children: [_jsx(Textarea, { ref: textareaRef, value: inputValue, onChange: (e) => setInputValue(e.target.value), onKeyDown: handleKeyDown, placeholder: "Ask anything...", disabled: !parentSessionId ||
                                                sendMessage.isPending ||
                                                createMutation.isPending, rows: 1, className: "flex-1 border-0 bg-transparent pl-2 pr-1 py-2 max-h-[120px] overflow-y-auto leading-normal resize-none scrollbar-hide text-sm focus:ring-0 focus:outline-none", style: { height: '2.25rem' } }), _jsx("button", { type: "button", onClick: handleSendMessage, disabled: !inputValue.trim() ||
                                                !parentSessionId ||
                                                sendMessage.isPending ||
                                                createMutation.isPending ||
                                                isGenerating, className: `flex items-center justify-center w-9 h-9 rounded-full transition-colors flex-shrink-0 ${inputValue.trim() && parentSessionId && !isGenerating
                                                ? 'bg-teal-500 hover:bg-teal-600 text-white'
                                                : 'bg-transparent text-muted-foreground'}`, children: sendMessage.isPending || createMutation.isPending ? (_jsx(Loader2, { className: "w-4 h-4 animate-spin" })) : (_jsx(ArrowUp, { className: "w-4 h-4" })) })] }) }), injectionStatus === 'success' && (_jsxs("div", { className: "flex items-center gap-2 mt-2 px-2 py-1.5 text-xs rounded-lg bg-teal-500/10 border border-teal-500/30 text-teal-600 dark:text-teal-400", children: [_jsx(Check, { className: "w-3 h-3 flex-shrink-0" }), _jsx("span", { className: "flex-1", children: "Context injected \u2014 will be used on next request" }), _jsx("button", { type: "button", onClick: () => setInjectionStatus('idle'), className: "hover:text-teal-500", children: _jsx(X, { className: "w-3 h-3" }) })] })), injectionStatus === 'error' && (_jsxs("div", { className: "flex items-center gap-2 mt-2 px-2 py-1.5 text-xs rounded-lg bg-red-500/10 border border-red-500/30 text-red-600 dark:text-red-400", children: [_jsx(X, { className: "w-3 h-3 flex-shrink-0" }), _jsx("span", { className: "flex-1", children: "Failed to inject context" }), _jsx("button", { type: "button", onClick: () => setInjectionStatus('idle'), className: "hover:text-red-500", children: _jsx(X, { className: "w-3 h-3" }) })] })), _jsxs("div", { className: "flex gap-2 mt-2", children: [_jsxs("button", { type: "button", onClick: handleInject, disabled: !activeResearchSessionId ||
                                            injectMutation.isPending ||
                                            isGenerating ||
                                            isAlreadyInjected, className: `flex-1 flex items-center justify-center gap-1.5 px-2 py-1.5 text-xs rounded-lg transition-colors disabled:opacity-50 disabled:cursor-not-allowed ${isAlreadyInjected
                                            ? 'bg-teal-500/10 text-teal-600 dark:text-teal-400 border border-teal-500/30'
                                            : 'bg-muted hover:bg-muted/80 text-muted-foreground hover:text-foreground'}`, title: isAlreadyInjected
                                            ? 'Already injected into main session'
                                            : 'Inject findings into main session', children: [injectMutation.isPending ? (_jsx(Loader2, { className: "w-3 h-3 animate-spin" })) : isAlreadyInjected ? (_jsx(Check, { className: "w-3 h-3" })) : (_jsx(ArrowDownToLine, { className: "w-3 h-3" })), isAlreadyInjected ? 'Injected' : 'Inject'] }), _jsxs("button", { type: "button", onClick: handleExport, disabled: !activeResearchSessionId ||
                                            exportMutation.isPending ||
                                            isGenerating, className: "flex-1 flex items-center justify-center gap-1.5 px-2 py-1.5 text-xs rounded-lg bg-muted hover:bg-muted/80 text-muted-foreground hover:text-foreground transition-colors disabled:opacity-50 disabled:cursor-not-allowed", title: "Export to new main session", children: [exportMutation.isPending ? (_jsx(Loader2, { className: "w-3 h-3 animate-spin" })) : (_jsx(ExternalLink, { className: "w-3 h-3" })), "Export"] })] })] })] })), _jsxs("div", { className: "h-12 px-3 border-t border-border text-xs text-muted-foreground flex items-center justify-between", children: [_jsxs("span", { className: "text-[10px]", children: [sessions.length, " research session", sessions.length !== 1 ? 's' : ''] }), activeSession && (_jsxs("button", { type: "button", onClick: () => setShowModelSelector(true), className: "flex items-center gap-1 text-[10px] hover:text-foreground transition-colors", children: [_jsx("span", { className: "opacity-60", children: currentProviderLabel }), _jsx("span", { className: "opacity-40", children: "/" }), _jsx("span", { children: currentModelLabel }), _jsx(ChevronDown, { className: "w-3 h-3 opacity-40" })] }))] }), _jsx(Modal, { isOpen: showModelSelector, onClose: () => setShowModelSelector(false), title: "Select Model for Research", maxWidth: "md", children: activeSession && (_jsx(UnifiedModelSelector, { provider: activeSession.provider, model: activeSession.model, onChange: handleModelChange })) })] }));
});
function formatRelativeTime(timestamp) {
    const diff = Date.now() - timestamp;
    const minutes = Math.floor(diff / 60000);
    if (minutes < 1)
        return 'just now';
    if (minutes < 60)
        return `${minutes}m ago`;
    const hours = Math.floor(minutes / 60);
    if (hours < 24)
        return `${hours}h ago`;
    const days = Math.floor(hours / 24);
    return `${days}d ago`;
}
//# sourceMappingURL=ResearchSidebar.js.map