import { ValueTag } from '@bilig/protocol';
import { entityPayload, isRangeEntity, makeCellEntity } from '../../entity-ids.js';
import { addEngineCounter } from '../../perf/engine-counters.js';
export function pruneOperationCellIfOrphaned(input) {
    if (input.collectFormulaDependents(makeCellEntity(input.cellIndex)).length > 0) {
        return;
    }
    input.workbook.pruneCellIfEmpty(input.cellIndex);
}
export function normalizeOperationHistoryDependencyPlaceholder(input) {
    if (input.source !== 'undo' && input.source !== 'restore') {
        return;
    }
    if (input.state.workbook.getCellFormat(input.cellIndex) !== undefined) {
        return;
    }
    const flags = input.state.workbook.cellStore.flags[input.cellIndex] ?? 0;
    if ((flags &
        (2 /* CellFlags.HasFormula */ |
            4 /* CellFlags.JsOnly */ |
            8 /* CellFlags.InCycle */ |
            64 /* CellFlags.SpillChild */ |
            128 /* CellFlags.PivotOutput */ |
            32 /* CellFlags.PendingDelete */)) !==
        0) {
        return;
    }
    const value = input.state.workbook.cellStore.getValue(input.cellIndex, (id) => input.state.strings.get(id));
    if (value.tag !== ValueTag.Empty) {
        return;
    }
    if (input.collectFormulaDependents(makeCellEntity(input.cellIndex)).length === 0) {
        return;
    }
    input.state.workbook.cellStore.versions[input.cellIndex] = 0;
}
export function markOperationCycleMemberInputsChanged(input) {
    let changedInputCount = input.changedInputCount;
    input.formulas.forEach((_formula, cellIndex) => {
        if (((input.cellStore.flags[cellIndex] ?? 0) & 8 /* CellFlags.InCycle */) === 0) {
            return;
        }
        changedInputCount = input.markInputChanged(cellIndex, changedInputCount);
    });
    return changedInputCount;
}
export function hasOperationCycleMembers(input) {
    addEngineCounter(input.counters, 'cycleFormulaScans');
    let found = false;
    input.formulas.forEach((_formula, cellIndex) => {
        if (((input.cellStore.flags[cellIndex] ?? 0) & 8 /* CellFlags.InCycle */) !== 0) {
            found = true;
        }
    });
    return found;
}
export function hasOperationCompactedRangeDependencies(formula) {
    if (formula.rangeDependencies.length === 0) {
        return false;
    }
    if (formula.graphRangeDependencies.length === 0) {
        return true;
    }
    const graphRanges = new Set();
    for (let index = 0; index < formula.graphRangeDependencies.length; index += 1) {
        graphRanges.add(formula.graphRangeDependencies[index]);
    }
    for (let index = 0; index < formula.rangeDependencies.length; index += 1) {
        if (!graphRanges.has(formula.rangeDependencies[index])) {
            return true;
        }
    }
    return false;
}
export function collectOperationDynamicFormulaDependents(input) {
    const dependents = input.collectFormulaDependents(makeCellEntity(input.cellIndex));
    const dynamicDependents = [];
    for (let index = 0; index < dependents.length; index += 1) {
        const formulaCellIndex = dependents[index];
        if (formulaCellIndex === input.cellIndex) {
            continue;
        }
        const formula = input.formulas.get(formulaCellIndex);
        if (formula && hasOperationCompactedRangeDependencies(formula)) {
            dynamicDependents.push(formulaCellIndex);
        }
    }
    return dynamicDependents;
}
export function rebindOperationDynamicFormulaDependents(input) {
    const dynamicDependents = collectOperationDynamicFormulaDependents(input);
    return dynamicDependents.length === 0 ? input.formulaChangedCount : input.rebindFormulaCells(dynamicDependents, input.formulaChangedCount);
}
export function refreshDependentRangesAndRebindOperationFormulaDependents(input) {
    const directDependents = input.getEntityDependents(makeCellEntity(input.cellIndex));
    const rangeIndices = [];
    for (let index = 0; index < directDependents.length; index += 1) {
        const dependent = directDependents[index];
        if (isRangeEntity(dependent)) {
            rangeIndices.push(entityPayload(dependent));
        }
    }
    if (rangeIndices.length > 0) {
        input.refreshRangeDependencies(rangeIndices);
    }
    const formulas = Array.from(input.collectFormulaDependents(makeCellEntity(input.cellIndex))).filter((candidate) => candidate !== input.cellIndex);
    if (formulas.length === 0) {
        return input.formulaChangedCount;
    }
    return input.rebindFormulaCells(formulas, input.formulaChangedCount);
}
//# sourceMappingURL=operation-cell-lifecycle-helpers.js.map