import { jsx as _jsx } from "react/jsx-runtime";
/// <reference path="react-table-config.ts" />
import * as React from 'react';
import { useEffect } from 'react';
import { useBlockLayout, useExpanded, useFilters, useGlobalFilter, useRowSelect, useSortBy, useTable, defaultColumn, } from 'react-table';
import { useMemoCompare } from '../../hooks';
import { Box } from '../box/Box';
import { ConstrainedText } from '../constrainedtext/Constrainedtext.component';
import { Tooltip } from '../tooltip/Tooltip.component';
import { MultiSelectableContent } from './MultiSelectableContent';
import { TableSearch as Search } from './Search';
import { SearchWithQueryParams } from './SearchWithQueryParams';
import { SingleSelectableContent } from './SingleSelectableContent';
import { TableWrapper, TooltipContent } from './Tablestyle';
import { compareHealth } from './TableUtils';
import { useCheckbox } from './useCheckbox';
import { Icon } from '../icon/Icon.component';
const TableContext = React.createContext(null);
export const useTableContext = () => {
    const tableProps = React.useContext(TableContext);
    if (!tableProps) {
        throw new Error('The useTableContext hook can only be used within the <TableContext.Provider/>');
    }
    return tableProps; //Todo figure out a way to transfer the type to the context provider
};
export const EmptyCell = ({ tooltipContent, mr = 4, }) => {
    return (_jsx(Box, { mr: mr, children: _jsx(Tooltip, { overlay: _jsx(TooltipContent, { children: tooltipContent || 'unknown' }), children: _jsx(Icon, { name: "Minus" }) }) }));
};
const DefaultRenderer = ({ value }) => {
    const { rowHeight } = useTableContext();
    if (!value && value !== 0) {
        return _jsx(EmptyCell, {});
    }
    if (typeof value === 'string') {
        const lineClamp = rowHeight === 'h32'
            ? 1
            : rowHeight === 'h40' || rowHeight === 'h48'
                ? 2
                : 3;
        return (_jsx(Box, { mr: 4, children: _jsx(ConstrainedText, { text: value, lineClamp: lineClamp }) }));
    }
    return value;
};
function Table({ columns, data, defaultSortingKey, getRowId, children, sortTypes, globalFilter, allFilters, onBottom, onBottomOffset = 10, initiallySelectedRowsIds, updateTableData, }) {
    sortTypes = {
        health: (row1, row2) => {
            return compareHealth(row2.values.health, row1.values.health) || 0;
        },
        ...sortTypes,
    };
    const stringifyFilter = React.useMemo(() => {
        return (rows, columnIds, value) => {
            const filteredRows = rows.filter((row) => {
                // we stringify the object to make sure we can match the value
                return JSON.stringify(row.values)
                    .toLowerCase()
                    .includes((value || '').toLowerCase());
            });
            return filteredRows;
        };
    }, []);
    const formattedInitiallySelectedRows = React.useMemo(() => {
        if (initiallySelectedRowsIds) {
            return Array.from(initiallySelectedRowsIds).reduce((accumulatedValue, currentValue) => ({
                ...accumulatedValue,
                [currentValue]: true,
            }), {});
        }
        return {};
    }, []);
    const [rowHeight, setRowHeight] = React.useState('h40');
    const { headerGroups, rows, prepareRow, selectedFlatRows, getTableBodyProps, state: { selectedRowIds }, preGlobalFilteredRows, setGlobalFilter, setFilter, setAllFilters, setHiddenColumns, isAllRowsSelected, toggleAllRowsSelected, } = useTable({
        defaultColumn: {
            ...defaultColumn,
            Cell: DefaultRenderer,
        },
        columns: columns,
        data,
        getRowId,
        initialState: {
            sortBy: defaultSortingKey
                ? [
                    {
                        id: defaultSortingKey,
                        desc: false,
                    },
                ]
                : [],
            selectedRowIds: formattedInitiallySelectedRows,
            hiddenColumns: ['selection'],
        },
        disableMultiSort: true,
        autoResetSortBy: false,
        sortTypes,
        //@ts-ignore TODO investigate why this type is not matching
        globalFilter: stringifyFilter,
        autoResetHiddenColumns: false,
        updateTableData,
    }, useBlockLayout, useFilters, useGlobalFilter, useSortBy, useExpanded, useRowSelect, useCheckbox);
    useEffect(() => {
        if (globalFilter !== undefined && globalFilter !== null) {
            setGlobalFilter(globalFilter);
        }
    }, [globalFilter, setGlobalFilter, data]);
    const filters = useMemoCompare(allFilters, (previous, next) => !previous || JSON.stringify(previous) === JSON.stringify(next));
    useEffect(() => {
        if (!filters) {
            setAllFilters([]);
        }
        else {
            const validFilters = filters.filter((filter) => filter.id && filter.value !== undefined);
            setAllFilters(validFilters.length > 0 ? validFilters : []);
        }
    }, [filters, setAllFilters]);
    const contextValue = {
        headerGroups,
        rows,
        prepareRow,
        getTableBodyProps,
        selectedRowIds,
        selectedFlatRows,
        preGlobalFilteredRows,
        setGlobalFilter,
        rowHeight,
        setRowHeight,
        globalFilter,
        setFilter,
        onBottom,
        onBottomOffset,
        setHiddenColumns,
        isAllRowsSelected,
        toggleAllRowsSelected,
    };
    return (_jsx(TableContext.Provider
    //@ts-ignore
    , { 
        //@ts-ignore
        value: contextValue, children: _jsx(TableWrapper, { role: "grid", className: "table", children: children }) }));
}
Table.SingleSelectableContent = SingleSelectableContent;
Table.MultiSelectableContent = MultiSelectableContent;
Table.Search = Search;
Table.SearchWithQueryParams = SearchWithQueryParams;
export { Table };
