import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
import { useEffect, memo } from 'react';
import { areEqual } from 'react-window';
import { useTableContext } from './Tablev2.component';
import { HeadRow, NoResult, SortCaret, TableBody, TableHeader, TableRowMultiSelectable, } from './Tablestyle';
import { useTableScrollbar, VirtualizedRows } from './TableCommon';
import useSyncedScroll from './useSyncedScroll';
import { Box } from '../box/Box';
import { Loader } from '../loader/Loader.component';
import { spacing } from '../../spacing';
const translations = {
    en: {
        noResult: 'No results found',
    },
    fr: {
        noResult: `Aucun résultat`,
    },
};
/**
 * FIXME Need to spend time to change the type to something like this
 */
// type MultiSelectableContentProps<ENTRY extends Record<string, any>> = {
//   onMultiSelectionChanged: (rows: Row<ENTRY>[]) => void;
//   rowHeight?: TableHeightKeyType;
//   separationLineVariant?: TableVariantType;
//   backgroundVariant?: TableVariantType;
//   customItemKey?: (index: Number, data: ENTRY) => string;
// } & ({
//   locale: TableLocalType;
// } | {
//   children: (rows: JSX.Element) => JSX.Element;
//   });
export const MultiSelectableContent = ({ onMultiSelectionChanged, onSingleRowSelected, onToggleAll, rowHeight = 'h40', separationLineVariant = 'backgroundLevel3', backgroundVariant = 'backgroundLevel1', locale = 'en', customItemKey, isLoadingMoreItems, children, }) => {
    const { headerGroups, prepareRow, rows, setRowHeight, setHiddenColumns, selectedRowIds, onBottom, onBottomOffset, isAllRowsSelected, toggleAllRowsSelected, } = useTableContext();
    useEffect(() => {
        setRowHeight(rowHeight);
    }, [rowHeight, setRowHeight]);
    useEffect(() => {
        setHiddenColumns((oldHiddenColumns) => {
            return oldHiddenColumns.filter((column) => column !== 'selection');
        });
    }, [setHiddenColumns]);
    const handleMultipleSelectedRows = (selectedRowIds, rows, currentRow, currentRowIndex) => {
        const keys = Object.keys(selectedRowIds);
        if (onMultiSelectionChanged) {
            if (currentRow.isSelected) {
                // we remove the item from the list
                onMultiSelectionChanged(rows.filter((row) => keys.includes(row.id) && rows[currentRowIndex].id !== row.id));
            }
            else {
                // we add the new item from the list
                onMultiSelectionChanged([
                    ...rows.filter((row) => keys.includes(row.id)),
                    rows[currentRowIndex],
                ]);
            }
        }
        currentRow.toggleRowSelected(!currentRow.isSelected);
    };
    const { hasScrollbar, setHasScrollbar, scrollBarWidth, handleScrollbarWidth, } = useTableScrollbar();
    const itemKey = (index, data) => {
        if (typeof customItemKey === 'function') {
            return customItemKey(index, data);
        }
        return index;
    };
    const { bodyRef, headerRef } = useSyncedScroll();
    const RenderRow = memo(({ index, style }) => {
        const row = rows[index];
        prepareRow(row);
        const rowProps = {
            ...row.getRowProps({
                /**
                 * Note:We need to pass the style property to the row component.
                 * Otherwise when we scroll down, the next rows are flashing
                 * because they are re-rendered in loop.
                 */
                style: { ...style },
            }),
            onClick: onSingleRowSelected
                ? () => {
                    onSingleRowSelected(row);
                    toggleAllRowsSelected(false);
                    row.toggleRowSelected(true);
                }
                : () => handleMultipleSelectedRows(selectedRowIds, rows, row, index),
        };
        return (_jsx(TableRowMultiSelectable, { ...rowProps, isSelected: row.isSelected, separationLineVariant: separationLineVariant, backgroundVariant: backgroundVariant, className: "tr", children: row.cells.map((cell) => {
                const cellProps = cell.getCellProps({
                    style: {
                        ...cell.column.cellStyle,
                        // Vertically center the text in cells.
                        display: 'flex',
                        flexDirection: 'column',
                        justifyContent: 'center',
                    },
                    role: 'gridcell',
                });
                if (cell.column.id === 'selection') {
                    return (_jsx("div", { ...cellProps, onClick: onSingleRowSelected
                            ? (event) => {
                                event.stopPropagation();
                                handleMultipleSelectedRows(selectedRowIds, rows, row, index);
                            }
                            : undefined, children: cell.render('Cell') }));
                }
                return (_jsx("div", { ...cellProps, className: "td", children: cell.render('Cell') }));
            }) }));
    }, areEqual);
    return (_jsxs(_Fragment, { children: [_jsx("div", { children: headerGroups.map((headerGroup) => (_jsx(HeadRow, { ...headerGroup.getHeaderGroupProps(), hasScrollBar: hasScrollbar, scrollBarWidth: scrollBarWidth, rowHeight: rowHeight, ref: headerRef, children: headerGroup.headers.map((column) => {
                        const headerStyleProps = column.getHeaderProps(Object.assign(column.getSortByToggleProps(), {
                            style: { ...column === null || column === void 0 ? void 0 : column.cellStyle, position: 'relative' },
                        }));
                        return (_jsx(TableHeader, { ...headerStyleProps, role: "columnheader", children: _jsxs("div", { children: [column.id === 'selection' ? (_jsx("div", { onClick: (event) => {
                                            const eventTarget = event.target;
                                            if (onToggleAll) {
                                                onToggleAll(eventTarget.checked);
                                            }
                                            if (onMultiSelectionChanged) {
                                                if (isAllRowsSelected) {
                                                    onMultiSelectionChanged([]);
                                                }
                                                else {
                                                    onMultiSelectionChanged(rows);
                                                }
                                            }
                                        }, children: column.render('Header') })) : (column.render('Header')), _jsx(SortCaret, { column: column })] }) }));
                    }) }))) }), _jsx(TableBody, { role: "rowgroup", className: "tbody", ref: handleScrollbarWidth, children: typeof children === 'function' ? (children(_jsx(VirtualizedRows, { rows: rows, listRef: bodyRef, itemKey: itemKey, rowHeight: rowHeight, setHasScrollbar: setHasScrollbar, onBottom: onBottom, onBottomOffset: onBottomOffset, RenderRow: RenderRow }))) : rows.length ? (_jsx(VirtualizedRows, { rows: rows, listRef: bodyRef, itemKey: itemKey, rowHeight: rowHeight, setHasScrollbar: setHasScrollbar, onBottom: onBottom, onBottomOffset: onBottomOffset, RenderRow: RenderRow })) : (_jsx(NoResult, { children: translations[locale].noResult })) }), isLoadingMoreItems && (_jsx(Box, { display: "flex", justifyContent: "center", marginTop: spacing.r16, marginBottom: spacing.r16, children: _jsx(Loader, { size: "large" }) }))] }));
};
