"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.AiChatInterface = void 0;
const jsx_runtime_1 = require("react/jsx-runtime");
const react_1 = require("react");
const Card_1 = require("../common/Card");
const Button_1 = require("../forms/Button");
const Textarea_1 = require("../forms/Textarea");
const Select_1 = require("../forms/Select");
const ChatService_1 = require("../../services/ChatService");
const UIConfigService_1 = require("../../services/UIConfigService");
const AiChatInterface = ({ conversationId, onConversationChange, onSendMessage, className = '', height = 'h-96', apiConfig, customConfig = {}, }) => {
    // Get configuration from UI config service
    const config = UIConfigService_1.uiConfigService.getConfig();
    const chatConfig = { ...config.chat, ...customConfig };
    const features = { ...config.features, ...customConfig };
    const branding = config.branding;
    // Component state
    const [currentMessage, setCurrentMessage] = (0, react_1.useState)('');
    const [selectedModel, setSelectedModel] = (0, react_1.useState)('');
    const [isLoading, setIsLoading] = (0, react_1.useState)(false);
    const [isTyping, setIsTyping] = (0, react_1.useState)(false);
    const [availableModels, setAvailableModels] = (0, react_1.useState)([]);
    const [messages, setMessages] = (0, react_1.useState)([]);
    const [error, setError] = (0, react_1.useState)(null);
    const [currentConversationId, setCurrentConversationId] = (0, react_1.useState)(conversationId || null);
    const messagesEndRef = (0, react_1.useRef)(null);
    // Get dynamic values from config service
    const placeholder = customConfig.placeholder || UIConfigService_1.uiConfigService.getPlaceholderText();
    const welcomeMessage = customConfig.welcomeMessage || UIConfigService_1.uiConfigService.getWelcomeMessage();
    const enableMarkdown = features.enableMarkdown;
    const enableVoiceInput = features.enableVoiceInput;
    const enableFileUpload = features.enableFileUpload;
    const maxHistory = features.maxHistoryLength;
    const showTypingIndicator = customConfig.showTypingIndicator ?? true;
    const theme = customConfig.theme || config.themes.default;
    const enableStreaming = features.enableStreaming;
    // Initialize component
    (0, react_1.useEffect)(() => {
        initializeChat();
    }, [conversationId, apiConfig]);
    (0, react_1.useEffect)(() => {
        scrollToBottom();
    }, [messages]);
    const scrollToBottom = () => {
        messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });
    };
    const initializeChat = async () => {
        try {
            setIsLoading(true);
            setError(null);
            // Configure chat service if API config provided
            if (apiConfig) {
                // In a real implementation, you'd update the service configuration
                console.log('Configuring chat service with:', apiConfig);
            }
            // Load available models
            const models = customConfig.models || await ChatService_1.chatService.getAvailableModels();
            setAvailableModels(models);
            // Set default model
            if (models.length > 0) {
                const defaultModel = customConfig.models?.find(m => m.id === config.models.defaultModel) ||
                    models.find(m => config.models.preferredModels.includes(m.id)) ||
                    models[0];
                setSelectedModel(defaultModel.id);
            }
            // Load existing conversation or create new one
            if (conversationId) {
                const conversation = ChatService_1.chatService.getConversation(conversationId);
                if (conversation) {
                    setMessages(conversation.messages);
                    setCurrentConversationId(conversationId);
                }
            }
            else {
                // Create new conversation if none specified
                const newConversationId = ChatService_1.chatService.createConversation(selectedModel || config.models.defaultModel);
                setCurrentConversationId(newConversationId);
                onConversationChange?.(newConversationId);
            }
        }
        catch (err) {
            setError(err instanceof Error ? err.message : 'Failed to initialize chat');
            console.error('Chat initialization error:', err);
        }
        finally {
            setIsLoading(false);
        }
    };
    const handleSendMessage = async () => {
        if (!currentMessage.trim() || isLoading)
            return;
        const messageText = currentMessage.trim();
        setCurrentMessage('');
        setIsLoading(true);
        setIsTyping(true);
        setError(null);
        try {
            // Use custom onSendMessage if provided, otherwise use chat service
            if (onSendMessage) {
                await onSendMessage(messageText, selectedModel);
                // If using custom handler, we need to manually update messages
                // This is handled by the parent component
            }
            else {
                // Use streaming if enabled
                if (enableStreaming) {
                    await handleStreamingMessage(messageText);
                }
                else {
                    const response = await ChatService_1.chatService.sendMessage(messageText, selectedModel, currentConversationId || undefined);
                    // Update messages from the current conversation
                    const conversation = ChatService_1.chatService.getConversation(currentConversationId);
                    if (conversation) {
                        setMessages([...conversation.messages]);
                    }
                }
            }
        }
        catch (err) {
            const errorMessage = err instanceof Error ? err.message : 'Failed to send message';
            setError(errorMessage);
            // Add error message to chat
            const errorChatMessage = {
                id: `error-${Date.now()}`,
                role: 'assistant',
                content: UIConfigService_1.uiConfigService.getSystemMessage('error'),
                timestamp: new Date(),
                metadata: { error: true }
            };
            setMessages(prev => [...prev, errorChatMessage]);
        }
        finally {
            setIsLoading(false);
            setIsTyping(false);
        }
    };
    const handleStreamingMessage = async (messageText) => {
        try {
            const generator = ChatService_1.chatService.sendStreamingMessage(messageText, selectedModel, currentConversationId || undefined);
            let streamingMessage = {
                id: `streaming-${Date.now()}`,
                role: 'assistant',
                content: '',
                timestamp: new Date(),
                metadata: { streaming: true }
            };
            // Add user message first
            const userMessage = {
                id: `user-${Date.now()}`,
                role: 'user',
                content: messageText,
                timestamp: new Date()
            };
            setMessages(prev => [...prev, userMessage, streamingMessage]);
            // Stream the response
            for await (const chunk of generator) {
                streamingMessage = {
                    ...streamingMessage,
                    content: chunk.content,
                    metadata: { ...streamingMessage.metadata, streaming: !chunk.done }
                };
                setMessages(prev => {
                    const newMessages = [...prev];
                    newMessages[newMessages.length - 1] = streamingMessage;
                    return newMessages;
                });
                if (chunk.done) {
                    break;
                }
            }
        }
        catch (err) {
            throw err;
        }
    };
    const handleKeyPress = (e) => {
        if (e.key === 'Enter' && !e.shiftKey) {
            e.preventDefault();
            handleSendMessage();
        }
    };
    const formatMessage = (content) => {
        if (enableMarkdown) {
            // Basic markdown rendering - in production use a proper markdown library
            return content
                .replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>')
                .replace(/\*(.*?)\*/g, '<em>$1</em>')
                .replace(/`(.*?)`/g, '<code>$1</code>');
        }
        return content;
    };
    return ((0, jsx_runtime_1.jsxs)(Card_1.Card, { className: `llm-ui-chat-interface theme-${theme} ${className}`, style: {
            '--primary-color': branding.primaryColor,
            '--secondary-color': branding.secondaryColor
        }, children: [(0, jsx_runtime_1.jsxs)("div", { className: "chat-header p-4 border-b bg-gradient-to-r from-blue-50 to-purple-50", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-between mb-2", children: [(0, jsx_runtime_1.jsxs)("h3", { className: "text-lg font-semibold text-gray-900", children: [branding.appName, " Chat"] }), error && ((0, jsx_runtime_1.jsx)("div", { className: "text-sm text-red-600 bg-red-50 px-2 py-1 rounded", children: error }))] }), availableModels.length > 0 && ((0, jsx_runtime_1.jsxs)("div", { className: "flex items-center space-x-2", children: [(0, jsx_runtime_1.jsx)("label", { className: "text-sm text-gray-600", children: "Model:" }), (0, jsx_runtime_1.jsx)(Select_1.Select, { value: selectedModel, onChange: (e) => setSelectedModel(e.target.value), className: "model-selector flex-1", disabled: isLoading, children: availableModels.map((model) => ((0, jsx_runtime_1.jsx)("option", { value: model.id, children: UIConfigService_1.uiConfigService.getModelDisplayName(model.id) }, model.id))) })] })), isLoading && availableModels.length === 0 && ((0, jsx_runtime_1.jsx)("div", { className: "text-sm text-gray-500", children: UIConfigService_1.uiConfigService.getSystemMessage('connecting') }))] }), (0, jsx_runtime_1.jsxs)("div", { className: `chat-messages ${height} overflow-y-auto p-4 space-y-4 bg-gray-50`, children: [welcomeMessage && messages.length === 0 && !isLoading && ((0, jsx_runtime_1.jsxs)("div", { className: "message system-message bg-gradient-to-r from-blue-50 to-indigo-50 border border-blue-200 p-4 rounded-lg", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-start space-x-2", children: [(0, jsx_runtime_1.jsx)("div", { className: "text-blue-500 text-xl", children: "\uD83E\uDD16" }), (0, jsx_runtime_1.jsx)("div", { className: "text-blue-900", children: welcomeMessage })] }), chatConfig.suggestions && chatConfig.suggestions.length > 0 && ((0, jsx_runtime_1.jsxs)("div", { className: "mt-3", children: [(0, jsx_runtime_1.jsx)("p", { className: "text-sm text-blue-700 mb-2", children: "Try asking:" }), (0, jsx_runtime_1.jsx)("div", { className: "flex flex-wrap gap-2", children: chatConfig.suggestions.slice(0, 3).map((suggestion, index) => ((0, jsx_runtime_1.jsx)("button", { onClick: () => setCurrentMessage(suggestion), className: "text-xs bg-blue-100 hover:bg-blue-200 text-blue-800 px-2 py-1 rounded-full transition-colors", children: suggestion }, index))) })] }))] })), messages.slice(-maxHistory).map((message) => ((0, jsx_runtime_1.jsx)("div", { className: `message ${message.role === 'user' ? 'user-message ml-8' : 'assistant-message mr-8'}`, children: (0, jsx_runtime_1.jsxs)("div", { className: `p-3 rounded-lg ${message.role === 'user'
                                ? 'bg-blue-500 text-white ml-auto'
                                : 'bg-gray-100 text-gray-900'}`, children: [(0, jsx_runtime_1.jsx)("div", { className: "message-content", dangerouslySetInnerHTML: { __html: formatMessage(message.content) } }), (0, jsx_runtime_1.jsxs)("div", { className: "message-meta text-xs opacity-70 mt-1 flex items-center justify-between", children: [(0, jsx_runtime_1.jsx)("span", { children: message.timestamp.toLocaleTimeString() }), (0, jsx_runtime_1.jsxs)("div", { className: "flex items-center space-x-2", children: [message.metadata?.streaming && ((0, jsx_runtime_1.jsx)("span", { className: "text-blue-500", children: "\u25CF" })), message.metadata?.model && ((0, jsx_runtime_1.jsx)("span", { className: "text-gray-500", children: UIConfigService_1.uiConfigService.getModelDisplayName(message.metadata.model) })), message.metadata?.tokens && ((0, jsx_runtime_1.jsxs)("span", { className: "text-gray-400", children: [message.metadata.tokens, " tokens"] })), message.metadata?.error && ((0, jsx_runtime_1.jsx)("span", { className: "text-red-500", children: "\u26A0\uFE0F" }))] })] })] }) }, message.id))), isTyping && showTypingIndicator && ((0, jsx_runtime_1.jsx)("div", { className: "typing-indicator mr-8", children: (0, jsx_runtime_1.jsx)("div", { className: "bg-white border border-gray-200 p-3 rounded-lg inline-block shadow-sm", children: (0, jsx_runtime_1.jsxs)("div", { className: "flex items-center space-x-2", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex space-x-1", children: [(0, jsx_runtime_1.jsx)("div", { className: "w-2 h-2 bg-gray-400 rounded-full animate-bounce" }), (0, jsx_runtime_1.jsx)("div", { className: "w-2 h-2 bg-gray-400 rounded-full animate-bounce", style: { animationDelay: '0.1s' } }), (0, jsx_runtime_1.jsx)("div", { className: "w-2 h-2 bg-gray-400 rounded-full animate-bounce", style: { animationDelay: '0.2s' } })] }), (0, jsx_runtime_1.jsxs)("span", { className: "text-xs text-gray-500", children: [selectedModel ? UIConfigService_1.uiConfigService.getModelDisplayName(selectedModel) : 'AI', " is thinking..."] })] }) }) })), (0, jsx_runtime_1.jsx)("div", { ref: messagesEndRef })] }), (0, jsx_runtime_1.jsx)("div", { className: "chat-input p-4 border-t", children: (0, jsx_runtime_1.jsxs)("div", { className: "flex space-x-2", children: [(0, jsx_runtime_1.jsx)(Textarea_1.Textarea, { value: currentMessage, onChange: (e) => setCurrentMessage(e.target.value), onKeyPress: handleKeyPress, placeholder: placeholder, className: "flex-1 resize-none", rows: 2, disabled: isLoading }), (0, jsx_runtime_1.jsxs)("div", { className: "flex flex-col space-y-2", children: [enableVoiceInput && ((0, jsx_runtime_1.jsx)(Button_1.Button, { type: "button", variant: "secondary", size: "sm", title: "Voice input", disabled: isLoading, children: "\uD83C\uDFA4" })), enableFileUpload && ((0, jsx_runtime_1.jsx)(Button_1.Button, { type: "button", variant: "secondary", size: "sm", title: "Upload file", disabled: isLoading, children: "\uD83D\uDCCE" })), (0, jsx_runtime_1.jsx)(Button_1.Button, { onClick: handleSendMessage, disabled: !currentMessage.trim() || isLoading, loading: isLoading, children: "Send" })] })] }) })] }));
};
exports.AiChatInterface = AiChatInterface;
exports.default = exports.AiChatInterface;
//# sourceMappingURL=AiChatInterface.js.map