import { Effect } from 'effect';
import { definedNameValuesEqual, renameDefinedNameValueSheet } from '../../engine-metadata-utils.js';
import { createInitialRecalcMetrics, createInitialSelectionState } from '../runtime-state.js';
import { EngineMaintenanceError } from '../errors.js';
function maintenanceErrorMessage(message, cause) {
    return cause instanceof Error && cause.message.length > 0 ? cause.message : message;
}
function estimatePotentialNewCells(ops) {
    let count = 0;
    for (let index = 0; index < ops.length; index += 1) {
        const op = ops[index];
        if (op.kind === 'setCellValue' || op.kind === 'setCellFormula' || op.kind === 'setCellFormat') {
            count += 1;
        }
    }
    return count;
}
export function createEngineMaintenanceService(args) {
    const rewriteDefinedNamesForSheetRenameNow = (oldSheetName, newSheetName) => {
        args.state.workbook.listDefinedNames().forEach((record) => {
            const nextValue = renameDefinedNameValueSheet(record.value, oldSheetName, newSheetName);
            if (!definedNameValuesEqual(record.value, nextValue)) {
                args.state.workbook.setDefinedName(record.name, nextValue, record.scopeSheetName);
            }
        });
    };
    const resetWorkbookNow = (workbookName = 'Workbook') => {
        const previousBatchId = args.state.getLastMetrics().batchId;
        args.state.workbook.reset(workbookName);
        args.state.formulas.clear();
        args.reverseState.reverseCellEdges.length = 0;
        args.reverseState.reverseRangeEdges.length = 0;
        args.reverseState.reverseDefinedNameEdges.clear();
        args.reverseState.reverseTableEdges.clear();
        args.reverseState.reverseSpillEdges.clear();
        args.reverseState.reverseAggregateColumnEdges.clear();
        args.reverseState.reverseExactLookupColumnEdges.clear();
        args.reverseState.reverseSortedLookupColumnEdges.clear();
        args.pivotOutputOwners.clear();
        args.state.ranges.reset();
        args.edgeArena.reset();
        args.state.entityVersions.clear();
        args.state.sheetDeleteVersions.clear();
        args.state.undoStack.length = 0;
        args.state.redoStack.length = 0;
        args.state.setSelection(createInitialSelectionState());
        args.state.setSyncState('local-only');
        args.state.setLastMetrics({
            ...createInitialRecalcMetrics(),
            batchId: previousBatchId,
        });
        args.resetFormulaRuntimeCaches();
        args.setWasmProgramSyncPending(false);
        args.setMaterializedCellCount(0);
        args.resetWasmState();
    };
    return {
        captureSheetCellState(sheetName) {
            return Effect.try({
                try: () => args.captureSheetCellState(sheetName),
                catch: (cause) => new EngineMaintenanceError({
                    message: maintenanceErrorMessage('Failed to capture sheet cell state', cause),
                    cause,
                }),
            });
        },
        captureRowRangeCellState(sheetName, start, count) {
            return Effect.try({
                try: () => args.captureRowRangeCellState(sheetName, start, count),
                catch: (cause) => new EngineMaintenanceError({
                    message: maintenanceErrorMessage('Failed to capture row range cell state', cause),
                    cause,
                }),
            });
        },
        captureColumnRangeCellState(sheetName, start, count) {
            return Effect.try({
                try: () => args.captureColumnRangeCellState(sheetName, start, count),
                catch: (cause) => new EngineMaintenanceError({
                    message: maintenanceErrorMessage('Failed to capture column range cell state', cause),
                    cause,
                }),
            });
        },
        rewriteDefinedNamesForSheetRename(oldSheetName, newSheetName) {
            return Effect.try({
                try: () => {
                    rewriteDefinedNamesForSheetRenameNow(oldSheetName, newSheetName);
                },
                catch: (cause) => new EngineMaintenanceError({
                    message: maintenanceErrorMessage('Failed to rewrite defined names for sheet rename', cause),
                    cause,
                }),
            });
        },
        estimatePotentialNewCells(ops) {
            return Effect.try({
                try: () => estimatePotentialNewCells(ops),
                catch: (cause) => new EngineMaintenanceError({
                    message: maintenanceErrorMessage('Failed to estimate potential new cells', cause),
                    cause,
                }),
            });
        },
        resetWorkbook(workbookName) {
            return Effect.try({
                try: () => {
                    resetWorkbookNow(workbookName);
                },
                catch: (cause) => new EngineMaintenanceError({
                    message: maintenanceErrorMessage('Failed to reset workbook', cause),
                    cause,
                }),
            });
        },
    };
}
//# sourceMappingURL=maintenance-service.js.map