import React from 'react';
import defaultTo from 'lodash/defaultTo';
import classNames from 'classnames';
import { ScrollSync } from 'react-scroll-sync';
import { classes } from './Table.st.css.js';
import DataTable from './DataTable';
import * as dataTableRowStyle from './DataTable/components/DataTableRow.st.css.js';
import Checkbox from '../Checkbox';
import { TableContext } from './TableContext';
import { BulkSelection } from './BulkSelection';
import { ColumnResize } from './ColumnResize';
import * as dataTableRowVirtualStyle from './DataTable/components/DataTableRowVirtual.st.css.js';
import { TableBulkSelectionCheckbox, TableContent, TableEmptyState, TableSubToolbar, TableTitleBar, TableToolbarContainer, } from './components';
import { RowNumberCell } from './components/RowNumberCell';
import { FloatingScrollBarContextProvider } from './FloatingScrollBar/FloatingScrollBarContext';
const hasUnselectablesSymbol = Symbol('hasUnselectables');
export function createColumns({ tableProps, bulkSelectionContext }) {
    const { dragAndDrop, isDragAndDropDisabled } = tableProps;
    const includeDragHandleColumn = dragAndDrop != null &&
        dragAndDrop.createDragHandleColumn != null &&
        !isDragAndDropDisabled;
    const createCheckboxColumn = ({ toggleSelectionById, isSelected, selectionDisabled, }) => {
        const isRowSelectionDisabled = rowData => selectionDisabled === true ||
            (typeof selectionDisabled === 'function' && selectionDisabled(rowData));
        return {
            key: 'bulk-selection-cell',
            title: tableProps.hideBulkSelectionCheckbox ? ('') : (React.createElement(TableBulkSelectionCheckbox, { dataHook: "table-select", ref: tableProps.bulkSelectionCheckboxRef })),
            dataHook: 'bulk-selection-cell',
            onCellClick: (column, row, rowNum, event) => {
                if (row.unselectable) {
                    return;
                }
                event.stopPropagation();
                if (isRowSelectionDisabled(row)) {
                    return;
                }
                const id = defaultTo(row.id, rowNum);
                toggleSelectionById(id, 'Checkbox');
            },
            render: (row, rowNum) => {
                const id = defaultTo(row.id, rowNum);
                const tooltipContent = row.checkboxTooltipContent;
                const checked = !row.unselectable && isSelected(id);
                const disabled = row.unselectable || isRowSelectionDisabled(row);
                if (tableProps.showRowNumbers) {
                    return (React.createElement(RowNumberCell, { rowNum: rowNum, checked: checked, disabled: disabled, tooltipContent: tooltipContent, dataHook: "row-select" }));
                }
                return row.unselectable ? null : (React.createElement(Checkbox, { disabled: isRowSelectionDisabled(row), dataHook: "row-select", checked: isSelected(id), tooltipProps: { disabled: !tooltipContent }, tooltipContent: tooltipContent }));
            },
            width: '12px',
            style: (_, row) => (row.unselectable ? undefined : { cursor: 'pointer' }),
        };
    };
    const checkboxColumn = tableProps.showSelection
        ? createCheckboxColumn(bulkSelectionContext)
        : null;
    const columns = [
        ...(includeDragHandleColumn
            ? [dragAndDrop.createDragHandleColumn(tableProps)]
            : []),
        ...(checkboxColumn ? [checkboxColumn] : []),
        ...tableProps.columns,
    ];
    // Apply different column width when checkbox column is the last sticky column
    // (looks weird otherwise when stickied with default 12px width).
    if (checkboxColumn &&
        !tableProps.showRowNumbers &&
        columns.indexOf(checkboxColumn) + 1 === tableProps.stickyColumns) {
        checkboxColumn.width = '34px';
    }
    return columns;
}
export function getDataTableProps(tableProps) {
    const { showSelection, onSelectionChanged, onSelectionStarted, dataHook, ...props } = tableProps;
    return {
        ...props,
        rowClass: classNames(tableProps.rowClass, classes.tableRow),
    };
}
/**
 * Table is a composite component that allows adding SelectionColumn, Toolbar (on top of the TitleBar).
 * It is a context provider, and thus the Table.Consumer, Table.TitleBar and Table.Content can be rendered separately.
 */
