import { formatAddress } from '@bilig/formula';
import { emptyValue, literalToValue, writeLiteralToCellStore } from '../../engine-value-utils.js';
import { withOptionalLookupStringIds } from './direct-lookup-helpers.js';
import { applyTableHeaderRenameForSetCellValue, isWorkbookTableHeaderCell } from './operation-table-header-rename.js';
export function applyClearCellMutation(request) {
    const args = request.serviceArgs;
    const { existingIndex, isRestore, mutation, sheetId } = request;
    const { hasAggregateDependents, hasExactLookupDependents, hasSortedLookupDependents, needsLookupValueRead } = request.dependencyFlags;
    const prior = request.readCellValueForLookup(existingIndex);
    let changedInputCount = request.changedInputCount;
    let formulaChangedCount = request.formulaChangedCount;
    let explicitChangedCount = request.explicitChangedCount;
    let topologyChanged = request.topologyChanged;
    let headerClearValue;
    const sheetName = request.resolveSheetName(sheetId);
    if (!isRestore && isWorkbookTableHeaderCell(args.state.workbook, sheetName, mutation.row, mutation.col)) {
        const renamed = applyTableHeaderRenameForSetCellValue({
            serviceArgs: args,
            sheetName,
            row: mutation.row,
            col: mutation.col,
            value: null,
            formulaChangedCount,
            topologyChanged,
        });
        formulaChangedCount = renamed.formulaChangedCount;
        topologyChanged = renamed.topologyChanged;
        headerClearValue = String(renamed.value ?? '');
    }
    const markReplicaVersion = () => {
        if (!isRestore && args.state.trackReplicaVersions) {
            request.setCellEntityVersion(sheetName, formatAddress(mutation.row, mutation.col), request.order);
        }
    };
    const nextCellValue = () => headerClearValue === undefined ? emptyValue() : literalToValue(headerClearValue, args.state.strings);
    const writeNextCellValue = (cellIndex) => {
        if (headerClearValue === undefined) {
            args.state.workbook.cellStore.setValue(cellIndex, emptyValue());
            return;
        }
        writeLiteralToCellStore(args.state.workbook.cellStore, cellIndex, headerClearValue, args.state.strings);
    };
    const markDirectDependents = (cellIndex) => {
        if (isRestore) {
            return;
        }
        const nextValue = nextCellValue();
        const directDependentsHandled = request.markPostRecalcDirectFormulaDependents(cellIndex, request.postRecalcDirectFormulaIndices, prior.value, nextValue);
        if (!directDependentsHandled) {
            request.markDirectScalarDeltaClosure(cellIndex, prior.value, nextValue, request.postRecalcDirectFormulaIndices);
        }
    };
    const markLookupAndAggregateDependents = (cellIndex) => {
        if (!needsLookupValueRead) {
            return;
        }
        const nextValue = nextCellValue();
        const newStringId = headerClearValue === undefined ? undefined : args.state.workbook.cellStore.stringIds[cellIndex];
        if (hasExactLookupDependents || hasAggregateDependents) {
            const exactLookupRequest = withOptionalLookupStringIds({
                sheetName,
                row: mutation.row,
                col: mutation.col,
                oldValue: prior.value,
                newValue: nextValue,
                oldStringId: prior.stringId,
                newStringId,
                inputCellIndex: cellIndex,
            });
            if (hasExactLookupDependents) {
                formulaChangedCount = request.noteExactLookupLiteralWriteWhenDirty(exactLookupRequest, formulaChangedCount, request.exactLookupImpactCaches);
            }
            if (hasAggregateDependents) {
                args.noteAggregateLiteralWrite({
                    sheetName: exactLookupRequest.sheetName,
                    row: exactLookupRequest.row,
                    col: exactLookupRequest.col,
                    oldValue: exactLookupRequest.oldValue,
                    newValue: exactLookupRequest.newValue,
                });
                formulaChangedCount = request.markAffectedDirectRangeDependents(exactLookupRequest, formulaChangedCount, request.postRecalcDirectFormulaIndices);
            }
        }
        if (hasSortedLookupDependents) {
            const sortedLookupRequest = withOptionalLookupStringIds({
                sheetName,
                row: mutation.row,
                col: mutation.col,
                oldValue: prior.value,
                newValue: nextValue,
                oldStringId: prior.stringId,
                newStringId,
            });
            formulaChangedCount = request.noteSortedLookupLiteralWriteWhenDirty(sortedLookupRequest, formulaChangedCount);
        }
    };
    const markChanged = (cellIndex) => {
        changedInputCount = args.markInputChanged(cellIndex, changedInputCount);
        if (request.trackExplicitChanges) {
            explicitChangedCount = args.markExplicitChanged(cellIndex, explicitChangedCount);
        }
    };
    const rebindValueSensitiveDependents = (cellIndex) => {
        const rebound = request.rebindValueSensitiveFormulaDependents(cellIndex, {
            changedInputCount,
            formulaChangedCount,
            explicitChangedCount,
            topologyChanged,
        });
        changedInputCount = rebound.changedInputCount;
        formulaChangedCount = rebound.formulaChangedCount;
        explicitChangedCount = rebound.explicitChangedCount;
        topologyChanged = rebound.topologyChanged;
    };
    if (existingIndex !== undefined && headerClearValue === undefined && request.isClearCellNoOp(existingIndex)) {
        return { changedInputCount, formulaChangedCount, explicitChangedCount, topologyChanged };
    }
    if (existingIndex !== undefined && request.canFastPathLiteralOverwrite(existingIndex)) {
        writeNextCellValue(existingIndex);
        args.state.workbook.notifyCellValueWritten(existingIndex);
        if (!isRestore) {
            rebindValueSensitiveDependents(existingIndex);
        }
        markDirectDependents(existingIndex);
        markLookupAndAggregateDependents(existingIndex);
        markChanged(existingIndex);
        markReplicaVersion();
        return { changedInputCount, formulaChangedCount, explicitChangedCount, topologyChanged };
    }
    if (existingIndex === undefined) {
        if (headerClearValue !== undefined) {
            const cellIndex = args.state.workbook.ensureCellAt(sheetId, mutation.row, mutation.col).cellIndex;
            writeNextCellValue(cellIndex);
            args.state.workbook.notifyCellValueWritten(cellIndex);
            if (!isRestore) {
                rebindValueSensitiveDependents(cellIndex);
            }
            markDirectDependents(cellIndex);
            markLookupAndAggregateDependents(cellIndex);
            markChanged(cellIndex);
        }
        markReplicaVersion();
        return { changedInputCount, formulaChangedCount, explicitChangedCount, topologyChanged };
    }
    changedInputCount = args.markPivotRootsChanged(args.clearPivotForCell(existingIndex), changedInputCount);
    const clearedSpill = args.clearSpillForCell(existingIndex);
    changedInputCount = args.markSpillRootsChanged(clearedSpill.changedCellIndices, changedInputCount);
    if (clearedSpill.ownerCellIndex !== undefined) {
        formulaChangedCount = args.markFormulaChanged(clearedSpill.ownerCellIndex, formulaChangedCount);
    }
    const removedFormula = args.removeFormula(existingIndex);
    topologyChanged = removedFormula || topologyChanged;
    if (removedFormula) {
        args.invalidateAggregateColumn({ sheetName, col: mutation.col });
        request.clearTrackedColumnDependencyFlagCache();
    }
    writeNextCellValue(existingIndex);
    args.state.workbook.notifyCellValueWritten(existingIndex);
    if (!isRestore) {
        rebindValueSensitiveDependents(existingIndex);
    }
    markDirectDependents(existingIndex);
    markLookupAndAggregateDependents(existingIndex);
    args.state.workbook.cellStore.flags[existingIndex] =
        (args.state.workbook.cellStore.flags[existingIndex] ?? 0) &
            ~(2 /* CellFlags.HasFormula */ | 4 /* CellFlags.JsOnly */ | 8 /* CellFlags.InCycle */ | 64 /* CellFlags.SpillChild */ | 128 /* CellFlags.PivotOutput */);
    if (headerClearValue === undefined) {
        args.state.workbook.cellStore.flags[existingIndex] &= ~256 /* CellFlags.AuthoredBlank */;
    }
    request.normalizeHistoryDependencyPlaceholder(existingIndex, request.source);
    if (!isRestore && headerClearValue === undefined) {
        request.pruneCellIfOrphaned(existingIndex);
    }
    markChanged(existingIndex);
    markReplicaVersion();
    return { changedInputCount, formulaChangedCount, explicitChangedCount, topologyChanged };
}
//# sourceMappingURL=operation-clear-cell-mutation.js.map