import { aggregationFns } from '../aggregationFns';
import { isFunction, makeStateUpdater } from '../utils';
//
export const ColumnGrouping = {
    getDefaultColumnDef: () => {
        return {
            aggregatedCell: (props) => { var _a, _b, _c; return (_c = (_b = (_a = props.getValue()) === null || _a === void 0 ? void 0 : _a.toString) === null || _b === void 0 ? void 0 : _b.call(_a)) !== null && _c !== void 0 ? _c : null; },
            aggregationFn: 'auto',
        };
    },
    getInitialState: (state) => {
        return {
            grouping: [],
            ...state,
        };
    },
    getDefaultOptions: (table) => {
        return {
            onGroupingChange: makeStateUpdater('grouping', table),
            groupedColumnMode: 'reorder',
        };
    },
    createColumn: (column, table) => {
        column.toggleGrouping = () => {
            table.setGrouping((old) => {
                // Find any existing grouping for this column
                if (old === null || old === void 0 ? void 0 : old.includes(column.id)) {
                    return old.filter((d) => d !== column.id);
                }
                return [...(old !== null && old !== void 0 ? old : []), column.id];
            });
        };
        column.getCanGroup = () => {
            var _a, _b;
            return (((_a = column.columnDef.enableGrouping) !== null && _a !== void 0 ? _a : true) &&
                ((_b = table.options.enableGrouping) !== null && _b !== void 0 ? _b : true) &&
                (!!column.accessorFn || !!column.columnDef.getGroupingValue));
        };
        column.getIsGrouped = () => {
            var _a;
            return (_a = table.getState().grouping) === null || _a === void 0 ? void 0 : _a.includes(column.id);
        };
        column.getGroupedIndex = () => { var _a; return (_a = table.getState().grouping) === null || _a === void 0 ? void 0 : _a.indexOf(column.id); };
        column.getToggleGroupingHandler = () => {
            const canGroup = column.getCanGroup();
            return () => {
                if (!canGroup)
                    return;
                column.toggleGrouping();
            };
        };
        column.getAutoAggregationFn = () => {
            const firstRow = table.getCoreRowModel().flatRows[0];
            const value = firstRow === null || firstRow === void 0 ? void 0 : firstRow.getValue(column.id);
            if (typeof value === 'number') {
                return aggregationFns.sum;
            }
            if (Object.prototype.toString.call(value) === '[object Date]') {
                return aggregationFns.extent;
            }
        };
        column.getAggregationFn = () => {
            var _a, _b;
            if (!column) {
                throw new Error();
            }
            if (isFunction(column.columnDef.aggregationFn)) {
                return column.columnDef.aggregationFn;
            }
            if (column.columnDef.aggregationFn === 'auto') {
                return column.getAutoAggregationFn();
            }
            return ((_b = (_a = table.options.aggregationFns) === null || _a === void 0 ? void 0 : _a[column.columnDef.aggregationFn]) !== null && _b !== void 0 ? _b : aggregationFns[column.columnDef.aggregationFn]);
        };
    },
    createTable: (table) => {
        table.setGrouping = (updater) => { var _a, _b; return (_b = (_a = table.options).onGroupingChange) === null || _b === void 0 ? void 0 : _b.call(_a, updater); };
        table.resetGrouping = (defaultState) => {
            var _a, _b;
            table.setGrouping(defaultState ? [] : ((_b = (_a = table.initialState) === null || _a === void 0 ? void 0 : _a.grouping) !== null && _b !== void 0 ? _b : []));
        };
        table.getPreGroupedRowModel = () => table.getFilteredRowModel();
        table.getGroupedRowModel = () => {
            if (!table._getGroupedRowModel && table.options.getGroupedRowModel) {
                table._getGroupedRowModel = table.options.getGroupedRowModel(table);
            }
            if (table.options.manualGrouping || !table._getGroupedRowModel) {
                return table.getPreGroupedRowModel();
            }
            return table._getGroupedRowModel();
        };
    },
    createRow: (row, table) => {
        row.getIsGrouped = () => !!row.groupingColumnId;
        row.getGroupingValue = (columnId) => {
            if (Object.prototype.hasOwnProperty.call(row._groupingValuesCache, columnId)) {
                return row._groupingValuesCache[columnId];
            }
            const column = table.getColumn(columnId);
            if (!(column === null || column === void 0 ? void 0 : column.columnDef.getGroupingValue)) {
                return row.getValue(columnId);
            }
            row._groupingValuesCache[columnId] = column.columnDef.getGroupingValue(row.original);
            return row._groupingValuesCache[columnId];
        };
        row._groupingValuesCache = {};
    },
    createCell: (cell, column, row, 
    // eslint-disable-next-line @typescript-eslint/no-unused-vars -- 接口约定保留 table 参数
    table) => {
        cell.getIsGrouped = () => column.getIsGrouped() && column.id === row.groupingColumnId;
        cell.getIsPlaceholder = () => !cell.getIsGrouped() && column.getIsGrouped();
        cell.getIsAggregated = () => { var _a; return !cell.getIsGrouped() && !cell.getIsPlaceholder() && !!((_a = row.subRows) === null || _a === void 0 ? void 0 : _a.length); };
    },
};
export function orderColumns(leafColumns, grouping, groupedColumnMode) {
    if (!(grouping === null || grouping === void 0 ? void 0 : grouping.length) || !groupedColumnMode) {
        return leafColumns;
    }
    const nonGroupingColumns = leafColumns.filter((col) => !grouping.includes(col.id));
    if (groupedColumnMode === 'remove') {
        return nonGroupingColumns;
    }
    const groupingColumns = grouping
        .map((g) => leafColumns.find((col) => col.id === g))
        .filter(Boolean);
    return [...groupingColumns, ...nonGroupingColumns];
}
