import { composeSingleDisjointExplicitEventChanges } from './direct-formula-recalc-helpers.js';
import { makeCompactExistingNumericMutationResult, makeExistingNumericMutationResult, tagTrustedPhysicalTrackedChanges, } from './operation-change-helpers.js';
import { emitOperationTrackedCellsBatch } from './operation-tracked-event-helpers.js';
export function tryApplySingleDirectAggregateLiteralMutationFastPath(args, request) {
    let singleAffected = -2;
    if (request.singleRangeEntityDependent !== undefined) {
        const rangeDependent = args.getSingleEntityDependent(request.singleRangeEntityDependent);
        if (rangeDependent < -1) {
            return null;
        }
        if (rangeDependent >= 0) {
            singleAffected = rangeDependent;
        }
    }
    if (singleAffected >= 0 && !args.canApplyDirectAggregateLiteralDeltaForRequest(singleAffected, request)) {
        return null;
    }
    if (singleAffected < -1) {
        singleAffected = args.collectSingleApplicableDirectAggregateDependent({
            sheetName: request.sheetName,
            ...(request.sheetId === undefined ? {} : { sheetId: request.sheetId }),
            row: request.row,
            col: request.col,
        });
    }
    if (singleAffected === -1) {
        args.writeFastPathLiteralToExistingCell(request.existingIndex, request.value);
        args.deferSingleCellKernelSync(request.existingIndex);
        const lastMetrics = args.makeSingleLiteralSkipMetrics();
        args.state.setLastMetrics(lastMetrics);
        if (request.emitTracked) {
            const changed = Uint32Array.of(request.existingIndex);
            emitOperationTrackedCellsBatch({
                events: args.state.events,
                changedCellIndices: changed,
                metrics: lastMetrics,
            });
            return makeExistingNumericMutationResult(changed, 1);
        }
        return makeCompactExistingNumericMutationResult(request.existingIndex, undefined, 1);
    }
    let singleAggregateCellIndex = -1;
    let affected;
    if (singleAffected >= 0) {
        singleAggregateCellIndex = singleAffected;
    }
    else {
        const collected = args.collectAffectedDirectRangeDependents({
            sheetName: request.sheetName,
            row: request.row,
            col: request.col,
        });
        if (collected.length === 0 || collected.length > args.directRangePostRecalcLimit) {
            return null;
        }
        for (let index = 0; index < collected.length; index += 1) {
            if (!args.canApplyDirectAggregateLiteralDelta(collected[index])) {
                return null;
            }
        }
        affected = collected;
    }
    const affectedCount = singleAggregateCellIndex >= 0 ? 1 : (affected?.length ?? 0);
    const sharesSingleAggregateVersionColumn = singleAggregateCellIndex >= 0 &&
        request.sheetId !== undefined &&
        args.state.workbook.cellStore.sheetIds[singleAggregateCellIndex] === request.sheetId &&
        args.state.workbook.cellStore.cols[singleAggregateCellIndex] === request.col;
    const shouldBatchColumnVersions = affectedCount > 1 ||
        (singleAggregateCellIndex >= 0 &&
            (request.sheetId === undefined
                ? args.cellsShareVersionColumn(request.existingIndex, singleAggregateCellIndex)
                : sharesSingleAggregateVersionColumn));
    let singleAggregateNumericValue;
    if (!shouldBatchColumnVersions && singleAggregateCellIndex >= 0) {
        args.writeFastPathLiteralToExistingCell(request.existingIndex, request.value);
        singleAggregateNumericValue = args.applyTerminalDirectFormulaNumericDeltaAndReturn(singleAggregateCellIndex, request.delta);
        if (singleAggregateNumericValue === undefined) {
            throw new Error('Failed to apply direct aggregate delta');
        }
    }
    else {
        args.withOptionalColumnVersionBatch(shouldBatchColumnVersions, () => {
            args.writeFastPathLiteralToExistingCell(request.existingIndex, request.value);
            if (singleAggregateCellIndex >= 0) {
                if (!args.applyDirectFormulaNumericDelta(singleAggregateCellIndex, request.delta)) {
                    throw new Error('Failed to apply direct aggregate delta');
                }
            }
            else {
                if (!args.applyDirectFormulaNumericDeltaBatch(affected, request.delta)) {
                    throw new Error('Failed to apply direct aggregate delta');
                }
            }
        });
    }
    args.state.counters.directAggregateDeltaApplications += affectedCount;
    args.state.counters.directAggregateDeltaOnlyRecalcSkips += 1;
    args.deferSingleCellKernelSync(request.existingIndex);
    const lastMetrics = args.makeSingleLiteralSkipMetrics();
    args.state.setLastMetrics(lastMetrics);
    if (request.emitTracked) {
        const changed = singleAggregateCellIndex >= 0
            ? Uint32Array.of(request.existingIndex, singleAggregateCellIndex)
            : affectedCount === 0
                ? Uint32Array.of(request.existingIndex)
                : composeSingleDisjointExplicitEventChanges(request.existingIndex, Uint32Array.from(affected));
        if (singleAggregateCellIndex >= 0 && changed.length > 4 && request.sheetId !== undefined) {
            tagTrustedPhysicalTrackedChanges(changed, request.sheetId, 1);
        }
        emitOperationTrackedCellsBatch({
            events: args.state.events,
            changedCellIndices: changed,
            metrics: lastMetrics,
        });
        return makeExistingNumericMutationResult(changed, 1);
    }
    if (singleAggregateCellIndex >= 0) {
        const cellStore = args.state.workbook.cellStore;
        return makeCompactExistingNumericMutationResult(request.existingIndex, singleAggregateCellIndex, 1, singleAggregateNumericValue, cellStore.rows[singleAggregateCellIndex] ?? 0, cellStore.cols[singleAggregateCellIndex] ?? 0);
    }
    if (affectedCount === 0) {
        return makeCompactExistingNumericMutationResult(request.existingIndex, undefined, 1);
    }
    const changed = composeSingleDisjointExplicitEventChanges(request.existingIndex, Uint32Array.from(affected));
    if (singleAggregateCellIndex >= 0 && changed.length > 4 && request.sheetId !== undefined) {
        tagTrustedPhysicalTrackedChanges(changed, request.sheetId, 1);
    }
    return makeExistingNumericMutationResult(changed, 1);
}
export function tryApplyTrustedSingleRangeDirectAggregateExistingNumericMutation(args, request) {
    if (request.hasExactLookupDependents || request.hasSortedLookupDependents) {
        return null;
    }
    const formulaCellIndex = args.getSingleEntityDependent(request.rangeEntityDependent);
    if (formulaCellIndex < 0 || !args.canApplyDirectAggregateLiteralDelta(formulaCellIndex)) {
        return null;
    }
    args.writeTrustedExistingNumericLiteralToCell(request.existingIndex, request.sheet, request.col, request.value);
    const aggregateNumericValue = args.applyTerminalDirectFormulaNumericDeltaAndReturn(formulaCellIndex, request.delta);
    if (aggregateNumericValue === undefined) {
        throw new Error('Failed to apply direct aggregate delta');
    }
    args.state.counters.directAggregateDeltaApplications += 1;
    args.state.counters.directAggregateDeltaOnlyRecalcSkips += 1;
    args.deferSingleCellKernelSync(request.existingIndex);
    args.state.setLastMetrics(args.makeSingleLiteralSkipMetrics());
    const cellStore = args.state.workbook.cellStore;
    return makeCompactExistingNumericMutationResult(request.existingIndex, formulaCellIndex, 1, aggregateNumericValue, cellStore.rows[formulaCellIndex] ?? 0, cellStore.cols[formulaCellIndex] ?? 0);
}
export function tryApplyTrustedColumnDirectAggregateExistingNumericMutation(args, request) {
    if (request.hasExactLookupDependents || request.hasSortedLookupDependents) {
        return null;
    }
    const formulaCellIndex = args.collectSingleApplicableDirectAggregateDependent({
        sheetName: request.sheetName,
        sheetId: request.sheetId,
        row: request.row,
        col: request.col,
    });
    if (formulaCellIndex < 0) {
        return null;
    }
    args.writeTrustedExistingNumericLiteralToCell(request.existingIndex, request.sheet, request.col, request.value);
    const aggregateNumericValue = args.applyTerminalDirectFormulaNumericDeltaAndReturn(formulaCellIndex, request.delta);
    if (aggregateNumericValue === undefined) {
        throw new Error('Failed to apply direct aggregate delta');
    }
    args.state.counters.directAggregateDeltaApplications += 1;
    args.state.counters.directAggregateDeltaOnlyRecalcSkips += 1;
    args.deferSingleCellKernelSync(request.existingIndex);
    args.state.setLastMetrics(args.makeSingleLiteralSkipMetrics());
    const cellStore = args.state.workbook.cellStore;
    return makeCompactExistingNumericMutationResult(request.existingIndex, formulaCellIndex, 1, aggregateNumericValue, cellStore.rows[formulaCellIndex] ?? 0, cellStore.cols[formulaCellIndex] ?? 0);
}
//# sourceMappingURL=operation-direct-aggregate-literal-fast-path.js.map