import { registerDeferredFormulaFamilyIndexRunsNow } from './formula-initialization-family-runs.js';
import { queueDeferredFormulaFamilyStructuralSourceTransforms } from './formula-binding-deferred-family-transforms.js';
export function createFormulaBindingFamilyIndexController(args) {
    let needsRebuild = false;
    let deferredRuns;
    let deferredStructuralSourceTransforms;
    const clearNow = () => {
        args.formulaFamilyShapeKeyCache.clear();
        deferredRuns = undefined;
        deferredStructuralSourceTransforms = undefined;
        needsRebuild = false;
    };
    const registerFormulaFamilyNow = (cellIndex, formula, ownerPosition) => {
        if (needsRebuild) {
            deferredRuns = undefined;
            deferredStructuralSourceTransforms = undefined;
            return;
        }
        args.registerFormulaFamilyInStoreNow(cellIndex, formula, ownerPosition);
    };
    const invalidateDeferredRunsForExternalRegistration = () => {
        args.formulaFamilyShapeKeyCache.clear();
        deferredRuns = undefined;
        deferredStructuralSourceTransforms = undefined;
        needsRebuild = true;
    };
    const registerFreshFormulaFamilyRunNow = (run) => {
        if (needsRebuild) {
            invalidateDeferredRunsForExternalRegistration();
            return true;
        }
        return args.formulaFamilies.registerFreshUniformRun(run);
    };
    const upsertFormulaFamilyRunNow = (run) => {
        if (needsRebuild) {
            invalidateDeferredRunsForExternalRegistration();
            return;
        }
        args.formulaFamilies.registerFormulaRun(run);
    };
    const ensureNow = () => {
        if (!needsRebuild) {
            return;
        }
        if (deferredRuns) {
            registerDeferredFormulaFamilyIndexRunsNow({
                formulaFamilies: args.formulaFamilies,
                formulaFamilyShapeKeyCache: args.formulaFamilyShapeKeyCache,
                runs: deferredRuns,
                ...(deferredStructuralSourceTransforms === undefined ? {} : { structuralSourceTransforms: deferredStructuralSourceTransforms }),
            });
            deferredRuns = undefined;
            deferredStructuralSourceTransforms = undefined;
        }
        else {
            args.rebuildFormulaFamilyIndexNow();
            deferredStructuralSourceTransforms = undefined;
        }
        needsRebuild = false;
    };
    const deferRebuildNow = () => {
        args.formulaFamilyShapeKeyCache.clear();
        deferredRuns = undefined;
        deferredStructuralSourceTransforms = undefined;
        needsRebuild = true;
    };
    const deferRunsNow = (runs) => {
        args.formulaFamilyShapeKeyCache.clear();
        deferredRuns = deferredRuns === undefined ? [...runs] : [...deferredRuns, ...runs];
        deferredStructuralSourceTransforms = undefined;
        needsRebuild = true;
    };
    const tryDeferStructuralSourceTransformsNow = (sheetId, transform, canDeferCellIndex) => {
        if (!needsRebuild) {
            return undefined;
        }
        const result = queueDeferredFormulaFamilyStructuralSourceTransforms({
            runs: deferredRuns,
            existingTransforms: deferredStructuralSourceTransforms,
            sheetId,
            transform,
            ownedFormulaCount: args.countFormulaSheetMembersNow(sheetId),
            canDeferCellIndex,
        });
        if (result === undefined) {
            return undefined;
        }
        deferredStructuralSourceTransforms = result.transforms;
        return result.memberCount;
    };
    const getStructuralSourceTransformNow = (cellIndex) => {
        if (needsRebuild &&
            deferredRuns !== undefined &&
            !args.formulaFamilies.hasStructuralSourceTransforms() &&
            deferredStructuralSourceTransforms === undefined) {
            return undefined;
        }
        ensureNow();
        return args.formulaFamilies.getStructuralSourceTransform(cellIndex);
    };
    const peekDeferredStructuralSourceTransformsNow = () => {
        if (!needsRebuild || deferredRuns === undefined || deferredStructuralSourceTransforms === undefined) {
            return args.formulaFamilies.peekStructuralSourceTransforms();
        }
        const entries = [];
        deferredStructuralSourceTransforms.forEach((transform, runIndex) => {
            const run = deferredRuns?.[runIndex];
            if (!run) {
                return;
            }
            entries.push({ cellIndices: run.cellIndices, transform });
        });
        return entries;
    };
    return {
        clearNow,
        registerFormulaFamilyNow,
        registerFreshFormulaFamilyRunNow,
        upsertFormulaFamilyRunNow,
        ensureNow,
        deferRebuildNow,
        deferRunsNow,
        canUseNow: () => !needsRebuild || deferredRuns !== undefined,
        isReadyNow: () => !needsRebuild,
        countSheetMembersNow(sheetId) {
            ensureNow();
            return args.formulaFamilies.countSheetMembers(sheetId);
        },
        tryDeferStructuralSourceTransformsNow,
        forEachFamilyNow(fn) {
            ensureNow();
            args.formulaFamilies.forEachFamily(fn);
        },
        setStructuralSourceTransformNow(familyId, transform) {
            ensureNow();
            args.formulaFamilies.setStructuralSourceTransform(familyId, transform);
        },
        getStructuralSourceTransformNow,
        hasStructuralSourceTransformsNow() {
            return (args.formulaFamilies.hasStructuralSourceTransforms() ||
                (deferredStructuralSourceTransforms !== undefined && deferredStructuralSourceTransforms.size > 0));
        },
        peekStructuralSourceTransformsNow: peekDeferredStructuralSourceTransformsNow,
        consumeStructuralSourceTransformsNow() {
            ensureNow();
            return args.formulaFamilies.consumeStructuralSourceTransforms();
        },
    };
}
//# sourceMappingURL=formula-binding-family-index-controller.js.map