import { Fragment, jsx, jsxs } from "react/jsx-runtime";
import { useLingui } from "@lingui/react";
import Search from "@mui/icons-material/Search";
import { CircularProgress, Popover, styled } from "@mui/material";
import apollo_core from "@uipath/apollo-core";
import { differenceInDays, differenceInMonths, isToday, isYesterday } from "date-fns";
import debounce from "debounce";
import react, { useCallback, useEffect, useMemo, useRef, useState } from "react";
import react_focus_lock from "react-focus-lock";
import { ApSkeleton } from "../../../ap-skeleton/index.js";
import { ApTextField } from "../../../ap-text-field/index.js";
import { ApTypography } from "../../../ap-typography/index.js";
import { useScheduledCallback } from "../../hooks/use-scheduled-callback.js";
import { useChatService } from "../../providers/chat-service.provider.js";
import { useChatState } from "../../providers/chat-state-provider.js";
import { useChatWidth } from "../../providers/chat-width-provider.js";
import { AutopilotChatEvent, AutopilotChatInternalEvent, CHAT_HISTORY_FULL_SCREEN_WIDTH, CHAT_HISTORY_SIDE_BY_SIDE_MAX_HEIGHT, CHAT_HISTORY_SIDE_BY_SIDE_MAX_WIDTH } from "../../service/index.js";
import { AutopilotChatHistoryGroup } from "./chat-history-group.js";
const ChatHistoryContainer = styled('div')(({ isFullScreen, width, fullScreenContainer })=>({
        display: 'flex',
        flexDirection: 'column',
        backgroundColor: 'var(--color-background)',
        padding: `${apollo_core.Spacing.SpacingXs} 0`,
        boxSizing: 'border-box',
        height: isFullScreen ? `calc(${fullScreenContainer?.clientHeight}px - ${apollo_core.Spacing.SpacingBase})` : CHAT_HISTORY_SIDE_BY_SIDE_MAX_HEIGHT,
        width: isFullScreen ? Math.min(width, CHAT_HISTORY_FULL_SCREEN_WIDTH) : Math.min(width, CHAT_HISTORY_SIDE_BY_SIDE_MAX_WIDTH - 2 * parseInt(apollo_core.Spacing.SpacingBase, 10)),
        '& .chat-history-search': {
            width: `calc(100% - 2 * ${apollo_core.Spacing.SpacingBase})`,
            marginLeft: apollo_core.Spacing.SpacingBase,
            '& .MuiInputBase-root': {
                backgroundColor: 'var(--color-background)'
            }
        },
        '& .chat-history-content': {
            outline: 'none',
            flex: 1,
            overflowY: 'auto',
            marginRight: `calc(-${apollo_core.Spacing.SpacingBase})`,
            paddingRight: apollo_core.Spacing.SpacingBase
        }
    }));
const EmptyStateContainer = styled('div')(()=>({
        display: 'flex',
        justifyContent: 'center',
        alignItems: 'center',
        height: '100%'
    }));
const HistorySkeletonContainer = styled('div')(()=>({
        padding: apollo_core.Spacing.SpacingBase,
        '& .skeleton-item': {
            padding: apollo_core.Spacing.SpacingXs,
            marginBottom: apollo_core.Spacing.SpacingXs
        }
    }));
const HistorySkeletonLoader = ()=>/*#__PURE__*/ jsx(HistorySkeletonContainer, {
        children: [
            ...Array(6)
        ].map((_, index)=>/*#__PURE__*/ jsx("div", {
                className: "skeleton-item",
                children: /*#__PURE__*/ jsx(ApSkeleton, {
                    style: {
                        width: '90%',
                        height: apollo_core.Spacing.SpacingL
                    }
                })
            }, index))
    });
