"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
    if (mod && mod.__esModule) return mod;
    var result = {};
    if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
    __setModuleDefault(result, mod);
    return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Table = void 0;
const react_table_1 = require("@tanstack/react-table");
const react_virtual_1 = require("@tanstack/react-virtual");
const __1 = require("../..");
const react_1 = __importStar(require("react"));
const useCallbackRef_1 = require("../../hooks/useCallbackRef");
const inlines_1 = require("inlines");
const TableTopBar_1 = require("./TableTopBar");
function renderCell(key, row, renderAs = 'normal') {
    if (typeof renderAs === 'function')
        return renderAs(row);
    if (renderAs === 'normal')
        return react_1.default.createElement(__1.Text, null, row[key]);
    if (renderAs === 'medium')
        return react_1.default.createElement(__1.Text, { weight: "medium" }, row[key]);
    if (renderAs === 'strong')
        return react_1.default.createElement(__1.Text, { weight: "strong" }, row[key]);
    if (renderAs === 'image')
        return react_1.default.createElement(__1.Thumbnail, { color: "neutral", size: "small", src: row[key] });
    if (renderAs === 'badge')
        return (react_1.default.createElement(__1.Badge, { autoColor: true, light: true, copy: true, copyValue: row[key] }, row[key]));
    if (renderAs === 'avatar')
        return (react_1.default.createElement(__1.Avatar, { light: true, autoColor: true }, row[key]));
    if (renderAs === 'toggle')
        return react_1.default.createElement(__1.Toggle, { value: row[key] });
    let content = row[key];
    if (row[key] instanceof Date) {
        content = row[key].getTime();
    }
    if (typeof row[key] === 'object') {
        content = JSON.stringify(row[key]);
    }
    return (react_1.default.createElement(__1.Text, { valueFormat: renderAs, light: renderAs?.includes?.('date') || renderAs?.includes?.('time') }, content));
}
function generateColumDefinitionsFromData(element) {
    let columnDefinitions = Object.entries(element).map(([key, value]) => {
        const columnDefinition = {
            key,
            header: key.charAt(0).toUpperCase() + key.slice(1),
        };
        if (value instanceof Date) {
            columnDefinition.renderAs = 'date-time-human';
        }
        if (key === 'id') {
            columnDefinition.header = 'ID';
            columnDefinition.renderAs = 'badge';
        }
        if (key === 'price') {
            columnDefinition.renderAs = 'number-euro';
        }
        if (key === 'bytes' || key === 'size') {
            columnDefinition.renderAs = 'number-bytes';
        }
        if (key === 'avatar') {
            columnDefinition.renderAs = 'avatar';
        }
        if (key === 'image' || key === 'img' || key === 'logo') {
            columnDefinition.renderAs = 'image';
        }
        if (key === 'createdAt' || key === 'updatedAt') {
            columnDefinition.renderAs = 'date-time-human';
        }
        if (key === 'name' || key === 'title') {
            columnDefinition.renderAs = 'medium';
        }
        if (key === 'status') {
            columnDefinition.renderAs = 'badge';
        }
        return columnDefinition;
    });
    const maybeNameIndex = columnDefinitions.findIndex((e) => e.key === 'name' || e.key === 'title');
    const maybeImageIndex = columnDefinitions.findIndex((e, i) => e.renderAs === 'image' && Math.abs(maybeNameIndex - i) < 2);
    if (maybeNameIndex > -1 && maybeImageIndex > -1) {
        const nameColumn = columnDefinitions[maybeNameIndex];
        const imageColumn = columnDefinitions[maybeImageIndex];
        columnDefinitions = columnDefinitions.filter((_, i) => i !== maybeImageIndex);
        columnDefinitions[columnDefinitions.findIndex((e) => e.key === 'name' || e.key === 'title')].renderAs = (row) => (react_1.default.createElement("div", { style: { display: 'flex', alignItems: 'center', gap: 12 } },
            react_1.default.createElement(__1.Thumbnail, { color: "neutral", size: "small", src: row[imageColumn.key] }),
            react_1.default.createElement(__1.Text, null, row[nameColumn.key])));
    }
    return columnDefinitions;
}
function Table({ data = [], columns: columnsProp, onScrollToBottom: onScrollToBottomProp, onVisibleElementsChange: onVisibleElementsChangeProp, virtualized, header = true, border, rowAction, onRowClick: onRowClickProp, selectable, onMultiSelectDelete, topBar, onFilterChange, }) {
    const [selectedPillVal, setSelectedPillVal] = (0, react_1.useState)('');
    const [searchValue, setSearchValue] = (0, react_1.useState)('');
    const [filteredColumns, setFilteredColumns] = (0, react_1.useState)([]);
    const [allColumnNames, setAllColumnNames] = (0, react_1.useState)([]);
    const [rowSelection, setRowSelection] = (0, react_1.useState)({});
    const [tableSearchFilterValue, setTableSearchFilterValue] = (0, react_1.useState)('');
    const [operatorTableSearchValue, setOperatorTableSearchValue] = (0, react_1.useState)('');
    if (searchValue) {
        const res = data.filter((obj) => JSON.stringify(obj).toLowerCase().includes(searchValue.toLowerCase()));
        data = res;
    }
    // filter changes
    // TODO: do something if there is a query or not..
    if (selectedPillVal && operatorTableSearchValue && tableSearchFilterValue) {
        let res;
        if (operatorTableSearchValue === '=') {
            res = data.filter((obj) => obj[selectedPillVal].toString().toLowerCase() ===
                tableSearchFilterValue.toString().toLowerCase());
        }
        else if (operatorTableSearchValue === '!=') {
            res = data.filter((obj) => obj[selectedPillVal].toString().toLowerCase() !==
                tableSearchFilterValue.toString().toLowerCase());
        }
        else if (operatorTableSearchValue === '<') {
            res = data.filter((obj) => obj[selectedPillVal] < tableSearchFilterValue);
        }
        else if (operatorTableSearchValue === '>') {
            res = data.filter((obj) => obj[selectedPillVal] > tableSearchFilterValue);
        }
        console.log('fire 🔥', res);
        if (res.length > 0) {
            data = res;
        }
    }
    (0, react_1.useEffect)(() => {
        setRowSelection({});
    }, [searchValue]);
    (0, react_1.useEffect)(() => {
        if (!selectedPillVal && virtualized && onFilterChange) {
            onFilterChange(null);
        }
        if (virtualized && onFilterChange) {
            if (selectedPillVal) {
                onFilterChange({
                    operator: operatorTableSearchValue,
                    field: selectedPillVal,
                    value: tableSearchFilterValue,
                });
            }
        }
    }, [tableSearchFilterValue, selectedPillVal]);
    // useEffect(() => {
    //   console.log('YOW he 🍿', rowSelection)
    //   console.log('AND THIS YOAW', table.getSelectedRowModel().flatRows)
    // }, [rowSelection])
    const columns = (0, react_1.useMemo)(() => {
        return [
            ...(columnsProp ?? generateColumDefinitionsFromData(data[0] ?? {})),
            ...(rowAction
                ? [
                    {
                        align: 'end',
                        id: 'internal_row_action',
                        header: '',
                        renderAs: rowAction,
                    },
                ]
                : []),
        ];
    }, [columnsProp, data]);
    const table = (0, react_table_1.useReactTable)({
        data,
        columns: columns
            .filter((item) => !filteredColumns.includes(item.key))
            .map((c) => {
            if ('id' in c) {
                return {
                    align: c.align,
                    id: c.id,
                    header: c.header,
                    cell: ({ row }) => c.renderAs(row.original),
                };
            }
            return {
                align: c.align,
                header: c.header,
                accessorKey: c.key,
                cell: ({ row }) => renderCell(c.key, row.original, c.renderAs),
            };
        }),
        state: {
            rowSelection,
        },
        enableRowSelection: true,
        onRowSelectionChange: setRowSelection,
        getCoreRowModel: (0, react_table_1.getCoreRowModel)(),
        getSortedRowModel: (0, react_table_1.getSortedRowModel)(),
    });
    const { rows } = table.getRowModel();
    const tableContainerRef = react_1.default.useRef(null);
    const rowVirtualizer = (0, react_virtual_1.useVirtualizer)({
        count: rows.length,
        getScrollElement: () => tableContainerRef.current,
        estimateSize: (0, react_1.useCallback)(() => 61, []),
        overscan: 10,
        // parentRef: tableContainerRef,
        // size: rows.length,
        // estimateSize: useCallback(() => 61, []),
        // overscan: 10,
    });
    const totalSize = rowVirtualizer.getTotalSize();
    const virtualRows = rowVirtualizer.getVirtualItems();
    // const { virtualItems: virtualRows, totalSize } = rowVirtualizer
    const paddingTop = virtualRows.length > 0 ? virtualRows?.[0]?.start || 0 : 0;
    const paddingBottom = virtualRows.length > 0
        ? totalSize - (virtualRows?.[virtualRows.length - 1]?.end || 0)
        : 0;
    const onVisibleElementsChange = (0, useCallbackRef_1.useCallbackRef)(onVisibleElementsChangeProp);
    (0, react_1.useEffect)(() => {
        if (onVisibleElementsChange) {
            onVisibleElementsChange(virtualRows.map((e) => e.index));
        }
    }, [onVisibleElementsChange, virtualRows]);
    const onScrollToBottom = (0, useCallbackRef_1.useCallbackRef)(onScrollToBottomProp);
    const handleScroll = react_1.default.useCallback((containerRefElement) => {
        if (onScrollToBottom) {
            const { scrollHeight, scrollTop, clientHeight } = containerRefElement;
            if (scrollHeight - scrollTop - clientHeight < 300) {
                onScrollToBottom();
            }
        }
    }, [onScrollToBottom]);
    const onRowClick = (0, useCallbackRef_1.useCallbackRef)(onRowClickProp);
    let tableHeaderGroups = table.getAllLeafColumns();
    (0, react_1.useEffect)(() => {
        let pillOptions = [];
        tableHeaderGroups?.map((item) => pillOptions.push({ label: item.id, value: item.id }));
        setAllColumnNames(pillOptions);
    }, []);
    return (react_1.default.createElement(react_1.default.Fragment, null,
        topBar && (react_1.default.createElement(TableTopBar_1.TableTopBar, { onMultiSelectDelete: onMultiSelectDelete, rowSelection: rowSelection, setRowSelection: setRowSelection, allColumnNames: allColumnNames, setSelectedPillVal: setSelectedPillVal, selectedPillVal: selectedPillVal, searchValue: searchValue, setSearchValue: setSearchValue, filteredColumns: filteredColumns, setFilteredColumns: setFilteredColumns, tableSearchFilterValue: tableSearchFilterValue, setTableSearchFilterValue: setTableSearchFilterValue, operatorTableSearchValue: operatorTableSearchValue, setOperatorTableSearchValue: setOperatorTableSearchValue, style: {
                borderLeft: border
                    ? `1px solid ${(0, __1.color)('border', 'default', 'strong')}`
                    : 0,
                borderRight: border
                    ? `1px solid ${(0, __1.color)('border', 'default', 'strong')}`
                    : 0,
            } })),
        react_1.default.createElement(inlines_1.styled.div, { ref: tableContainerRef, style: {
                overflow: 'auto',
                height: '100%',
                width: '100%',
                scrollbarColor: `${(0, __1.color)('border', 'default', 'strong')} transparent`,
                scrollbarWidth: 'thin',
                '&::-webkit-scrollbar': {
                    visibility: 'hidden',
                },
                '&::-webkit-scrollbar:vertical': {
                    width: '8px',
                },
                '&::-webkit-scrollbar:horizontal': {
                    height: '8px',
                },
                '@media (hover: hover)': {
                    '&:hover': {
                        '&::-webkit-scrollbar': {
                            visibility: 'visible',
                        },
                        '&::-webkit-scrollbar-thumb': {
                            backgroundColor: (0, __1.color)('border', 'default', 'strong'),
                            borderRadius: '4px',
                        },
                        '&::-webkit-scrollbar-thumb:vertical': {
                            borderRight: `2px solid ${(0, __1.color)('background', 'default', 'surface')}`,
                            minHeight: '32px',
                        },
                        '&::-webkit-scrollbar-thumb:horizontal': {
                            borderBottom: `2px solid ${(0, __1.color)('background', 'default', 'surface')}`,
                            minWidth: '32px',
                        },
                    },
                },
            }, onScroll: (e) => handleScroll(e.target) },
            react_1.default.createElement("table", { style: {
                    width: '100%',
                    borderCollapse: 'separate',
                    borderSpacing: 0,
                    ...(border
                        ? {
                            border: `1px solid ${(0, __1.color)('border', 'default', 'strong')}`,
                            borderRadius: 16,
                            borderTopRightRadius: topBar ? 0 : 16,
                            borderTopLeftRadius: topBar ? 0 : 16,
                        }
                        : {}),
                } },
                react_1.default.createElement("tbody", null,
                    virtualized && paddingTop > 0 && (react_1.default.createElement("tr", null,
                        react_1.default.createElement("td", { style: { height: `${paddingTop}px` } }))),
                    (virtualized
                        ? virtualRows.map((row) => rows[row.index])
                        : rows).map((row, index) => {
                        return (react_1.default.createElement("tr", { onClick: (e) => {
                                if (onRowClick) {
                                    onRowClick(row.original);
                                }
                            }, key: row.id },
                            selectable && (react_1.default.createElement("td", { style: {
                                    borderBottom: index !==
                                        (virtualized
                                            ? virtualRows.map((row) => rows[row.index])
                                            : rows).length -
                                            1 &&
                                        `1px solid ${(0, __1.color)('border', 'default', 'strong')}`,
                                } },
                                react_1.default.createElement(__1.Input, { type: "checkbox", value: row.getIsSelected(), onChange: row.getToggleSelectedHandler(), style: { marginLeft: 8 } }))),
                            row.getVisibleCells().map((cell) => {
                                return (react_1.default.createElement("td", { style: {
                                        boxSizing: 'border-box',
                                        height: 61,
                                        padding: '0 12px',
                                        borderBottom: index !==
                                            (virtualized
                                                ? virtualRows.map((row) => rows[row.index])
                                                : rows).length -
                                                1 &&
                                            `1px solid ${(0, __1.color)('border', 'default', 'strong')}`,
                                        overflow: 'hidden',
                                        textOverflow: 'ellipsis',
                                        whiteSpace: 'nowrap',
                                        maxWidth: '100%',
                                        borderTop: !border &&
                                            !header &&
                                            index === 0 &&
                                            `1px solid ${(0, __1.color)('border', 'default', 'strong')}`,
                                    }, key: cell.id },
                                    react_1.default.createElement("div", { style: {
                                            display: 'flex',
                                            justifyContent: cell.column.columnDef.align ?? 'start',
                                            alignItems: 'center',
                                        } }, (0, react_table_1.flexRender)(cell.column.columnDef.cell, cell.getContext()))));
                            })));
                    }),
                    virtualized && paddingBottom > 0 && (react_1.default.createElement("tr", null,
                        react_1.default.createElement("td", { style: { height: `${paddingBottom}px` } })))),
                header && (react_1.default.createElement("thead", { style: {
                        ...(header === 'sticky'
                            ? {
                                position: 'sticky',
                                top: 0,
                                margin: 0,
                                textAlign: 'left',
                                background: (0, __1.color)('background', 'default', 'strong'),
                            }
                            : {}),
                    } }, table.getHeaderGroups().map((headerGroup) => (react_1.default.createElement("tr", { key: headerGroup.id },
                    selectable && (react_1.default.createElement("th", { style: {
                            borderTop: !border &&
                                `1px solid ${(0, __1.color)('border', 'default', 'strong')}`,
                            borderBottom: `1px solid ${(0, __1.color)('border', 'default', 'strong')}`,
                        } },
                        react_1.default.createElement(__1.Input, { type: "checkbox", value: table.getIsAllRowsSelected(), onChange: () => {
                                if (table.getIsAllRowsSelected()) {
                                    setRowSelection({});
                                }
                                else {
                                    setRowSelection(Object.assign({}, new Array(data.length).fill(true)));
                                }
                            }, style: { marginLeft: 8, marginBottom: 4 } }))),
                    headerGroup.headers.map((header) => {
                        return (react_1.default.createElement("th", { key: header.id, style: {
                                padding: '0 12px',
                                height: 42,
                                boxSizing: 'border-box',
                                borderTop: !border &&
                                    `1px solid ${(0, __1.color)('border', 'default', 'strong')}`,
                                borderBottom: `1px solid ${(0, __1.color)('border', 'default', 'strong')}`,
                            } }, header.isPlaceholder ? null : (react_1.default.createElement("div", { onClick: header.column.getToggleSortingHandler(), style: {
                                display: 'flex',
                                height: '100%',
                                justifyContent: header.column.columnDef.align ??
                                    'start',
                                alignItems: 'center',
                                userSelect: 'none',
                                cursor: header.column.getCanSort()
                                    ? 'pointer'
                                    : 'default',
                            } },
                            {
                                asc: (react_1.default.createElement(__1.IconSortAsc, { color: "brand", style: {
                                        marginRight: 8,
                                    } })),
                                desc: (react_1.default.createElement(__1.IconSortDesc, { style: { marginRight: 8 }, color: "brand" })),
                            }[header.column.getIsSorted()] ?? null,
                            react_1.default.createElement(__1.Text, { style: {
                                    color: header.column.getIsSorted() ||
                                        selectedPillVal === header.id
                                        ? (0, __1.color)('content', 'brand', 'primary')
                                        : (0, __1.color)('content', 'default', 'secondary'),
                                }, weight: selectedPillVal === header.id
                                    ? 'medium'
                                    : 'normal' }, (0, react_table_1.flexRender)(header.column.columnDef.header, header.getContext()))))));
                    }))))))))));
}
exports.Table = Table;
//# sourceMappingURL=index.js.map