import { applyCellContent, parseA1Notation } from "./formula";

function cloneMergeConfig(input) {
    return Array.isArray(input) ? input.map((i => Object.assign(Object.assign({}, i), {
        range: (null == i ? void 0 : i.range) ? {
            start: Object.assign({}, i.range.start),
            end: Object.assign({}, i.range.end)
        } : null == i ? void 0 : i.range
    }))) : input;
}

function getCustomMergeCellFunc(customMergeCell) {
    return "function" == typeof customMergeCell ? customMergeCell : Array.isArray(customMergeCell) ? (col, row) => customMergeCell.find((item => item.range.start.col <= col && item.range.end.col >= col && item.range.start.row <= row && item.range.end.row >= row)) : void 0;
}

function applyMergeConfig(table, customMergeCell) {
    (null == table ? void 0 : table.options) && (null == table ? void 0 : table.internalProps) && (table.options.customMergeCell = cloneMergeConfig(customMergeCell), 
    table.internalProps.customMergeCell = getCustomMergeCellFunc(table.options.customMergeCell));
}

function cloneSortState(input) {
    return input ? Array.isArray(input) ? input.filter(Boolean).map((s => ({
        field: s.field,
        order: s.order
    }))) : {
        field: input.field,
        order: input.order
    } : null;
}