export class Table extends React.Component {
    constructor() {
        super(...arguments);
        this.state = {
            leftShadowVisible: false,
            rightShadowVisible: false,
        };
        this.tableRef = React.createRef();
        this.scrollElementRef = React.createRef();
        this._handleUpdateScrollShadows = (leftShadowVisible, rightShadowVisible) => {
            if (leftShadowVisible !== this.state.leftShadowVisible) {
                this.setState({ leftShadowVisible });
            }
            if (rightShadowVisible !== this.state.rightShadowVisible) {
                this.setState({ rightShadowVisible });
            }
        };
    }
    shouldComponentUpdate() {
        // Table is not really a PureComponent
        return true;
    }
    setSelectedIds(selectedIds) {
        this.bulkSelection.setSelectedIds(selectedIds);
    }
    renderChildren() {
        const { children, withWrapper, dataHook } = this.props;
        return withWrapper ? React.createElement("div", { "data-hook": dataHook }, children) : children;
    }
    render() {
        const { data, selectedIds, showSelection, deselectRowsByDefault, infiniteScroll, totalSelectableCount, onSelectionChanged, onSelectionStarted, hasMore, horizontalScroll, resizable, resizeProps, selectionDisabled, dragAndDrop, onDragEnd, scrollElement, } = this.props;
        this.scrollElementRef.current =
            typeof HTMLElement !== 'undefined' && scrollElement instanceof HTMLElement
                ? scrollElement
                : scrollElement?.current;
        let hasUnselectables = null;
        let allIds = data.map((rowData, rowIndex) => rowData.unselectable ||
            (typeof selectionDisabled === 'function' && selectionDisabled(rowData))
            ? (hasUnselectables = hasUnselectablesSymbol)
            : defaultTo(rowData.id, rowIndex));
        if (hasUnselectables === hasUnselectablesSymbol) {
            allIds = allIds.filter(rowId => rowId !== hasUnselectablesSymbol);
        }
        const { leftShadowVisible, rightShadowVisible } = this.state;
        const isTableResizable = resizable === true && horizontalScroll === true;
        const contextValue = {
            ...this.props,
            leftShadowVisible,
            rightShadowVisible,
            onUpdateScrollShadows: this._handleUpdateScrollShadows,
            tableRef: this.tableRef,
        };
        let table = this.renderChildren();
        table = horizontalScroll ? (React.createElement(FloatingScrollBarContextProvider, { scrollableContentRef: this.tableRef, viewportRef: this.props.viewportRef, scrollElementRef: this.scrollElementRef }, table)) : (table);
        table = (React.createElement(TableContext.Provider, { value: contextValue },
            React.createElement(ColumnResize, { columns: this.props.columns, onColumnResize: resizeProps?.onColumnResize, onColumnResizeStart: resizeProps?.onColumnResizeStart, onColumnResizeEnd: resizeProps?.onColumnResizeEnd, isTableResizable: isTableResizable, minColumnWidth: resizeProps?.minColumnWidth, maxColumnWidth: resizeProps?.maxColumnWidth }, showSelection ? (React.createElement(BulkSelection, { ref: _ref => {
                    this.bulkSelection = _ref;
                }, selectedIds: selectedIds, deselectRowsByDefault: deselectRowsByDefault, selectionDisabled: selectionDisabled, hasMoreInBulkSelection: infiniteScroll && Boolean(totalSelectableCount) && hasMore, totalCount: totalSelectableCount, allIds: allIds, onSelectionChanged: onSelectionChanged, onSelectionStarted: onSelectionStarted }, table)) : (table))));
        table = horizontalScroll ? (React.createElement(ScrollSync, { proportional: false, horizontal: true, vertical: false }, table)) : (table);
        return table;
    }
}
Table.ToolbarContainer = TableToolbarContainer;
Table.Titlebar = TableTitleBar;
Table.Content = TableContent;
Table.SubToolbar = TableSubToolbar;
Table.EmptyState = TableEmptyState;
Table.BulkSelectionCheckbox = TableBulkSelectionCheckbox;
Table.displayName = 'Table';
Table.dataTableRowVirtualStyle = dataTableRowVirtualStyle;
Table.dataTableRowStyle = dataTableRowStyle;
Table.defaultProps = {
    ...DataTable.defaultProps,
    showSelection: false,
    showRowNumbers: false,
    hideBulkSelectionCheckbox: false,
    children: [React.createElement(Table.Content, { key: "content" })],
    withWrapper: true,
    showLastRowDivider: false,
    horizontalScroll: false,
    stickyColumns: 0,
    isRowDisabled: () => false,
    deselectRowsByDefault: false,
    resizable: false,
};
// export default Table;
//# sourceMappingURL=Table.js.map