import React, { useState, useEffect, useRef, useCallback } from 'react';
import { AmbientTextField } from '../UI/inputs/textField/AmbientTextField';
import { FluentButton } from '../UI/inputs/buttons/FluentButton';
import { useUser } from '../utilities/auth/useUser';
import { ChatMessage } from './ChatMessage';
import { Link, Typography } from '@material-ui/core';
import { makeStyles } from '@material-ui/core/styles';
import { apiMutate } from '../utilities/useAxiosMutate';
import { useChatBot } from '../utilities/chatBot/useChatBot';
import { useTranslation } from 'react-i18next';
import { useSnackbar } from 'notistack';
import { ConfigService } from '../configService';
const useStyles = makeStyles((theme) => ({
    loadingContainer: {
        display: 'inline-block',
        fontSize: '2em', // Adjust the font size to make the whole section bigger
    },
    pulseEllipsis: {
        display: 'inline-block',
        animation: '$pulse 1.5s infinite',
        '&:nth-of-type(2)': {
            animationDelay: '0.5s',
        },
        '&:nth-of-type(3)': {
            animationDelay: '1s',
        },
    },
    '@keyframes pulse': {
        '0%': {
            transform: 'scale(1)',
            opacity: 0.6,
        },
        '50%': {
            transform: 'scale(1.2)',
            opacity: 1,
        },
        '100%': {
            transform: 'scale(1)',
            opacity: 0.6,
        },
    },
}));
export const ChatContainer = (props) => {
    const classes = useStyles();
    const { messageHistory, addMessage, removeMessageHistory, removeLoadingMessage } = useChatBot();
    const user = useUser();
    const [newMessageContent, setNewMessageContent] = useState('');
    const messageEndRef = useRef(null);
    const productId = ConfigService.config.UNITY_PRODUCT_ID;
    const aiSearchUrl = ConfigService.config.AI_SEARCH_URL;
    const aiSearchIndexName = ConfigService.config.AI_SEARCH_INDEX_NAME;
    const aiSearchKey = ConfigService.config.AI_SEARCH_KEY;
    const udpAiApiBase = ConfigService.config.UDPAI_API_BASE;
    const { enqueueSnackbar } = useSnackbar();
    const { t } = useTranslation();
    const handleSendMessage = async () => {
        addMessage(newMessageContent, Object.assign(Object.assign({}, user), { name: 'You' }), newMessageContent);
        setNewMessageContent('');
        addLoadingMessage();
        try {
            await sendMessage(newMessageContent, addMessage);
            removeLoadingMessage();
        }
        catch (error) {
            console.error('Error sending message:', error);
        }
    };
    const handleNewSession = async () => {
        try {
            await removeMessageHistory();
            enqueueSnackbar(t(`Chat Session Cleared`), {
                variant: 'success',
                anchorOrigin: {
                    vertical: 'top',
                    horizontal: 'center',
                }
            });
        }
        catch (error) {
            console.error('Error create new chat session:', error);
        }
    };
    const addLoadingMessage = () => {
        const messageContent = (React.createElement("div", { className: classes.loadingContainer }, React.createElement("span", { className: classes.pulseEllipsis }, "."), React.createElement("span", { className: classes.pulseEllipsis }, "."), React.createElement("span", { className: classes.pulseEllipsis }, ".")));
        addMessage(messageContent, { name: 'AI Assistant', loading: true }, "");
    };
    useEffect(() => {
        var _a;
        (_a = messageEndRef.current) === null || _a === void 0 ? void 0 : _a.scrollIntoView({ behavior: 'smooth' });
    }, [messageHistory]);
    const formatCitations = (citations) => {
        return (React.createElement("div", null, React.createElement("ol", null, citations.map((citation) => {
            return (React.createElement("li", null, React.createElement(Link, { href: citation.url, target: "_blank", rel: "noopener" }, React.createElement(Typography, { variant: "body2", style: { whiteSpace: 'pre-line' } }, citation.title))));
        }))));
    };
    const parseAiResponse = (response, addMessage) => {
        try {
            const gptResponseMessage = response.data.LLMResponse.choices[0].message;
            const messageText = gptResponseMessage.content;
            const citations = gptResponseMessage.context.citations;
            const showCitations = messageText.toString().includes('[doc');
            const textContent = messageText.toString().replaceAll('[doc', '[');
            const responseMessage = (React.createElement("div", null, React.createElement("div", { style: { wordWrap: 'break-word' } }, React.createElement(Typography, { variant: "body2", style: { whiteSpace: 'pre-line' } }, textContent)), citations.length > 0 && showCitations && (React.createElement("div", null, React.createElement("br", null), React.createElement(Typography, { variant: "body2", style: { whiteSpace: 'pre-line' } }, "Refer to the XWiki documents for more info"), formatCitations(citations)))));
            addMessage(responseMessage, { name: 'AI Assistant' }, textContent);
        }
        catch (e) {
            const errorMessage = "Sorry, an error has occurred.";
            addMessage(errorMessage, { name: 'AI Assistant' }, errorMessage);
        }
    };
    const executeQuery = useCallback(async (data, aiModelId) => apiMutate(udpAiApiBase, `aiservice/llm`, {
        method: 'post',
        headers: {
            currentProductId: productId, //temporary bypass -> //currentProductId: '1'
        }
    }, data), [productId, udpAiApiBase]);
    const sendMessage = async (newMessageContent, addMessage) => {
        const messageHistoryTextArray = messageHistory
            .map(item => ({
            role: item.createdBy.name === 'AI Assistant' ? 'assistant' : item.createdBy.name === 'You' ? 'user' : item.createdBy.name,
            content: item.messageText
        }));
        const body = {
            modelName: 'gpt-4o',
            useCache: 'false',
            payload: {
                max_tokens: 4096,
                temperature: 0.5,
                n: 1,
                presence_penalty: 0,
                messages: [
                    {
                        role: 'system',
                        content: 'You are an assistant helping a user using existing knowledge supplemented by additional data.'
                    },
                    ...messageHistoryTextArray,
                    {
                        role: 'user',
                        content: newMessageContent
                    }
                ],
                data_sources: [
                    {
                        type: 'azure_search',
                        parameters: {
                            endpoint: aiSearchUrl,
                            // set sematic configuration name to match index name
                            semantic_configuration: aiSearchIndexName,
                            query_type: "semantic",
                            in_scope: false,
                            //role_information: "You are an AI search assistant having access to wiki documentation data. Please be helpful to the user answer any questions to the best of your ability.",
                            strictness: 1,
                            top_n_documents: 5,
                            authentication: {
                                type: 'api_key',
                                key: aiSearchKey
                            },
                            index_name: aiSearchIndexName,
                            filter: `Products/any(p: p eq '${productId}')`
                        }
                    }
                ]
            }
        };
        const aiResponse = await executeQuery({ data: body });
        parseAiResponse(aiResponse, addMessage);
    };
    return (React.createElement("div", { style: { display: 'flex', flexDirection: 'column', height: '100%' } }, React.createElement(FluentButton, { id: "udpRecord-ChatContainer-NewSession", onClick: handleNewSession }, "Clear Chat"), React.createElement("div", { style: {
            display: 'flex',
            flexDirection: 'column',
            gap: '10px',
            padding: '3px',
            height: '100%',
            overflowY: 'auto',
            flexGrow: 1
        } }, messageHistory.map((message, index) => (React.createElement(ChatMessage, { key: index, message: message }))), React.createElement("div", { ref: messageEndRef })), React.createElement("div", { style: { display: 'flex', flexDirection: 'column', marginTop: '5px', position: 'sticky', bottom: 0, padding: '3px', zIndex: 1, background: 'white' } }, React.createElement("div", { style: { flexGrow: 1 } }, React.createElement(AmbientTextField, { id: "udpRecord-ChatContainer-Enter", multiline: true, value: newMessageContent, onChange: (e) => setNewMessageContent(e.target.value), onKeyDown: (e) => {
            if (e.key === 'Enter' && !e.shiftKey) {
                e.preventDefault();
                handleSendMessage();
            }
        } })), React.createElement(FluentButton, { id: "udpRecord-ChatContainer-Send", onClick: handleSendMessage, autoFocus: true, variant: "outlined" }, "Sen"))));
};
//# sourceMappingURL=ChatContainer.js.map