import { formatAddress } from '@bilig/formula';
import { cellMutationRefToEngineOp, } from '../../cell-mutations-at.js';
export function createOpsTransactionRecord(ops, potentialNewCells, preparedCellAddressesByOpIndex) {
    const record = { kind: 'ops', ops };
    if (potentialNewCells !== undefined) {
        record.potentialNewCells = potentialNewCells;
    }
    if (preparedCellAddressesByOpIndex !== undefined) {
        record.preparedCellAddressesByOpIndex = preparedCellAddressesByOpIndex;
    }
    return record;
}
export function createLazySingleOpTransactionRecord(op, potentialNewCells) {
    return potentialNewCells === undefined ? { kind: 'single-op', op } : { kind: 'single-op', op, potentialNewCells };
}
function renameSheetTransactionRecordToOp(record) {
    return { kind: 'renameSheet', oldName: record.oldName, newName: record.newName };
}
export function createLazyCellMutationTransactionRecord(refs, potentialNewCells) {
    return potentialNewCells === undefined ? { kind: 'cell-mutations', refs } : { kind: 'cell-mutations', refs, potentialNewCells };
}
export function createSingleExistingNumericCellMutationTransactionRecord(request, potentialNewCells) {
    return {
        kind: 'single-existing-numeric-cell-mutation',
        sheetId: request.sheetId,
        row: request.row,
        col: request.col,
        cellIndex: request.cellIndex,
        value: request.value,
        potentialNewCells,
    };
}
export function singleExistingNumericCellMutationRecordToRef(record) {
    return singleExistingLiteralCellMutationRecordToRef({
        kind: 'single-existing-literal-cell-mutation',
        sheetId: record.sheetId,
        row: record.row,
        col: record.col,
        cellIndex: record.cellIndex,
        value: record.value,
        ...(record.potentialNewCells === undefined ? {} : { potentialNewCells: record.potentialNewCells }),
    });
}
export function createSingleExistingLiteralCellMutationTransactionRecord(request, potentialNewCells) {
    return {
        kind: 'single-existing-literal-cell-mutation',
        sheetId: request.sheetId,
        row: request.row,
        col: request.col,
        cellIndex: request.cellIndex,
        value: request.value,
        potentialNewCells,
    };
}
export function createExistingNumericCellMutationsTransactionRecord(captured, potentialNewCells) {
    return {
        kind: 'existing-numeric-cell-mutations',
        sheetIds: captured.sheetIds,
        cellIndexPlusOnes: captured.cellIndexPlusOnes,
        rows: captured.rows,
        cols: captured.cols,
        numbers: captured.numbers,
        potentialNewCells,
    };
}
export function createLazyReversedExistingNumericCellMutationsTransactionRecord(captured, numbers, potentialNewCells) {
    const count = captured.sheetIds.length;
    let sheetIds;
    let cellIndexPlusOnes;
    let rows;
    let cols;
    let reversedNumbers;
    const reverseUint32 = (source) => {
        const reversed = new Uint32Array(count);
        for (let index = 0; index < count; index += 1) {
            reversed[index] = source[count - 1 - index];
        }
        return reversed;
    };
    const reverseFloat64 = (source) => {
        const reversed = new Float64Array(count);
        for (let index = 0; index < count; index += 1) {
            reversed[index] = source[count - 1 - index];
        }
        return reversed;
    };
    return {
        kind: 'existing-numeric-cell-mutations',
        get sheetIds() {
            sheetIds ??= reverseUint32(captured.sheetIds);
            return sheetIds;
        },
        get cellIndexPlusOnes() {
            cellIndexPlusOnes ??= reverseUint32(captured.cellIndexPlusOnes);
            return cellIndexPlusOnes;
        },
        get rows() {
            rows ??= reverseUint32(captured.rows);
            return rows;
        },
        get cols() {
            cols ??= reverseUint32(captured.cols);
            return cols;
        },
        get numbers() {
            reversedNumbers ??= reverseFloat64(numbers);
            return reversedNumbers;
        },
        potentialNewCells,
    };
}
export function existingNumericCellMutationsRecordToRefs(record) {
    const refs = Array(record.sheetIds.length);
    for (let index = 0; index < refs.length; index += 1) {
        const cellIndexPlusOne = record.cellIndexPlusOnes[index];
        refs[index] = {
            sheetId: record.sheetIds[index],
            ...(cellIndexPlusOne === 0 ? {} : { cellIndex: cellIndexPlusOne - 1 }),
            mutation: {
                kind: 'setCellValue',
                row: record.rows[index],
                col: record.cols[index],
                value: record.numbers[index] ?? 0,
            },
        };
    }
    return refs;
}
export function singleExistingLiteralCellMutationRecordToRef(record) {
    return {
        sheetId: record.sheetId,
        cellIndex: record.cellIndex,
        mutation: {
            kind: 'setCellValue',
            row: record.row,
            col: record.col,
            value: record.value,
        },
    };
}
export function createLazyMaterializedCellMutationTransactionRecord(materializeRefs, potentialNewCells) {
    let cachedRefs;
    const record = {
        kind: 'cell-mutations',
        get refs() {
            cachedRefs ??= materializeRefs();
            return cachedRefs;
        },
    };
    if (potentialNewCells !== undefined) {
        record.potentialNewCells = potentialNewCells;
    }
    return record;
}
export function renderCommitCellMutationToEngineOp(entry) {
    const address = formatAddress(entry.mutation.row, entry.mutation.col);
    switch (entry.mutation.kind) {
        case 'setCellValue':
            return {
                kind: 'setCellValue',
                sheetName: entry.sheetName,
                address,
                value: entry.mutation.value,
            };
        case 'setCellFormula':
            return {
                kind: 'setCellFormula',
                sheetName: entry.sheetName,
                address,
                formula: entry.mutation.formula,
            };
        case 'clearCell':
            return {
                kind: 'clearCell',
                sheetName: entry.sheetName,
                address,
            };
    }
}
export function createLazyRenderCommitTransactionRecord(prefixOps, cellMutations, potentialNewCells) {
    let cachedOps;
    const record = {
        kind: 'ops',
        get ops() {
            cachedOps ??= [
                ...prefixOps.map((op) => structuredClone(op)),
                ...cellMutations.map((entry) => renderCommitCellMutationToEngineOp(entry)),
            ];
            return cachedOps;
        },
    };
    if (potentialNewCells !== undefined) {
        record.potentialNewCells = potentialNewCells;
    }
    return record;
}
export function transactionRecordOps(workbook, record) {
    if (record.kind === 'single-op') {
        return [record.op];
    }
    if (record.kind === 'rename-sheet') {
        return [renameSheetTransactionRecordToOp(record)];
    }
    if (record.kind === 'single-existing-numeric-cell-mutation') {
        return [cellMutationRefToEngineOp(workbook, singleExistingNumericCellMutationRecordToRef(record))];
    }
    if (record.kind === 'single-existing-literal-cell-mutation') {
        return [cellMutationRefToEngineOp(workbook, singleExistingLiteralCellMutationRecordToRef(record))];
    }
    if (record.kind === 'existing-numeric-cell-mutations') {
        return existingNumericCellMutationsRecordToRefs(record).map((ref) => cellMutationRefToEngineOp(workbook, ref));
    }
    if (record.kind === 'cell-mutations') {
        return record.refs.map((ref) => cellMutationRefToEngineOp(workbook, ref));
    }
    return record.ops;
}
export function cloneTransactionRecordOps(workbook, record) {
    if (record.kind === 'single-op') {
        return [structuredClone(record.op)];
    }
    if (record.kind === 'rename-sheet') {
        return [renameSheetTransactionRecordToOp(record)];
    }
    if (record.kind === 'single-existing-numeric-cell-mutation') {
        return [cellMutationRefToEngineOp(workbook, singleExistingNumericCellMutationRecordToRef(record))];
    }
    if (record.kind === 'single-existing-literal-cell-mutation') {
        return [cellMutationRefToEngineOp(workbook, singleExistingLiteralCellMutationRecordToRef(record))];
    }
    if (record.kind === 'existing-numeric-cell-mutations') {
        return existingNumericCellMutationsRecordToRefs(record).map((ref) => cellMutationRefToEngineOp(workbook, ref));
    }
    if (record.kind === 'cell-mutations') {
        return record.refs.map((ref) => cellMutationRefToEngineOp(workbook, ref));
    }
    return structuredClone(record.ops);
}
//# sourceMappingURL=mutation-transaction-records.js.map