const DEBOUNCE_DELAY_IN_MS = 400;
const LOAD_MORE_THRESHOLD_IN_PX = 50;
const AutopilotChatHistoryComponent = ({ open, isFullScreen })=>{
    const { _ } = useLingui();
    const chatService = useChatService();
    const internalService = chatService?.__internalService__;
    const [history, setHistory] = useState(chatService?.getHistory() ?? []);
    const [searchQuery, setSearchQuery] = useState('');
    const [isLoadingMore, setIsLoadingMore] = useState(false);
    const [isSearching, setIsSearching] = useState(false);
    const [scrollContainer, setScrollContainer] = useState(null);
    const popperContainerRef = useRef(null);
    const isLoadingMoreRef = useRef(false);
    const shouldShowLoadingMoreRef = useRef(true);
    const appendingRef = useRef(false);
    const scrollTopBeforeAppendRef = useRef(0);
    const searchQueryRef = useRef('');
    const { historyOpen, historyAnchorElement, fullScreenContainer, spacing, portalContainer } = useChatState();
    const popoverActionRef = useRef(null);
    const updatePosition = useCallback(()=>{
        if (popoverActionRef.current) popoverActionRef.current.updatePosition();
    }, []);
    const schedulePositionUpdate = useScheduledCallback(updatePosition);
    const handleTransitionEnter = useCallback(()=>{
        schedulePositionUpdate();
    }, [
        schedulePositionUpdate
    ]);
    const handleTransitionEntered = useCallback(()=>{
        schedulePositionUpdate();
    }, [
        schedulePositionUpdate
    ]);
    const { width } = useChatWidth();
    const handleScroll = useCallback(()=>{
        if (!scrollContainer || !chatService) return;
        const { scrollTop, scrollHeight, clientHeight } = scrollContainer;
        const scrollBottom = scrollHeight - scrollTop - clientHeight;
        if (scrollBottom < LOAD_MORE_THRESHOLD_IN_PX && !isLoadingMoreRef.current && shouldShowLoadingMoreRef.current && chatService.getConfig()?.paginatedHistory) {
            chatService._eventBus.publish(AutopilotChatEvent.HistoryLoadMore, {
                searchText: searchQueryRef.current
            });
            internalService.publish(AutopilotChatInternalEvent.SetIsLoadingMoreHistory, true);
        }
    }, [
        scrollContainer,
        chatService,
        internalService
    ]);
    const debouncedSearch = useMemo(()=>debounce((newSearchQuery)=>{
            if (chatService?.getConfig()?.paginatedHistory) {
                chatService._eventBus.publish(AutopilotChatEvent.HistorySearch, {
                    searchText: newSearchQuery
                });
                internalService.publish(AutopilotChatInternalEvent.SetIsLoadingMoreHistory, false);
            }
        }, DEBOUNCE_DELAY_IN_MS), [
        chatService,
        internalService
    ]);
    useEffect(()=>{
        if (!chatService || !internalService) return;
        const unsubscribeSetHistory = chatService.on(AutopilotChatEvent.SetHistory, (newHistory)=>{
            setHistory(newHistory);
            setIsSearching(false);
        });
        const unsubscribeSetIsLoadingMore = internalService.on(AutopilotChatInternalEvent.SetIsLoadingMoreHistory, (value)=>{
            isLoadingMoreRef.current = value;
            setIsLoadingMore(value);
        });
        const unsubscribeShouldShowLoading = internalService.on(AutopilotChatInternalEvent.ShouldShowLoadingMoreHistory, (value)=>{
            shouldShowLoadingMoreRef.current = value;
        });
        const unsubscribeAppendOlderHistory = internalService.on(AutopilotChatInternalEvent.AppendOlderHistory, ()=>{
            if (scrollContainer) {
                appendingRef.current = true;
                scrollTopBeforeAppendRef.current = scrollContainer.scrollTop;
            }
        });
        return ()=>{
            unsubscribeSetHistory();
            unsubscribeSetIsLoadingMore();
            unsubscribeShouldShowLoading();
            unsubscribeAppendOlderHistory();
        };
    }, [
        chatService,
        internalService,
        scrollContainer
    ]);
    useEffect(()=>{
        if (!scrollContainer || !historyOpen || !chatService) return;
        scrollContainer.addEventListener('scroll', handleScroll, {
            passive: true
        });
        return ()=>{
            scrollContainer.removeEventListener('scroll', handleScroll);
        };
    }, [
        scrollContainer,
        handleScroll,
        historyOpen,
        chatService
    ]);
    useEffect(()=>{
        if (appendingRef.current && scrollContainer) {
            scrollContainer.scrollTop = scrollTopBeforeAppendRef.current;
            appendingRef.current = false;
        }
    }, [
        history,
        scrollContainer
    ]);
    useEffect(()=>{
        searchQueryRef.current = searchQuery;
    }, [
        searchQuery
    ]);
    const groupedHistory = useMemo(()=>{
        const filteredHistory = chatService?.getConfig()?.paginatedHistory ? history : history.filter((item)=>item.name.toLowerCase().includes(searchQuery.toLowerCase()));
        const grouped = filteredHistory.reduce((acc, item)=>{
            const date = new Date(item.timestamp);
            const currentDate = new Date();
            const daysAgo = differenceInDays(currentDate, date);
            let groupTitle = '';
            if (isToday(date)) groupTitle = _({
                id: 'autopilot-chat.history.group.today'
            });
            else if (isYesterday(date)) groupTitle = _({
                id: 'autopilot-chat.history.group.yesterday'
            });
            else if (daysAgo <= 7) groupTitle = _({
                id: 'autopilot-chat.history.group.last-week'
            });
            else if (daysAgo <= 30) groupTitle = _({
                id: 'autopilot-chat.history.group.last-30-days'
            });
            else {
                const monthsAgo = differenceInMonths(currentDate, date);
                const count = monthsAgo;
                groupTitle = _({
                    id: 'autopilot-chat.history.group.months-ago',
                    values: {
                        count: count
                    }
                });
            }
            const existingGroup = acc.find((group)=>group.title === groupTitle);
            if (existingGroup) existingGroup.items.push(item);
            else acc.push({
                title: groupTitle,
                items: [
                    item
                ]
            });
            return acc;
        }, []);
        grouped.sort((a, b)=>{
            const getDate = (group)=>{
                if (0 === group.items.length) return new Date();
                return new Date(group.items[0].timestamp);
            };
            return getDate(b).getTime() - getDate(a).getTime();
        });
        grouped.forEach((group)=>{
            group.items.sort((a, b)=>new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime());
        });
        return grouped;
    }, [
        history,
        searchQuery,
        chatService,
        _
    ]);
    const handleSearchTextChange = useCallback((searchText)=>{
        const newSearchText = searchText || '';
        setSearchQuery(newSearchText);
        if (chatService?.getConfig()?.paginatedHistory) {
            setIsSearching(true);
            debouncedSearch(newSearchText);
        }
    }, [
        chatService,
        debouncedSearch
    ]);
    const hasHistoryData = history.length > 0 || searchQuery || isSearching;
    const hasNoSearchResults = 0 === groupedHistory.length && searchQuery;
    const showSkeletonLoader = isSearching && chatService?.getConfig()?.paginatedHistory;
    const showLoadMoreSpinner = isLoadingMore && chatService?.getConfig()?.paginatedHistory;
    const renderEmptyState = (message)=>/*#__PURE__*/ jsx(EmptyStateContainer, {
            children: /*#__PURE__*/ jsx(ApTypography, {
                color: 'var(--color-foreground)',
                variant: spacing.primaryFontToken,
                children: message
            })
        });
    const renderHistoryGroups = ()=>/*#__PURE__*/ jsxs(Fragment, {
            children: [
                groupedHistory.map((group)=>/*#__PURE__*/ jsx(AutopilotChatHistoryGroup, {
                        group: group,
                        isHistoryOpen: historyOpen
                    }, group.title)),
                showLoadMoreSpinner && /*#__PURE__*/ jsx("div", {
                    style: {
                        display: 'flex',
                        justifyContent: 'center',
                        margin: spacing.compactMode ? apollo_core.Spacing.SpacingXs : apollo_core.Spacing.SpacingBase
                    },
                    children: /*#__PURE__*/ jsx(CircularProgress, {
                        size: 20
                    })
                })
            ]
        });
    const renderHistoryContent = ()=>{
        if (showSkeletonLoader) return /*#__PURE__*/ jsx(HistorySkeletonLoader, {});
        if (hasNoSearchResults) return renderEmptyState(_({
            id: 'autopilot-chat.history.no-results'
        }));
        return renderHistoryGroups();
    };
    return /*#__PURE__*/ jsx(Popover, {
        open: open && historyOpen,
        anchorEl: historyAnchorElement,
        onClose: ()=>{
            chatService?.toggleHistory();
        },
        container: portalContainer,
        anchorOrigin: {
            vertical: 'bottom',
            horizontal: 'left'
        },
        transformOrigin: {
            vertical: 'top',
            horizontal: 'left'
        },
        slotProps: {
            paper: {
                ref: popperContainerRef,
                elevation: 6,
                sx: {
                    borderRadius: apollo_core.Spacing.SpacingMicro,
                    margin: `0 ${apollo_core.Spacing.SpacingXs + apollo_core.Spacing.SpacingBase} 0 ${apollo_core.Spacing.SpacingXs}`
                }
            }
        },
        action: popoverActionRef,
        TransitionProps: {
            onEnter: handleTransitionEnter,
            onEntered: handleTransitionEntered
        },
        children: /*#__PURE__*/ jsx(react_focus_lock, {
            disabled: !open || !historyOpen,
            returnFocus: false,
            children: /*#__PURE__*/ jsx(ChatHistoryContainer, {
                isFullScreen: isFullScreen,
                width: Math.min(width - 2 * parseInt(apollo_core.Spacing.SpacingBase, 10), popperContainerRef.current?.clientWidth ?? (portalContainer ? width - 2 * parseInt(apollo_core.Spacing.SpacingBase, 10) : 1 / 0)),
                fullScreenContainer: fullScreenContainer,
                children: hasHistoryData ? /*#__PURE__*/ jsxs(Fragment, {
                    children: [
                        /*#__PURE__*/ jsx(ApTextField, {
                            disabled: !historyOpen,
                            className: "chat-history-search",
                            size: "small",
                            startAdornment: /*#__PURE__*/ jsx(Search, {}),
                            placeholder: _({
                                id: 'autopilot-chat.history.search-placeholder'
                            }),
                            value: searchQuery,
                            onChange: handleSearchTextChange
                        }),
                        /*#__PURE__*/ jsx("div", {
                            className: "chat-history-content",
                            ref: setScrollContainer,
                            children: renderHistoryContent()
                        })
                    ]
                }) : renderEmptyState(_({
                    id: 'autopilot-chat.history.empty'
                }))
            })
        })
    });
};
const AutopilotChatHistory = /*#__PURE__*/ react.memo(AutopilotChatHistoryComponent);
export { AutopilotChatHistory };
