export function makeCellKey(sheetKey, row, col) {
    return `${sheetKey}:${row}:${col}`;
}

export function parseA1Notation(a1) {
    const match = a1.match(/^([A-Z]+)([0-9]+)$/i);
    if (!match) return null;
    const letters = match[1].toUpperCase(), rowNumber = parseInt(match[2], 10);
    if (!rowNumber || rowNumber < 1) return null;
    let col = 0;
    for (let i = 0; i < letters.length; i++) col = 26 * col + (letters.charCodeAt(i) - 64);
    return {
        row: rowNumber - 1,
        col: col - 1
    };
}

export function captureCellPreChangeContent(args) {
    const {sheetKey: sheetKey, row: row, col: col, currentValue: currentValue, formulaManager: formulaManager, store: store} = args;
    if (!sheetKey) return;
    const cellKey = makeCellKey(sheetKey, row, col);
    if (null == formulaManager ? void 0 : formulaManager.getCellFormula) try {
        const oldFormula = formulaManager.getCellFormula({
            sheet: sheetKey,
            row: row,
            col: col
        });
        if (oldFormula) {
            const normalized = "string" != typeof oldFormula || oldFormula.startsWith("=") ? oldFormula : `=${oldFormula}`;
            return void store.set(cellKey, normalized);
        }
    } catch (_a) {}
    store.set(cellKey, null == currentValue ? "" : currentValue);
}

export function popCellPreChangeContent(args) {
    const {sheetKey: sheetKey, row: row, col: col, fallbackOldContent: fallbackOldContent, store: store} = args;
    if (!sheetKey) return fallbackOldContent;
    const cellKey = makeCellKey(sheetKey, row, col), oldContent = store.get(cellKey);
    return store.delete(cellKey), void 0 !== oldContent ? oldContent : fallbackOldContent;
}

export function applyCellContent(args) {
    const {table: table, sheetKey: sheetKey, row: row, col: col, content: content, formulaManager: formulaManager} = args;
    if (sheetKey && (null == formulaManager ? void 0 : formulaManager.setCellContent) && (null == formulaManager ? void 0 : formulaManager.getCellValue)) {
        try {
            formulaManager.setCellContent({
                sheet: sheetKey,
                row: row,
                col: col
            }, content);
        } catch (_a) {
            return void table.changeCellValue(col, row, content, !1, !1, !0);
        }
        if ("string" == typeof content && content.startsWith("=")) {
            const result = formulaManager.getCellValue({
                sheet: sheetKey,
                row: row,
                col: col
            }), display = (null == result ? void 0 : result.error) ? "#ERROR!" : null == result ? void 0 : result.value;
            return table.changeCellValue(col, row, display, !1, !1, !0), void refreshDependentDisplays({
                table: table,
                sheetKey: sheetKey,
                startCell: {
                    sheet: sheetKey,
                    row: row,
                    col: col
                },
                formulaManager: formulaManager
            });
        }
        return table.changeCellValue(col, row, content, !1, !1, !0), void refreshDependentDisplays({
            table: table,
            sheetKey: sheetKey,
            startCell: {
                sheet: sheetKey,
                row: row,
                col: col
            },
            formulaManager: formulaManager
        });
    }
    table.changeCellValue(col, row, content, !1, !1, !0);
}

export function refreshDependentDisplays(args) {
    var _a;
    const {table: table, sheetKey: sheetKey, startCell: startCell, formulaManager: formulaManager} = args, maxCells = null !== (_a = args.maxCells) && void 0 !== _a ? _a : 5e3;
    if (!(null == formulaManager ? void 0 : formulaManager.getCellDependents) || !(null == formulaManager ? void 0 : formulaManager.getCellValue)) return;
    const visited = new Set, queue = [ ...formulaManager.getCellDependents(startCell) || [] ];
    let processed = 0;
    for (;queue.length; ) {
        const cell = queue.shift();
        if (!cell || cell.sheet !== sheetKey) continue;
        const key = makeCellKey(cell.sheet, cell.row, cell.col);
        if (visited.has(key)) continue;
        if (visited.add(key), processed++, processed > maxCells) break;
        const result = formulaManager.getCellValue(cell), display = (null == result ? void 0 : result.error) ? "#ERROR!" : null == result ? void 0 : result.value;
        table.changeCellValue(cell.col, cell.row, display, !1, !1, !0);
        (formulaManager.getCellDependents(cell) || []).forEach((d => queue.push(d)));
    }
}
//# sourceMappingURL=formula.js.map