import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
// (C) 2025-2026 GoodData Corporation
import { useCallback, useContext, useMemo } from "react";
import { IntlContext } from "react-intl";
import { IntlWrapper } from "@gooddata/sdk-ui";
import { b } from "../asyncTableBem.js";
import { CHECKBOX_COLUMN_WIDTH, ROW_HEIGHT_LARGE, ROW_HEIGHT_NORMAL, SCROLLBAR_WIDTH } from "./constants.js";
import { UiAsyncTableBody } from "./UiAsyncTableBody.js";
import { UiAsyncTableEmptyState } from "./UiAsyncTableEmptyState.js";
import { UiAsyncTableHeader } from "./UiAsyncTableHeader.js";
import { UiAsyncTableRow } from "./UiAsyncTableRow.js";
import { UiAsyncTableToolbar } from "./UiAsyncTableToolbar.js";
import { getColumnWidth, getItemKey } from "./utils.js";
function AsyncTableCore(props) {
    const { width, itemHeight, isLargeRow, renderHeader, renderItem, renderEmptyState, shouldLoadNextPage } = useAsyncTable(props);
    const { filters, bulkActions, selectedItemIds, totalItemsCount, items, isLoading, hasNextPage, maxHeight = 400, skeletonItemsCount = 0, columns, scrollToIndex, variant = "regular", isMobileView, isFiltersTooLarge, loadNextPage, setSelectedItemIds, onSearch, searchPlaceholder, renderToolbarCustomElement, accessibilityConfig, allowSearch, } = props;
    return (_jsxs("div", { className: b(), style: { width }, children: [
            _jsx(UiAsyncTableToolbar, { allowSearch: allowSearch, filters: filters, isFiltersTooLarge: isFiltersTooLarge, bulkActions: bulkActions, selectedItemIds: selectedItemIds, setSelectedItemIds: setSelectedItemIds ?? (() => { }), totalItemsCount: totalItemsCount ?? 0, items: items, variant: variant, isMobileView: isMobileView, width: width, onSearch: onSearch, searchPlaceholder: searchPlaceholder, renderToolbarCustomElement: renderToolbarCustomElement, accessibilityConfig: accessibilityConfig }), _jsxs("div", { role: "grid", "aria-label": accessibilityConfig?.gridAriaLabel, "aria-rowcount": totalItemsCount, "aria-colcount": bulkActions ? columns.length + 1 : columns.length, children: [renderHeader(), _jsx(UiAsyncTableBody, { items: items, maxHeight: maxHeight, itemHeight: itemHeight, skeletonItemsCount: skeletonItemsCount, hasNextPage: hasNextPage, isLoading: isLoading, onItemClick: props.onItemClick, loadNextPage: loadNextPage, columns: columns, bulkActions: bulkActions, scrollToIndex: scrollToIndex, shouldLoadNextPage: shouldLoadNextPage, renderItem: renderItem, isLargeRow: isLargeRow })
                ] }), items.length === 0 && !isLoading && renderEmptyState()] }));
}
const useAsyncTable = ({ columns, renderItem: renderItemProp, renderHeader: renderHeaderProp, renderEmptyState: renderEmptyStateProp, bulkActions, onSort, width: widthProp, sortBy, sortDirection, selectedItemIds, setSelectedItemIds, variant, onItemClick, accessibilityConfig, }) => {
    const isSmall = variant === "small";
    const handleColumnClick = useCallback((key) => {
        if (key !== undefined) {
            onSort?.(key);
        }
    }, [onSort]);
    const onItemSelect = useCallback((item) => {
        const key = getItemKey(item);
        const filteredItemIds = selectedItemIds?.filter((id) => id !== key) ?? [];
        setSelectedItemIds?.(filteredItemIds.length === selectedItemIds?.length
            ? [...(selectedItemIds ?? []), key]
            : filteredItemIds);
    }, [selectedItemIds, setSelectedItemIds]);
    const isItemSelected = useCallback((item) => {
        return selectedItemIds?.includes(getItemKey(item));
    }, [selectedItemIds]);
    const isLargeRow = useMemo(() => columns.some((column) => column.getMultiLineTextContent), [columns]);
    const itemHeight = useMemo(() => {
        return isLargeRow ? ROW_HEIGHT_LARGE : ROW_HEIGHT_NORMAL;
    }, [isLargeRow]);
    const width = useMemo(() => {
        return (widthProp ??
            columns.reduce((acc, column) => {
                const columnWidth = getColumnWidth(!!column.renderMenu, isLargeRow, column.width) ?? 0;
                return acc + columnWidth;
            }, SCROLLBAR_WIDTH + (bulkActions ? CHECKBOX_COLUMN_WIDTH : 0)));
    }, [columns, bulkActions, widthProp, isLargeRow]);
    const renderItem = useCallback((item, itemIndex, focusedItemRef, isFocused, focusedColumnIndex) => {
        return renderItemProp ? (renderItemProp(item)) : (_jsx(UiAsyncTableRow, { item: item, itemIndex: itemIndex, columns: columns, onSelect: onItemSelect, isSelected: isItemSelected(item), hasCheckbox: !!bulkActions, isLarge: isLargeRow, onClick: onItemClick, isFocused: isFocused, focusedColumnIndex: focusedColumnIndex, focusedElementRef: focusedItemRef, accessibilityConfig: accessibilityConfig }));
    }, [
        columns,
        renderItemProp,
        onItemSelect,
        isItemSelected,
        onItemClick,
        bulkActions,
        isLargeRow,
        accessibilityConfig,
    ]);
    const renderHeader = useCallback(() => {
        return renderHeaderProp ? (renderHeaderProp()) : (_jsx(UiAsyncTableHeader, { columns: columns, handleColumnClick: handleColumnClick, sortBy: sortBy, sortDirection: sortDirection, hasCheckbox: !!bulkActions, width: width, small: isSmall, largeRow: isLargeRow }));
    }, [
        columns,
        renderHeaderProp,
        handleColumnClick,
        bulkActions,
        width,
        sortBy,
        sortDirection,
        isLargeRow,
        isSmall,
    ]);
    const renderEmptyState = useCallback(() => {
        return renderEmptyStateProp ? renderEmptyStateProp() : _jsx(UiAsyncTableEmptyState, {});
    }, [renderEmptyStateProp]);
    const shouldLoadNextPage = useCallback((lastItemIndex, itemsCount) => {
        return lastItemIndex >= itemsCount - 1;
    }, []);
    return {
        width,
        itemHeight,
        isLargeRow,
        renderHeader,
        renderItem,
        renderEmptyState,
        shouldLoadNextPage,
        onItemSelect,
        isItemSelected,
    };
};
/**
 * @internal
 */
export function UiAsyncTable(props) {
    const intlContext = useContext(IntlContext);
    if (!intlContext) {
        return (_jsx(IntlWrapper, { locale: props.locale, children: _jsx(AsyncTableCore, { ...props }) }));
    }
    return _jsx(AsyncTableCore, { ...props });
}
