import { parseArithmeticScalarText } from '@bilig/formula';
import { ErrorCode, ValueTag } from '@bilig/protocol';
import { directErrorResult, directNumberResult } from './formula-evaluation-helpers.js';
function readDirectScalarOperand(operand, readCellValueByIndex) {
    if (operand.kind === 'literal-number') {
        return { tag: ValueTag.Number, value: operand.value };
    }
    if (operand.kind === 'error') {
        return directErrorResult(operand.code);
    }
    return readCellValueByIndex(operand.cellIndex);
}
function coerceDirectScalarNumeric(value, dateSystem) {
    if (!value) {
        return undefined;
    }
    switch (value.tag) {
        case ValueTag.Number:
            return { kind: 'number', value: value.value };
        case ValueTag.Boolean:
            return { kind: 'number', value: value.value ? 1 : 0 };
        case ValueTag.Empty:
            return { kind: 'number', value: 0 };
        case ValueTag.Error:
            return { kind: 'error', code: value.code };
        case ValueTag.String: {
            const numeric = parseArithmeticScalarText(value.value, dateSystem);
            return numeric === undefined ? { kind: 'error', code: ErrorCode.Value } : { kind: 'number', value: numeric };
        }
        default:
            return undefined;
    }
}
export function tryEvaluateDirectScalar(formula, readCellValueByIndex, dateSystem = '1900') {
    const directScalar = formula.directScalar;
    if (!directScalar) {
        return undefined;
    }
    if (directScalar.kind === 'abs') {
        const operand = coerceDirectScalarNumeric(readDirectScalarOperand(directScalar.operand, readCellValueByIndex), dateSystem);
        if (operand === undefined) {
            return undefined;
        }
        if (operand.kind === 'error') {
            return directErrorResult(operand.code);
        }
        return directNumberResult(Math.abs(operand.value));
    }
    const left = coerceDirectScalarNumeric(readDirectScalarOperand(directScalar.left, readCellValueByIndex), dateSystem);
    const right = coerceDirectScalarNumeric(readDirectScalarOperand(directScalar.right, readCellValueByIndex), dateSystem);
    if (left === undefined || right === undefined) {
        return undefined;
    }
    if (left.kind === 'error') {
        return directErrorResult(left.code);
    }
    if (right.kind === 'error') {
        return directErrorResult(right.code);
    }
    let result;
    switch (directScalar.operator) {
        case '+':
            result = left.value + right.value;
            break;
        case '-':
            result = left.value - right.value;
            break;
        case '*':
            result = left.value * right.value;
            break;
        case '/':
            if (right.value === 0) {
                return directErrorResult(ErrorCode.Div0);
            }
            result = left.value / right.value;
            break;
    }
    return directNumberResult(result + (directScalar.resultOffset ?? 0));
}
//# sourceMappingURL=formula-evaluation-direct-scalar.js.map