import { getMemoOptions, makeStateUpdater, memo } from '../utils';
//
const getDefaultColumnPinningState = () => ({
    left: [],
    right: [],
});
export const ColumnPinning = {
    getInitialState: (state) => {
        return {
            columnPinning: getDefaultColumnPinningState(),
            ...state,
        };
    },
    getDefaultOptions: (table) => {
        return {
            onColumnPinningChange: makeStateUpdater('columnPinning', table),
        };
    },
    createColumn: (column, table) => {
        column.pin = (position) => {
            const columnIds = column
                .getLeafColumns()
                .map((d) => d.id)
                .filter(Boolean);
            table.setColumnPinning((old) => {
                var _a, _b, _c, _d, _e, _f;
                if (position === 'right') {
                    return {
                        left: ((_a = old === null || old === void 0 ? void 0 : old.left) !== null && _a !== void 0 ? _a : []).filter((d) => !(columnIds === null || columnIds === void 0 ? void 0 : columnIds.includes(d))),
                        right: [...((_b = old === null || old === void 0 ? void 0 : old.right) !== null && _b !== void 0 ? _b : []).filter((d) => !(columnIds === null || columnIds === void 0 ? void 0 : columnIds.includes(d))), ...columnIds],
                    };
                }
                if (position === 'left') {
                    return {
                        left: [...((_c = old === null || old === void 0 ? void 0 : old.left) !== null && _c !== void 0 ? _c : []).filter((d) => !(columnIds === null || columnIds === void 0 ? void 0 : columnIds.includes(d))), ...columnIds],
                        right: ((_d = old === null || old === void 0 ? void 0 : old.right) !== null && _d !== void 0 ? _d : []).filter((d) => !(columnIds === null || columnIds === void 0 ? void 0 : columnIds.includes(d))),
                    };
                }
                return {
                    left: ((_e = old === null || old === void 0 ? void 0 : old.left) !== null && _e !== void 0 ? _e : []).filter((d) => !(columnIds === null || columnIds === void 0 ? void 0 : columnIds.includes(d))),
                    right: ((_f = old === null || old === void 0 ? void 0 : old.right) !== null && _f !== void 0 ? _f : []).filter((d) => !(columnIds === null || columnIds === void 0 ? void 0 : columnIds.includes(d))),
                };
            });
        };
        column.getCanPin = () => {
            const leafColumns = column.getLeafColumns();
            return leafColumns.some((d) => {
                var _a, _b, _c;
                return ((_a = d.columnDef.enablePinning) !== null && _a !== void 0 ? _a : true) &&
                    ((_c = (_b = table.options.enableColumnPinning) !== null && _b !== void 0 ? _b : table.options.enablePinning) !== null && _c !== void 0 ? _c : true);
            });
        };
        column.getIsPinned = () => {
            const leafColumnIds = column.getLeafColumns().map((d) => d.id);
            const { left, right } = table.getState().columnPinning;
            const isLeft = leafColumnIds.some((d) => left === null || left === void 0 ? void 0 : left.includes(d));
            const isRight = leafColumnIds.some((d) => right === null || right === void 0 ? void 0 : right.includes(d));
            if (isLeft)
                return 'left';
            if (isRight)
                return 'right';
            return false;
        };
        column.getPinnedIndex = () => {
            var _a, _b, _c;
            const position = column.getIsPinned();
            return position ? ((_c = (_b = (_a = table.getState().columnPinning) === null || _a === void 0 ? void 0 : _a[position]) === null || _b === void 0 ? void 0 : _b.indexOf(column.id)) !== null && _c !== void 0 ? _c : -1) : 0;
        };
    },
    createRow: (row, table) => {
        row.getCenterVisibleCells = memo(() => [
            row._getAllVisibleCells(),
            table.getState().columnPinning.left,
            table.getState().columnPinning.right,
        ], (allCells, left, right) => {
            const leftAndRight = [...(left !== null && left !== void 0 ? left : []), ...(right !== null && right !== void 0 ? right : [])];
            return allCells.filter((d) => !leftAndRight.includes(d.column.id));
        }, getMemoOptions(table.options, 'debugRows', 'getCenterVisibleCells'));
        row.getLeftVisibleCells = memo(() => [row._getAllVisibleCells(), table.getState().columnPinning.left], (allCells, left) => {
            const cells = (left !== null && left !== void 0 ? left : [])
                .map((columnId) => allCells.find((cell) => cell.column.id === columnId))
                .filter(Boolean)
                .map((d) => ({ ...d, position: 'left' }));
            return cells;
        }, getMemoOptions(table.options, 'debugRows', 'getLeftVisibleCells'));
        row.getRightVisibleCells = memo(() => [row._getAllVisibleCells(), table.getState().columnPinning.right], (allCells, right) => {
            const cells = (right !== null && right !== void 0 ? right : [])
                .map((columnId) => allCells.find((cell) => cell.column.id === columnId))
                .filter(Boolean)
                .map((d) => ({ ...d, position: 'right' }));
            return cells;
        }, getMemoOptions(table.options, 'debugRows', 'getRightVisibleCells'));
    },
    createTable: (table) => {
        table.setColumnPinning = (updater) => { var _a, _b; return (_b = (_a = table.options).onColumnPinningChange) === null || _b === void 0 ? void 0 : _b.call(_a, updater); };
        table.resetColumnPinning = (defaultState) => {
            var _a, _b;
            return table.setColumnPinning(defaultState
                ? getDefaultColumnPinningState()
                : ((_b = (_a = table.initialState) === null || _a === void 0 ? void 0 : _a.columnPinning) !== null && _b !== void 0 ? _b : getDefaultColumnPinningState()));
        };
        table.getIsSomeColumnsPinned = (position) => {
            var _a, _b, _c;
            const pinningState = table.getState().columnPinning;
            if (!position) {
                return Boolean(((_a = pinningState.left) === null || _a === void 0 ? void 0 : _a.length) || ((_b = pinningState.right) === null || _b === void 0 ? void 0 : _b.length));
            }
            return Boolean((_c = pinningState[position]) === null || _c === void 0 ? void 0 : _c.length);
        };
        table.getLeftLeafColumns = memo(() => [table.getAllLeafColumns(), table.getState().columnPinning.left], (allColumns, left) => {
            return (left !== null && left !== void 0 ? left : [])
                .map((columnId) => allColumns.find((column) => column.id === columnId))
                .filter(Boolean);
        }, getMemoOptions(table.options, 'debugColumns', 'getLeftLeafColumns'));
        table.getRightLeafColumns = memo(() => [table.getAllLeafColumns(), table.getState().columnPinning.right], (allColumns, right) => {
            return (right !== null && right !== void 0 ? right : [])
                .map((columnId) => allColumns.find((column) => column.id === columnId))
                .filter(Boolean);
        }, getMemoOptions(table.options, 'debugColumns', 'getRightLeafColumns'));
        table.getCenterLeafColumns = memo(() => [
            table.getAllLeafColumns(),
            table.getState().columnPinning.left,
            table.getState().columnPinning.right,
        ], (allColumns, left, right) => {
            const leftAndRight = [...(left !== null && left !== void 0 ? left : []), ...(right !== null && right !== void 0 ? right : [])];
            return allColumns.filter((d) => !leftAndRight.includes(d.id));
        }, getMemoOptions(table.options, 'debugColumns', 'getCenterLeafColumns'));
    },
};
