import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { useCallback } from "react";
import { Input } from "../../data-entry/input/index.js";
import { useGlobalTableKeyEvents } from "../hooks/useGlobalTableKeyEvents.js";
import { isCellEqual } from "../utils.js";
import { DefaultTableCell } from "./cells/default-cell.js";
import { InformationCell } from "./cells/information-cell.js";
import { RowNumberCell } from "./cells/row-number-cell.js";
import { TableRow } from "./rows/table-row.js";
import { useInternalTableState } from "./table-provider/table-provider.js";
const TableBody = ({ data, columns, }) => {
    const { config, state: { dispatch, selectedRowIndexes, selectedCellIndex, isCellEditMode }, api, } = useInternalTableState();
    // add global key events to the table
    useGlobalTableKeyEvents();
    const { allowRowSelection } = config;
    /**
     * Create a handler for the click event on the table numbering cell
     * This handler is used to select a row when the ctrl key is pressed
     * or select single rows when the index is clicked
     */
    const createSelectRowOnClickHandler = useCallback((index) => (e) => {
        if (!allowRowSelection)
            return;
        if (e.ctrlKey) {
            e.stopPropagation();
            api.selection.toggleRow(index);
        }
        else if (e.shiftKey) {
            return; // just let the row handle it
        }
        else {
            api.selection.selectRow(index);
        }
    }, [allowRowSelection]);
    /**
     * Create a handler for the click event on the table row
     * This handler is used to select a row when the ctrl key is pressed
     * in any other place other than the index cell or select a range of rows
     * when the shift key is pressed
     */
    const createAddSelectedRowHandler = useCallback((index) => (e) => {
        if (!allowRowSelection)
            return;
        if (e.ctrlKey) {
            api.selection.toggleRow(index);
        }
        else if (e.shiftKey) {
            // Prevent text selection when shift key is pressed
            document.getSelection()?.removeAllRanges();
            api.selection.selectFromLastActiveRow(index);
        }
    }, [allowRowSelection]);
    /**
     * Prevent text selection when shift key is pressed so that we
     * can select a range of rows while keeping a good user experience
     */
    const handleMouseDown = useCallback((event) => {
        if (event.shiftKey) {
            document.getSelection()?.removeAllRanges();
        }
    }, []);
    const createCellClickHandler = useCallback((index, column, columnDef) => (e) => {
        // if the cell is being edited, ignore clicking on it
        if (isCellEditMode &&
            selectedCellIndex?.row === index &&
            selectedCellIndex.column === column) {
            return;
        }
        // if shift or ctrl is pressed, the user is probably trying to select rows
        if (!e.ctrlKey && !e.shiftKey) {
            if (e.detail === 2 && columnDef.editable) {
                dispatch?.({
                    type: "ENTER_CELL_EDIT_MODE",
                    payload: { row: index, column },
                });
            }
            else {
                api.selection.selectCell(index, column);
            }
        }
    }, [dispatch, isCellEditMode]);
    return (_jsx("tbody", { className: "text-sm leading-5 text-gray-900", children: data.map((rowItem, index) => (_jsxs(TableRow
        // TODO: replace key with unique key (maybe generated with object-hash package)
        , { index: index, onClick: createAddSelectedRowHandler(index), onMouseDown: handleMouseDown, children: [_jsx(RowNumberCell, { index: index + 1, handleSelectRowOnClick: createSelectRowOnClickHandler(index), selected: selectedRowIndexes.includes(index) ||
                        selectedCellIndex?.row === index }), columns.map((column, columnIndex) => {
                    const cellContext = {
                        row: rowItem,
                        column,
                        rowIndex: index,
                        columnIndex,
                        tableConfig: config,
                    };
                    // get and format the cell value
                    const cellValue = column.valueFormatter?.(column.valueGetter?.(rowItem, cellContext), cellContext);
                    // render the cell
                    const cell = column.renderCell?.(cellValue, cellContext);
                    const currentCellIndex = {
                        row: index,
                        column: columnIndex,
                    };
                    const isCellSelected = isCellEqual(selectedCellIndex, currentCellIndex);
                    const isThisCellEditMode = isCellEditMode && isCellSelected;
                    return (_jsx(DefaultTableCell, { onClick: createCellClickHandler(index, columnIndex, column), isSelected: isCellSelected, isEditable: column.editable ?? false, children: isThisCellEditMode ? (_jsx(Input, { className: "max-w-full", autoFocus: true, defaultValue: column.valueGetter?.(rowItem, cellContext), 
                            // eslint-disable-next-line react/jsx-no-bind
                            onKeyDown: (e) => {
                                if (e.key === "Enter") {
                                    const newValue = e.target.value;
                                    column.onSave?.(newValue, cellContext);
                                }
                            } })) : (cell) }, column.field));
                }), _jsx(InformationCell, {})] }, index))) }));
};
export { TableBody };
//# sourceMappingURL=body.js.map