"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.HistoryList = HistoryList;
const tslib_1 = require("tslib");
const jsx_runtime_1 = require("react/jsx-runtime");
const react_1 = tslib_1.__importStar(require("react"));
const uikit_1 = require("@gravity-ui/uikit");
const chatUtils_1 = require("../../../utils/chatUtils.js");
const cn_1 = require("../../../utils/cn.js");
const IntersectionContainer_1 = require("../../atoms/IntersectionContainer/index.js");
const Loader_1 = require("../../atoms/Loader/index.js");
const ChatItem_1 = require("./ChatItem.js");
const DateHeaderItem_1 = require("./DateHeaderItem.js");
const i18n_1 = require("./i18n/index.js");
require("./History.css");
const b = (0, cn_1.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).
 */
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 = chatUtils_1.defaultChatFilter, loading = false, onChatClick, size = 'm', } = props;
    const [filteredItemCount, setFilteredItemCount] = (0, react_1.useState)(null);
    const [loadedChats, setLoadedChats] = (0, react_1.useState)([]);
    const [lazyHasMore, setLazyHasMore] = (0, react_1.useState)(hasMore);
    const [deletedChats, setDeletedChats] = (0, react_1.useState)(new Set());
    const loadingMoreRef = (0, react_1.useRef)(false);
    const displayChats = (0, react_1.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 = (0, react_1.useRef)(displayChats.length);
    displayChatsLengthRef.current = displayChats.length;
    (0, react_1.useEffect)(() => {
        if (loadMode === 'lazy') {
            setLazyHasMore(hasMore);
        }
    }, [loadMode, hasMore]);
    (0, react_1.useEffect)(() => {
        if (loadMode === 'lazy') {
            setLoadedChats([]);
        }
    }, [chats, loadMode]);
    const groupedChats = (0, react_1.useMemo)(() => {
        if (groupBy === 'none') {
            return new Map([['all', displayChats]]);
        }
        return (0, chatUtils_1.groupChatsByDate)(displayChats);
    }, [displayChats, groupBy]);
    const listItems = (0, react_1.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 = (0, react_1.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 = (0, react_1.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 = (0, react_1.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 (0, jsx_runtime_1.jsx)(DateHeaderItem_1.DateHeaderItem, { date: item.date }, `date-${item.date}`);
        }
        return ((0, jsx_runtime_1.jsx)(ChatItem_1.ChatItem, { chat: item, showActions: showActions, onDeleteClick: onDeleteChat ? handleDeleteClick : undefined, isActive: isActive }, item.id));
    };
    const emptyState = emptyPlaceholder || (0, jsx_runtime_1.jsx)("div", { className: b('empty'), children: (0, i18n_1.i18n)('empty-state') });
    const emptyFilteredState = emptyFilteredPlaceholder || ((0, jsx_runtime_1.jsx)("div", { className: b('empty'), children: (0, i18n_1.i18n)('empty-filtered-state') }));
    const finalEmptyPlaceholder = filteredItemCount === null || filteredItemCount === listItems.length
        ? emptyState
        : emptyFilteredState;
    return ((0, jsx_runtime_1.jsxs)("div", { className: b('container', className), "data-qa": qa, style: style, children: [(0, jsx_runtime_1.jsx)("div", { className: b('list-wrapper'), children: loading ? ((0, jsx_runtime_1.jsx)("div", { className: b('loader-wrapper'), children: (0, jsx_runtime_1.jsx)(Loader_1.Loader, { view: "loading" }) })) : ((0, jsx_runtime_1.jsxs)(react_1.default.Fragment, { children: [(0, jsx_runtime_1.jsx)(uikit_1.List, { size: size, items: listItems, renderItem: renderItem, virtualized: false, filterable: searchable, filterItem: wrappedFilterFunction, filterPlaceholder: searchPlaceholder !== null && searchPlaceholder !== void 0 ? searchPlaceholder : (0, i18n_1.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 && ((0, jsx_runtime_1.jsx)(IntersectionContainer_1.IntersectionContainer, { onIntersect: handleLoadMore, className: b('lazy-loader'), children: (0, jsx_runtime_1.jsx)(Loader_1.Loader, { view: "loading" }) }, displayChats.length))] })) }), loadMode === 'full' && hasMore && onLoadMore && ((0, jsx_runtime_1.jsx)(uikit_1.Button, { view: "flat-action", size: "m", width: "max", onClick: handleLoadMore, children: (0, i18n_1.i18n)('action-load-more') }))] }));
}
//# sourceMappingURL=HistoryList.js.map
