// register_cash_move
// Pure transition. Receives `input` as { states, ids, params }; returns
// an array of FieldOp objects. No clock, no random, no IO.
//
// states.caja: the current Caja record loaded from the store.
// ids.caja:    the Caja's UUID (string form).
// params:      { monto:i64, tipo:"in"|"out", timestamp:str, memo:str, movimiento_id:str }

let saldo = input.states.caja.saldo;
let monto = input.params.monto;
let tipo  = input.params.tipo;
let caja_id = input.ids.caja;

let nuevo_saldo = if tipo == "in" {
    saldo + monto
} else if tipo == "out" {
    saldo - monto
} else {
    throw "tipo desconocido: " + tipo
};

let mov_id = input.params.movimiento_id;
if type_of(mov_id) == "()" {
    throw "params.movimiento_id es obligatorio (idempotencia)"
}

[
    #{
        op: "set",
        path: #{ entity: "Caja", id: caja_id, field: "saldo" },
        value: nuevo_saldo,
    },
    #{
        op: "create",
        entity: "Movimiento",
        id: mov_id,
        data: #{
            id: mov_id,
            caja_id: caja_id,
            monto: monto,
            tipo: tipo,
            timestamp: input.params.timestamp,
            memo: input.params.memo,
        },
    },
]
