import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { Button, List } from '@gravity-ui/uikit';
import { defaultChatFilter, groupChatsByDate } from "../../../utils/chatUtils.js";
import { block } from "../../../utils/cn.js";
import { IntersectionContainer } from "../../atoms/IntersectionContainer/index.js";
import { Loader } from "../../atoms/Loader/index.js";
import { ChatItem } from "./ChatItem.js";
import { DateHeaderItem } from "./DateHeaderItem.js";
import { i18n } from "./i18n/index.js";
import "./History.css";
const b = block('history');
/**
 * HistoryList component - displays a list of chats with search, grouping, and actions
 *
 * @param props - {@link HistoryListProps}
 * @returns Rendered history list (search, grouping, lazy/full load, chat rows).
 */
export function HistoryList(props) {
    const { chats, selectedChat, onSelectChat, onDeleteChat, onLoadMore, hasMore = false, loadMode = 'full', searchable = true, groupBy = 'date', showActions = true, emptyPlaceholder, emptyFilteredPlaceholder, searchPlaceholder, className, qa, style, filterFunction = defaultChatFilter, loading = false, onChatClick, size = 'm', } = props;
    const [filteredItemCount, setFilteredItemCount] = useState(null);
    const [loadedChats, setLoadedChats] = useState([]);
    const [lazyHasMore, setLazyHasMore] = useState(hasMore);
    const [deletedChats, setDeletedChats] = useState(new Set());
    const loadingMoreRef = useRef(false);
    const displayChats = useMemo(() => {
        const totalChats = loadMode === 'lazy' ? [...chats, ...loadedChats] : chats;
        const filteredChats = totalChats.filter((chat) => !deletedChats.has(chat.id));
        return filteredChats;
    }, [loadMode, chats, loadedChats, deletedChats]);
    const displayChatsLengthRef = useRef(displayChats.length);
    displayChatsLengthRef.current = displayChats.length;
    useEffect(() => {
        if (loadMode === 'lazy') {
            setLazyHasMore(hasMore);
        }
    }, [loadMode, hasMore]);
    useEffect(() => {
        if (loadMode === 'lazy') {
            setLoadedChats([]);
        }
    }, [chats, loadMode]);
    const groupedChats = useMemo(() => {
        if (groupBy === 'none') {
            return new Map([['all', displayChats]]);
        }
        return groupChatsByDate(displayChats);
    }, [displayChats, groupBy]);
    const listItems = useMemo(() => {
        const items = [];
        const sortedGroups = Array.from(groupedChats.entries()).sort(([dateA], [dateB]) => {
            if (dateA === 'all')
                return 0;
            return new Date(dateB).getTime() - new Date(dateA).getTime();
        });
        sortedGroups.forEach(([dateKey, groupChats]) => {
            if (groupChats.length === 0) {
                return;
            }
            if (groupBy === 'date' && dateKey !== 'all') {
                items.push({
                    type: 'date-header',
                    disabled: true,
                    date: dateKey,
                });
            }
            groupChats.forEach((chat) => {
                items.push(Object.assign({ type: 'chat' }, chat));
            });
        });
        return items;
    }, [groupedChats, groupBy]);
    const selectedItemIndex = useMemo(() => {
        return listItems.findIndex((item) => item.type === 'chat' && item.id === (selectedChat === null || selectedChat === void 0 ? void 0 : selectedChat.id));
    }, [listItems, selectedChat]);
    const effectiveHasMore = loadMode === 'lazy' ? lazyHasMore : hasMore;
    /**
     * Unified load more handler.
     * full: fires onLoadMore(), parent manages data and hasMore
     * lazy: calls onLoadMore(offset), accumulates returned chats internally
     */
    const handleLoadMore = useCallback(async () => {
        if (!onLoadMore || loadingMoreRef.current) {
            return;
        }
        if (loadMode === 'full') {
            onLoadMore();
            return;
        }
        loadingMoreRef.current = true;
        try {
            const offset = displayChatsLengthRef.current;
            const result = await onLoadMore(offset);
            const newChats = Array.isArray(result) ? result : result.chats;
            const resultHasMore = Array.isArray(result) ? newChats.length > 0 : result.hasMore;
            setLoadedChats((prev) => [...prev, ...newChats]);
            setLazyHasMore(resultHasMore !== null && resultHasMore !== void 0 ? resultHasMore : newChats.length > 0);
        }
        catch (error) {
            // eslint-disable-next-line no-console
            console.error('HistoryList: failed to load more chats', error);
        }
        finally {
            loadingMoreRef.current = false;
        }
    }, [onLoadMore, loadMode]);
    const handleChatClick = (chat, _, fromKeyboard, event) => {
        var _a;
        if (fromKeyboard && ((_a = event === null || event === void 0 ? void 0 : event.target) === null || _a === void 0 ? void 0 : _a.type) === 'button') {
            return;
        }
        onSelectChat === null || onSelectChat === void 0 ? void 0 : onSelectChat(chat);
        onChatClick === null || onChatClick === void 0 ? void 0 : onChatClick(chat);
    };
    const handleDeleteClick = async (e, chat) => {
        e.stopPropagation();
        try {
            await (onDeleteChat === null || onDeleteChat === void 0 ? void 0 : onDeleteChat(chat));
            setDeletedChats((prevDeletedChats) => new Set([...prevDeletedChats, chat.id]));
        }
        catch (error) {
            // eslint-disable-next-line no-console
            console.error('HistoryList: failed to delete chat', error);
        }
    };
    const wrappedFilterFunction = useMemo(() => {
        return (filter) => {
            const userFilter = filterFunction(filter);
            return (item) => {
                if (filter && item.type === 'date-header') {
                    return false;
                }
                return userFilter(item);
            };
        };
    }, [filterFunction]);
    const renderItem = (item, isActive) => {
        if (item.type === 'date-header') {
            return _jsx(DateHeaderItem, { date: item.date }, `date-${item.date}`);
        }
        return (_jsx(ChatItem, { chat: item, showActions: showActions, onDeleteClick: onDeleteChat ? handleDeleteClick : undefined, isActive: isActive }, item.id));
    };
    const emptyState = emptyPlaceholder || _jsx("div", { className: b('empty'), children: i18n('empty-state') });
    const emptyFilteredState = emptyFilteredPlaceholder || (_jsx("div", { className: b('empty'), children: i18n('empty-filtered-state') }));
    const finalEmptyPlaceholder = filteredItemCount === null || filteredItemCount === listItems.length
        ? emptyState
        : emptyFilteredState;
    return (_jsxs("div", { className: b('container', className), "data-qa": qa, style: style, children: [_jsx("div", { className: b('list-wrapper'), children: loading ? (_jsx("div", { className: b('loader-wrapper'), children: _jsx(Loader, { view: "loading" }) })) : (_jsxs(React.Fragment, { children: [_jsx(List, { size: size, items: listItems, renderItem: renderItem, virtualized: false, filterable: searchable, filterItem: wrappedFilterFunction, filterPlaceholder: searchPlaceholder !== null && searchPlaceholder !== void 0 ? searchPlaceholder : i18n('search-placeholder'), filterClassName: b('filter'), emptyPlaceholder: finalEmptyPlaceholder, selectedItemIndex: selectedItemIndex, itemsClassName: b('list'), itemClassName: b('list-item'), onFilterEnd: (data) => setFilteredItemCount(data.items.length), onItemClick: handleChatClick }), loadMode === 'lazy' && effectiveHasMore && onLoadMore && (_jsx(IntersectionContainer, { onIntersect: handleLoadMore, className: b('lazy-loader'), children: _jsx(Loader, { view: "loading" }) }, displayChats.length))] })) }), loadMode === 'full' && hasMore && onLoadMore && (_jsx(Button, { view: "flat-action", size: "m", width: "max", onClick: handleLoadMore, children: i18n('action-load-more') }))] }));
}
//# sourceMappingURL=HistoryList.js.map
