import { ValueTag } from '@bilig/protocol';
import { writeLiteralToCellStore } from '../../engine-value-utils.js';
import { makeCellEntity } from '../../entity-ids.js';
import { addEngineCounter } from '../../perf/engine-counters.js';
export function tryApplySingleDirectScalarLiteralMutationWithoutEvents(args, request) {
    return tryApplySingleDirectScalarLiteralMutationWithoutEventsAndReturnChanged(args, request) !== null;
}
export function tryApplySingleDirectScalarLiteralMutationWithoutEventsAndReturnChanged(args, request) {
    const dependencyEntity = makeCellEntity(request.existingIndex);
    const singleDependent = args.getSingleEntityDependent(dependencyEntity);
    if (singleDependent === -1) {
        return null;
    }
    let singleFormulaCellIndex = -1;
    let dependents;
    if (singleDependent >= 0) {
        singleFormulaCellIndex = singleDependent;
    }
    else {
        dependents = args.getEntityDependents(dependencyEntity);
        if (dependents.length === 0) {
            return null;
        }
    }
    let commonDelta = 0;
    let hasCommonDelta = false;
    let canUseCleanTerminalWrites = true;
    const validateDependent = (formulaCellIndex) => {
        if (!args.canUseDirectFormulaPostRecalc(formulaCellIndex)) {
            return false;
        }
        const formula = args.state.formulas.get(formulaCellIndex);
        const delta = formula?.directScalar === undefined
            ? undefined
            : args.tryDirectScalarNumericDeltaFromNumbers(formula.directScalar, request.existingIndex, request.oldNumber, request.newNumber);
        if (delta === undefined ||
            ((args.state.workbook.cellStore.flags[formulaCellIndex] ?? 0) & 8 /* CellFlags.InCycle */) !== 0 ||
            args.state.workbook.cellStore.tags[formulaCellIndex] !== ValueTag.Number) {
            return false;
        }
        if (canUseCleanTerminalWrites &&
            (!args.canSkipDirectFormulaColumnVersion(formulaCellIndex) ||
                (args.state.workbook.cellStore.stringIds[formulaCellIndex] ?? 0) !== 0 ||
                (args.state.workbook.cellStore.errors[formulaCellIndex] ?? 0) !== 0 ||
                ((args.state.workbook.cellStore.flags[formulaCellIndex] ?? 0) & (64 /* CellFlags.SpillChild */ | 128 /* CellFlags.PivotOutput */)) !== 0)) {
            canUseCleanTerminalWrites = false;
        }
        if (!hasCommonDelta) {
            commonDelta = delta;
            hasCommonDelta = true;
            return true;
        }
        return Object.is(commonDelta, delta);
    };
    if (singleFormulaCellIndex >= 0) {
        if (!validateDependent(singleFormulaCellIndex)) {
            return null;
        }
    }
    else {
        for (let index = 0; index < dependents.length; index += 1) {
            if (!validateDependent(dependents[index])) {
                return null;
            }
        }
    }
    const changedFormulaIndices = singleFormulaCellIndex >= 0 ? Uint32Array.of(singleFormulaCellIndex) : dependents;
    args.state.workbook.withBatchedColumnVersionUpdates(() => {
        writeLiteralToCellStore(args.state.workbook.cellStore, request.existingIndex, request.value, args.state.strings);
        args.state.workbook.notifyCellValueWritten(request.existingIndex);
        if (canUseCleanTerminalWrites) {
            const numbers = args.state.workbook.cellStore.numbers;
            const versions = args.state.workbook.cellStore.versions;
            for (let index = 0; index < changedFormulaIndices.length; index += 1) {
                const cellIndex = changedFormulaIndices[index];
                numbers[cellIndex] = numbers[cellIndex] + commonDelta;
                versions[cellIndex] = versions[cellIndex] + 1;
            }
            return;
        }
        for (let index = 0; index < changedFormulaIndices.length; index += 1) {
            if (!args.applyDirectFormulaNumericDelta(changedFormulaIndices[index], commonDelta)) {
                throw new Error('Failed to apply direct scalar delta');
            }
        }
    });
    const applicationCount = singleFormulaCellIndex >= 0 ? 1 : dependents.length;
    addEngineCounter(args.state.counters, 'directScalarDeltaApplications', applicationCount);
    addEngineCounter(args.state.counters, 'directScalarDeltaOnlyRecalcSkips');
    args.deferSingleCellKernelSync(request.existingIndex);
    args.state.setLastMetrics(args.makeSingleLiteralSkipMetrics());
    return changedFormulaIndices;
}
//# sourceMappingURL=operation-direct-scalar-literal-fast-path.js.map