import { ErrorCode, ValueTag } from '@bilig/protocol';
import { createWrittenColumnTracker, markWrittenColumn, materializeWrittenColumns, } from '../../written-column-tracker.js';
export function createInitialFormulaValueWriter(args) {
    let singleSheetId;
    let singleSheetTracker;
    let writtenColumnsBySheetId;
    const promoteSingleSheetTracker = () => {
        writtenColumnsBySheetId = new Map();
        if (singleSheetId !== undefined && singleSheetTracker !== undefined) {
            writtenColumnsBySheetId.set(singleSheetId, singleSheetTracker);
        }
        singleSheetId = undefined;
        singleSheetTracker = undefined;
        return writtenColumnsBySheetId;
    };
    const markKnownColumn = (sheetId, col) => {
        if (!writtenColumnsBySheetId && (singleSheetId === undefined || singleSheetId === sheetId)) {
            singleSheetId = sheetId;
            singleSheetTracker ??= createWrittenColumnTracker();
            markWrittenColumn(singleSheetTracker, col);
            return;
        }
        const trackers = writtenColumnsBySheetId ?? promoteSingleSheetTracker();
        let tracker = trackers.get(sheetId);
        if (!tracker) {
            tracker = createWrittenColumnTracker();
            trackers.set(sheetId, tracker);
        }
        markWrittenColumn(tracker, col);
    };
    const markCellColumn = (cellIndex) => {
        const sheetId = args.state.workbook.cellStore.sheetIds[cellIndex];
        const col = args.state.workbook.cellStore.cols[cellIndex];
        if (sheetId === undefined || col === undefined) {
            return;
        }
        markKnownColumn(sheetId, col);
    };
    const clearDerivedFlags = (cellIndex) => {
        args.state.workbook.cellStore.flags[cellIndex] =
            (args.state.workbook.cellStore.flags[cellIndex] ?? 0) & ~(64 /* CellFlags.SpillChild */ | 128 /* CellFlags.PivotOutput */);
    };
    const writeNumberCore = (cellIndex, value) => {
        const cellStore = args.state.workbook.cellStore;
        clearDerivedFlags(cellIndex);
        cellStore.tags[cellIndex] = ValueTag.Number;
        cellStore.errors[cellIndex] = ErrorCode.None;
        cellStore.stringIds[cellIndex] = 0;
        cellStore.numbers[cellIndex] = value;
        cellStore.versions[cellIndex] = (cellStore.versions[cellIndex] ?? 0) + 1;
    };
    const writeValueCore = (cellIndex, value) => {
        const cellStore = args.state.workbook.cellStore;
        clearDerivedFlags(cellIndex);
        cellStore.tags[cellIndex] = value.tag;
        cellStore.errors[cellIndex] = value.tag === ValueTag.Error ? value.code : ErrorCode.None;
        cellStore.stringIds[cellIndex] = value.tag === ValueTag.String ? args.state.strings.intern(value.value) : 0;
        cellStore.numbers[cellIndex] = value.tag === ValueTag.Number ? value.value : value.tag === ValueTag.Boolean ? (value.value ? 1 : 0) : 0;
        cellStore.versions[cellIndex] = (cellStore.versions[cellIndex] ?? 0) + 1;
    };
    return {
        writeValue(cellIndex, value) {
            writeValueCore(cellIndex, value);
            markCellColumn(cellIndex);
        },
        writeValueAt(cellIndex, sheetId, col, value) {
            writeValueCore(cellIndex, value);
            markKnownColumn(sheetId, col);
        },
        writeNumber(cellIndex, value) {
            writeNumberCore(cellIndex, value);
            markCellColumn(cellIndex);
        },
        writeNumberAt(cellIndex, sheetId, col, value) {
            writeNumberCore(cellIndex, value);
            markKnownColumn(sheetId, col);
        },
        flush() {
            if (!writtenColumnsBySheetId) {
                if (singleSheetId !== undefined && singleSheetTracker !== undefined && singleSheetTracker.count > 0) {
                    args.state.workbook.notifyColumnsWritten(singleSheetId, materializeWrittenColumns(singleSheetTracker));
                }
                return;
            }
            writtenColumnsBySheetId.forEach((tracker, sheetId) => {
                if (tracker.count > 0) {
                    args.state.workbook.notifyColumnsWritten(sheetId, materializeWrittenColumns(tracker));
                }
            });
        },
    };
}
//# sourceMappingURL=formula-initialization-value-writer.js.map