"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const react_1 = tslib_1.__importDefault(require("react"));
const react_core_1 = require("@patternfly/react-core");
const react_table_1 = require("@patternfly/react-table");
const xor_js_1 = tslib_1.__importDefault(require("lodash-es/xor.js"));
const ui_1 = require("../ui");
const AITableMemo_1 = require("./AITableMemo");
require("./HostsTable.css");
const SelectionProvider = react_1.default.createContext({
    selectedIDs: [],
    allIDs: [],
});
const SelectCheckbox = ({ onSelect, id }) => {
    const { selectedIDs } = react_1.default.useContext(SelectionProvider);
    const isChecked = selectedIDs === null || selectedIDs === void 0 ? void 0 : selectedIDs.includes(id);
    return (react_1.default.createElement(react_core_1.Checkbox, { id: `select-${id}`, onChange: () => onSelect(!isChecked), isChecked: isChecked }));
};
const SelectAllCheckbox = ({ onSelect }) => {
    const { allIDs, selectedIDs } = react_1.default.useContext(SelectionProvider);
    const isChecked = (0, xor_js_1.default)(allIDs, selectedIDs).length === 0;
    return allIDs.length ? (react_1.default.createElement(react_core_1.Checkbox, { id: "select-all", onChange: () => onSelect(!isChecked), isChecked: isChecked })) : (react_1.default.createElement("div", null));
};
// eslint-disable-next-line
const AITable = ({ data, testId = 'hosts-table', className, content, ExpandComponent, getDataId, actionResolver, onSelect, children, selectedIDs, setSelectedIDs, perPage, page, onSetPage, onPerPageSelect, showPagination, perPageOptions, canSelectAll, variant, alreadySorted, }) => {
    const itemIDs = react_1.default.useMemo(() => data.map(getDataId), [data, getDataId]);
    const [openRows, setOpenRows] = react_1.default.useState({});
    const sortByRef = react_1.default.useRef();
    const [sortBy, setSortBy] = react_1.default.useState({
        index: onSelect ? 1 : 0,
        direction: react_table_1.SortByDirection.asc,
    });
    const dataRef = react_1.default.useRef(data);
    if (dataRef.current !== data) {
        dataRef.current = data;
    }
    react_1.default.useEffect(() => {
        if (selectedIDs && setSelectedIDs) {
            const idsToRemove = [];
            selectedIDs.forEach((id) => {
                const matchedData = data.find((d) => getDataId(d) === id);
                if (!matchedData) {
                    idsToRemove.push(id);
                }
            });
            if (idsToRemove.length) {
                setSelectedIDs(selectedIDs.filter((id) => !idsToRemove.includes(id)));
            }
        }
    }, [data, setSelectedIDs, selectedIDs, getDataId]);
    react_1.default.useEffect(() => {
        if (alreadySorted) {
            sortByRef.current = sortBy;
            setSortBy({
                index: -1,
                direction: react_table_1.SortByDirection.asc,
            });
        }
        else {
            if (sortBy.index === -1 && sortByRef.current) {
                setSortBy(sortByRef.current);
            }
        }
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [alreadySorted]);
    react_1.default.useEffect(() => {
        if (!alreadySorted) {
            sortByRef.current = sortBy;
        }
        else if (alreadySorted && sortBy.index !== -1) {
            sortByRef.current = sortBy;
        }
    }, [sortBy, alreadySorted]);
    const onSelectAll = react_1.default.useCallback((isChecked) => {
        setSelectedIDs === null || setSelectedIDs === void 0 ? void 0 : setSelectedIDs(isChecked ? dataRef.current.map(getDataId) : []);
    }, [setSelectedIDs, getDataId]);
    const [contentWithAdditions, columns] = react_1.default.useMemo(() => {
        let newContent = content;
        if (onSelect) {
            newContent = [
                {
                    header: {
                        title: canSelectAll ? react_1.default.createElement(SelectAllCheckbox, { onSelect: onSelectAll }) : '',
                        sort: false,
                    },
                    cell: (obj) => {
                        const id = getDataId(obj);
                        const selectId = `select-${id}`;
                        return {
                            title: react_1.default.createElement(SelectCheckbox, { id: id, onSelect: (isChecked) => onSelect(obj, isChecked) }),
                            props: { 'data-testid': selectId },
                        };
                    },
                },
                ...content,
            ];
        }
        const columns = newContent.map((c) => {
            var _a;
            return (Object.assign(Object.assign({}, c.header), { sort: (_a = c.header.sort) !== null && _a !== void 0 ? _a : true }));
        });
        return [newContent, columns];
    }, [canSelectAll, content, getDataId, onSelect, onSelectAll]);
    const getRows = react_1.default.useCallback((data) => (data || [])
        .map((obj) => {
        const id = getDataId(obj);
        const cells = contentWithAdditions.filter((c) => !!c.cell).map((c) => { var _a; return (_a = c.cell) === null || _a === void 0 ? void 0 : _a.call(c, obj); });
        const isOpen = !!openRows[id];
        return {
            isOpen,
            cells,
            key: `${id}-master`,
            id,
            actions: actionResolver ? actionResolver(obj) : undefined,
            nestedComponent: ExpandComponent ? react_1.default.createElement(ExpandComponent, { obj: obj }) : undefined,
        };
    })
        .slice((page - 1) * perPage, page * perPage), [page, perPage, getDataId, contentWithAdditions, openRows, actionResolver, ExpandComponent]);
    const hostRows = react_1.default.useMemo(() => getRows(data), [data, getRows]);
    const rows = react_1.default.useMemo(() => {
        if (hostRows.length) {
            return hostRows;
        }
        return (0, ui_1.getColSpanRow)(children, columns.length);
    }, [hostRows, columns, children]);
    const onCollapse = react_1.default.useCallback((_event, rowKey) => {
        const id = hostRows[rowKey].id;
        if (id) {
            setOpenRows(Object.assign({}, openRows, { [id]: !openRows[id] }));
        }
    }, [hostRows, openRows]);
    const onSort = react_1.default.useCallback((_event, index, direction) => {
        setOpenRows({}); // collapse all
        setSortBy({
            index,
            direction,
        });
    }, []);
    const sortedRows = react_1.default.useMemo(() => {
        if (alreadySorted && sortBy.index === -1) {
            return getRows(data);
        }
        return rows.sort((0, ui_1.rowSorter)(sortBy, (row, index = 0) => { var _a; return (_a = row.cells) === null || _a === void 0 ? void 0 : _a[index]; }));
    }, [alreadySorted, sortBy, rows, getRows, data]);
    return (react_1.default.createElement(react_1.default.Fragment, null,
        react_1.default.createElement(SelectionProvider.Provider, { value: {
                selectedIDs,
                allIDs: itemIDs,
            } },
            react_1.default.createElement(AITableMemo_1.AITableMemo, { rows: sortedRows, cols: columns, onCollapse: ExpandComponent ? onCollapse : undefined, className: className, "data-testid": testId, sortBy: sortBy, onSort: onSort, variant: variant })),
        showPagination && (react_1.default.createElement(react_core_1.Pagination, { variant: react_core_1.PaginationVariant.bottom, itemCount: itemIDs.length, perPage: perPage, onPerPageSelect: onPerPageSelect, page: page, onSetPage: onSetPage, perPageOptions: perPageOptions }))));
};
exports.default = AITable;
//# sourceMappingURL=AITable.js.map