export function replayCommand(args) {
    var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16;
    const {table: table, vtableSheet: vtableSheet, cmd: cmd, direction: direction, deleteRecordsByReference: deleteRecordsByReference} = args;
    switch (cmd.type) {
      case "cell":
      case "cells":
        {
            const sheetKey = cmd.sheetKey;
            cmd.cells.forEach((c => {
                const content = "undo" === direction ? c.oldContent : c.newContent;
                applyCellContent({
                    table: table,
                    sheetKey: sheetKey,
                    row: c.row,
                    col: c.col,
                    content: content,
                    formulaManager: null == vtableSheet ? void 0 : vtableSheet.formulaManager
                });
            }));
            break;
        }

      case "merge_cells":
        {
            const c = cmd, next = "undo" === direction ? c.oldCustomMergeCell : c.newCustomMergeCell;
            applyMergeConfig(table, next);
            const sg = table.scenegraph;
            if (null == sg ? void 0 : sg.updateCellContent) {
                for (let i = c.startCol; i <= c.endCol; i++) for (let j = c.startRow; j <= c.endRow; j++) sg.updateCellContent(i, j);
                null === (_a = sg.updateNextFrame) || void 0 === _a || _a.call(sg);
            } else "function" == typeof table.renderWithRecreateCells && table.renderWithRecreateCells();
            break;
        }

      case "filter":
        {
            const c = cmd, pluginId = c.pluginId, snapshot = "undo" === direction ? c.oldSnapshot : c.newSnapshot, pm = table.pluginManager, filterPlugin = null !== (_g = null !== (_e = null !== (_c = null === (_b = null == pm ? void 0 : pm.getPlugin) || void 0 === _b ? void 0 : _b.call(pm, pluginId)) && void 0 !== _c ? _c : null === (_d = null == pm ? void 0 : pm.getPluginByName) || void 0 === _d ? void 0 : _d.call(pm, "Filter")) && void 0 !== _e ? _e : null === (_f = null == pm ? void 0 : pm.getPlugin) || void 0 === _f ? void 0 : _f.call(pm, "filter")) && void 0 !== _g ? _g : null === (_h = null == pm ? void 0 : pm.getPluginByName) || void 0 === _h ? void 0 : _h.call(pm, "filter");
            (null == filterPlugin ? void 0 : filterPlugin.applyFilterSnapshot) && filterPlugin.applyFilterSnapshot(snapshot);
            break;
        }

      case "sort":
        {
            const c = cmd, next = "undo" === direction ? c.oldSortState : c.newSortState;
            null === (_k = (_j = table).updateSortState) || void 0 === _k || _k.call(_j, null !== (_l = cloneSortState(next)) && void 0 !== _l ? _l : null, !0);
            break;
        }

      case "add_record":
        {
            const c = cmd;
            if ("undo" === direction) {
                const ds = null === (_m = null == table ? void 0 : table.internalProps) || void 0 === _m ? void 0 : _m.dataSource, rawRecords = null === (_o = null == ds ? void 0 : ds.dataSourceObj) || void 0 === _o ? void 0 : _o.records;
                let deletedByRaw = !1;
                if (Array.isArray(rawRecords) && "number" == typeof c.rawInsertIndex && c.recordCount > 0) {
                    const idx = c.rawInsertIndex;
                    idx >= 0 && idx < rawRecords.length && (rawRecords.splice(idx, c.recordCount), deletedByRaw = !0);
                }
                if (Array.isArray(rawRecords) && Array.isArray(c.records) && c.records.length) for (let i = 0; i < c.records.length; i++) {
                    const rawIndex = rawRecords.indexOf(c.records[i]);
                    rawIndex >= 0 && (rawRecords.splice(rawIndex, 1), deletedByRaw = !0);
                }
                if (!deletedByRaw && Array.isArray(rawRecords) && "number" == typeof c.recordCount && c.recordCount > 0) {
                    const before = c.anchorBefore, after = c.anchorAfter, beforeIndex = before ? rawRecords.indexOf(before) : -1, afterIndex = after ? rawRecords.indexOf(after) : -1;
                    beforeIndex >= 0 ? (rawRecords.splice(beforeIndex + 1, c.recordCount), deletedByRaw = !0) : afterIndex >= 0 && (rawRecords.splice(Math.max(0, afterIndex - c.recordCount), c.recordCount), 
                    deletedByRaw = !0);
                }
                if (deletedByRaw && (null === (_q = null === (_p = null == ds ? void 0 : ds.beforeChangedRecordsMap) || void 0 === _p ? void 0 : _p.clear) || void 0 === _q || _q.call(_p), 
                null === (_s = null === (_r = null == ds ? void 0 : ds.sortedIndexMap) || void 0 === _r ? void 0 : _r.clear) || void 0 === _s || _s.call(_r), 
                "function" == typeof table.updateFilterRules ? table.updateFilterRules(null === (_t = null == ds ? void 0 : ds.dataConfig) || void 0 === _t ? void 0 : _t.filterRules, {
                    clearRowHeightCache: !1
                }) : null === (_u = null == ds ? void 0 : ds.updateFilterRules) || void 0 === _u || _u.call(ds, null === (_v = null == ds ? void 0 : ds.dataConfig) || void 0 === _v ? void 0 : _v.filterRules)), 
                !deletedByRaw) if ("number" == typeof c.recordIndex && c.recordCount > 0) {
                    const indexs = [];
                    for (let i = 0; i < c.recordCount; i++) indexs.push(c.recordIndex + i);
                    null === (_x = (_w = table).deleteRecords) || void 0 === _x || _x.call(_w, indexs);
                } else deleteRecordsByReference(c.records);
            } else c.records.length && (null === (_z = (_y = table).addRecords) || void 0 === _z || _z.call(_y, c.records, c.recordIndex));
            break;
        }

      case "delete_record":
        {
            const c = cmd;
            if ("undo" === direction) {
                if (table.addRecord && Array.isArray(c.records) && Array.isArray(c.recordIndexs)) {
                    const pairs = [];
                    for (let i = 0; i < c.recordIndexs.length; i++) {
                        const idx = c.recordIndexs[i];
                        "number" == typeof idx && pairs.push({
                            idx: idx,
                            record: c.records[i]
                        });
                    }
                    pairs.sort(((a, b) => a.idx - b.idx));
                    for (const p of pairs) table.addRecord(p.record, p.idx);
                }
                if (c.deletedRowHeights && "function" == typeof table.setRowHeight) {
                    const headerCount = table.transpose ? table.rowHeaderLevelCount : table.columnHeaderLevelCount;
                    Object.keys(c.deletedRowHeights).forEach((k => {
                        const idx = Number(k), height = c.deletedRowHeights[k];
                        Number.isFinite(idx) && "number" == typeof height && table.setRowHeight(idx + (null != headerCount ? headerCount : 0), height);
                    }));
                }
            } else table.deleteRecords && table.deleteRecords(c.recordIndexs);
            if ("oldCustomMergeCell" in c || "newCustomMergeCell" in c) {
                const target = "undo" === direction ? c.oldCustomMergeCell : c.newCustomMergeCell;
                applyMergeConfig(table, target);
                const sg = table.scenegraph;
                if (null == sg ? void 0 : sg.updateCellContent) {
                    [ ...Array.isArray(c.oldCustomMergeCell) ? c.oldCustomMergeCell.map((i => null == i ? void 0 : i.range)).filter(Boolean) : [], ...Array.isArray(c.newCustomMergeCell) ? c.newCustomMergeCell.map((i => null == i ? void 0 : i.range)).filter(Boolean) : [] ].forEach((r => {
                        if (null == r ? void 0 : r.start) for (let col = r.start.col; col <= r.end.col; col++) for (let row = r.start.row; row <= r.end.row; row++) sg.updateCellContent(col, row);
                    })), null === (_0 = sg.updateNextFrame) || void 0 === _0 || _0.call(sg);
                } else "function" == typeof table.renderWithRecreateCells && table.renderWithRecreateCells();
            }
            break;
        }

      case "update_record":
        {
            const c = cmd;
            table.updateRecords && ("undo" === direction ? table.updateRecords(c.oldRecords, c.recordIndexs) : table.updateRecords(c.newRecords, c.recordIndexs));
            break;
        }

      case "add_column":
        {
            const c = cmd;
            if ("undo" === direction) {
                const deleteIndexs = [];
                for (let i = 0; i < c.columnCount; i++) deleteIndexs.push(c.columnIndex + i);
                null === (_2 = (_1 = table).deleteColumns) || void 0 === _2 || _2.call(_1, deleteIndexs, !0);
            } else null === (_4 = (_3 = table).addColumns) || void 0 === _4 || _4.call(_3, c.columns, c.columnIndex, !0);
            break;
        }

      case "delete_column":
        {
            const c = cmd;
            if ("undo" === direction) {
                if (c.deleteColIndexs.map(((idx, i) => ({
                    idx: idx,
                    column: c.columns[i]
                }))).sort(((a, b) => a.idx - b.idx)).forEach((item => {
                    var _a, _b;
                    null === (_b = (_a = table).addColumns) || void 0 === _b || _b.call(_a, [ item.column ], item.idx, !0);
                })), c.deletedColWidths && "function" == typeof table.setColWidth && Object.entries(c.deletedColWidths).forEach((([k, width]) => {
                    const idx = Number(k);
                    Number.isFinite(idx) && "number" == typeof width && table.setColWidth(idx, width);
                })), Array.isArray(c.deletedRecordValues) && c.deletedRecordValues.length) {
                    const records = table.records;
                    if (Array.isArray(records) && records.length) {
                        const recordIndexs = [], newRecords = [];
                        for (let i = 0; i < records.length; i++) {
                            const rec = records[i], rowValues = c.deletedRecordValues[i];
                            if (!Array.isArray(rec) || !Array.isArray(rowValues) || rowValues.length !== c.deleteColIndexs.length) continue;
                            const next = rec.slice();
                            for (let k = 0; k < c.deleteColIndexs.length; k++) next[c.deleteColIndexs[k]] = rowValues[k];
                            recordIndexs.push(i), newRecords.push(next);
                        }
                        recordIndexs.length && (null === (_6 = (_5 = table).updateRecords) || void 0 === _6 || _6.call(_5, newRecords, recordIndexs, !1));
                    }
                }
                if (c.sheetKey) {
                    const fm = null == vtableSheet ? void 0 : vtableSheet.formulaManager, engine = null == fm ? void 0 : fm.formulaEngine;
                    if ((null == fm ? void 0 : fm.normalizeSheetData) && (null == engine ? void 0 : engine.updateSheetData)) try {
                        const normalized = fm.normalizeSheetData(table.records || [], table);
                        engine.updateSheetData(c.sheetKey, normalized);
                    } catch (_17) {}
                }
                if (c.sheetKey && c.deletedFormulas) {
                    Object.entries(c.deletedFormulas).forEach((([cellRef, formula]) => {
                        const parsed = parseA1Notation(cellRef);
                        parsed && applyCellContent({
                            table: table,
                            sheetKey: c.sheetKey,
                            row: parsed.row,
                            col: parsed.col,
                            content: formula,
                            formulaManager: null == vtableSheet ? void 0 : vtableSheet.formulaManager
                        });
                    }));
                }
            } else null === (_8 = (_7 = table).deleteColumns) || void 0 === _8 || _8.call(_7, c.deleteColIndexs, !0);
            break;
        }

      case "change_header_position":
        {
            const c = cmd, moving = c.moving, from = "undo" === direction ? c.targetIndex : c.sourceIndex, to = "undo" === direction ? c.sourceIndex : c.targetIndex;
            "column" === moving ? null === (_10 = (_9 = table).changeHeaderPosition) || void 0 === _10 || _10.call(_9, {
                source: {
                    col: from,
                    row: 0
                },
                target: {
                    col: to,
                    row: 0
                },
                movingColumnOrRow: "column"
            }) : null === (_12 = (_11 = table).changeHeaderPosition) || void 0 === _12 || _12.call(_11, {
                source: {
                    col: 0,
                    row: from
                },
                target: {
                    col: 0,
                    row: to
                },
                movingColumnOrRow: "row"
            });
            break;
        }

      case "resize_row":
        {
            const c = cmd, height = "undo" === direction ? c.oldHeight : c.newHeight;
            null === (_14 = (_13 = table).setRowHeight) || void 0 === _14 || _14.call(_13, c.row, height);
            break;
        }

      case "resize_column":
        {
            const c = cmd, width = "undo" === direction ? c.oldWidth : c.newWidth;
            null === (_16 = (_15 = table).setColWidth) || void 0 === _16 || _16.call(_15, c.col, width);
            break;
        }
    }
}
//# sourceMappingURL=replay.js.map
