import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "@emotion/react/jsx-runtime";
import { useEffect, useMemo, useState } from 'react';
import { sortBy } from 'lodash-es';
import { Table as BaseTable, Thead, Tr, Th, Tbody, Checkbox, Td, Box, Spinner, } from '@chakra-ui/react';
import { TablePagination } from './Pagination';
import { TableTd } from './TableTd';
export const TableImpl = ({ data, majorKey, rowsPerPage, size, columns, isMultiSelect, mergeState, services, }) => {
    const [selectedItem, setSelectedItem] = useState();
    const [selectedItems, setSelectedItems] = useState([]);
    const [currentPage, setCurrentPage] = useState(0);
    const [sortRule, setSortRule] = useState();
    const pageNumber = Math.ceil(((data === null || data === void 0 ? void 0 : data.length) || 0) / rowsPerPage);
    useEffect(() => {
        updateSelectedItems([]);
        updateSelectedItem(undefined);
        setCurrentPage(0);
        setSortRule(undefined);
    }, [data]);
    const updateSelectedItems = (items) => {
        setSelectedItems(items);
        mergeState({ selectedItems: items });
    };
    const updateSelectedItem = (item) => {
        setSelectedItem(item);
        mergeState({ selectedItem: item });
    };
    const sortedData = useMemo(() => {
        if (!sortRule)
            return data;
        const sorted = sortBy(data, sortRule.key);
        return sortRule.desc ? sorted.reverse() : sorted;
    }, [sortRule, data]);
    const currentPageData = sortedData === null || sortedData === void 0 ? void 0 : sortedData.slice(currentPage * rowsPerPage, currentPage * rowsPerPage + rowsPerPage);
    function isItemSelected(target) {
        if (isMultiSelect) {
            return selectedItems.findIndex(item => item[majorKey] === target[majorKey]) > -1;
        }
        return selectedItem && selectedItem[majorKey] === target[majorKey];
    }
    function selectItem(item) {
        if (isMultiSelect) {
            let newSelectedItems;
            if (isItemSelected(item)) {
                newSelectedItems = selectedItems.filter(selectedItem => selectedItem[majorKey] != item[majorKey]);
            }
            else {
                newSelectedItems = selectedItems.concat(item);
            }
            updateSelectedItems(newSelectedItems);
        }
        updateSelectedItem(item);
    }
    const allCheckbox = useMemo(() => {
        if (!data)
            return null;
        const isAllChecked = isMultiSelect && selectedItems.length === data.length;
        const isIndeterminate = selectedItems.length > 0 && selectedItems.length < data.length;
        const onChange = (e) => {
            if (e.target.checked) {
                updateSelectedItems(data);
            }
            else {
                updateSelectedItems([]);
            }
        };
        return (_jsx(Th, Object.assign({ paddingX: "4", paddingY: "2", width: "10" }, { children: _jsx(Checkbox, { size: "lg", isIndeterminate: isIndeterminate, checked: isAllChecked, onChange: onChange }, void 0) }), "allCheckbox"));
    }, [selectedItems.length, data]);
    const tableContent = (_jsxs(_Fragment, { children: [_jsxs(BaseTable, Object.assign({ size: size }, { children: [_jsx(Thead, { children: _jsxs(Tr, Object.assign({ height: "10" }, { children: [isMultiSelect ? allCheckbox : undefined, columns.map(({ title, key }) => {
                                    let sortArrow;
                                    if (sortRule && sortRule.key === key) {
                                        sortArrow = sortRule.desc ? '⬇️' : '⬆️';
                                    }
                                    const onClick = () => {
                                        if (sortRule && sortRule.key === key) {
                                            setSortRule({ key, desc: !sortRule.desc });
                                        }
                                        else {
                                            setSortRule({ key, desc: true });
                                        }
                                    };
                                    return (_jsxs(Th, Object.assign({ paddingX: "4", paddingY: "2", onClick: onClick }, { children: [title, sortArrow] }), key));
                                })] }), void 0) }, void 0), _jsx(Tbody, { children: currentPageData === null || currentPageData === void 0 ? void 0 : currentPageData.map(item => {
                            const isSelected = isItemSelected(item);
                            let onClickToggle = true;
                            const onClickCheckbox = (e) => {
                                if (onClickToggle) {
                                    e.stopPropagation();
                                }
                                onClickToggle = !onClickToggle;
                            };
                            const checkbox = (_jsx(Td, Object.assign({ paddingX: "4", paddingY: "2", width: "10", onClick: onClickCheckbox }, { children: _jsx(Checkbox, { size: "lg", isChecked: isSelected }, void 0) }), "$checkbox"));
                            return (_jsxs(Tr, Object.assign({ height: "10", bgColor: isSelected ? 'yellow.100' : undefined, onClick: () => {
                                    selectItem(item);
                                } }, { children: [isMultiSelect ? checkbox : undefined, columns.map(column => (_jsx(TableTd, { item: item, column: column, onClickItem: () => selectItem(item), services: services }, column.key)))] }), item[majorKey]));
                        }) }, void 0)] }), void 0), _jsx(TablePagination, { pageNumber: pageNumber, currentPage: currentPage, onChange: v => setCurrentPage(v) }, void 0)] }, void 0));
    const loadingSpinner = (_jsx(Box, Object.assign({ display: "flex", height: "full" }, { children: _jsx(Spinner, { size: "xl", margin: "auto" }, void 0) }), void 0));
    return (_jsx(Box, Object.assign({ width: "full", height: "full", background: "white", border: "1px solid", borderColor: "gray.200", borderRadius: "base", overflow: "auto" }, { children: !data ? loadingSpinner : tableContent }), void 0));
};
//# sourceMappingURL=Table.js.map