import { consumirSaldoNc, reponerSaldoNc } from './saldo-nc';

/** NC en memoria: saldo disponible (NULL = nunca tocada, vale su total) y subtotal. */
function txFalsa(nc: { rec_saldo_disponible: number | null; total: number }) {
  const estado = { ...nc };
  const tx = {
    nota_credito_cab: {
      findUnique: async () => ({ id: 'nc1', rec_saldo_disponible: estado.rec_saldo_disponible }),
      update: async ({ data }: any) => {
        estado.rec_saldo_disponible = Number(data.rec_saldo_disponible);
        return data;
      },
    },
    nota_credito_subtotal: {
      aggregate: async () => ({ _sum: { dtotgralope: estado.total } }),
    },
  };
  return { tx, estado };
}

describe('consumirSaldoNc', () => {
  it('descuenta lo aplicado en el recibo del total cuando la NC nunca se tocó (NULL)', async () => {
    const { tx, estado } = txFalsa({ rec_saldo_disponible: null, total: 1000 });
    expect(await consumirSaldoNc(tx as any, 'nc1', 300)).toBe(700);
    expect(estado.rec_saldo_disponible).toBe(700);
  });

  it('descuenta del saldo ya reducido, no del total', async () => {
    const { tx, estado } = txFalsa({ rec_saldo_disponible: 200, total: 1000 });
    await consumirSaldoNc(tx as any, 'nc1', 200);
    expect(estado.rec_saldo_disponible).toBe(0);
  });

  it('no deja saldo negativo por redondeo', async () => {
    const { tx, estado } = txFalsa({ rec_saldo_disponible: 100, total: 1000 });
    await consumirSaldoNc(tx as any, 'nc1', 100.004);
    expect(estado.rec_saldo_disponible).toBe(0);
  });
});

describe('reponerSaldoNc', () => {
  it('devuelve lo aplicado al anular el recibo', async () => {
    const { tx, estado } = txFalsa({ rec_saldo_disponible: 700, total: 1000 });
    expect(await reponerSaldoNc(tx as any, 'nc1', 300)).toBe(1000);
    expect(estado.rec_saldo_disponible).toBe(1000);
  });

  it('nunca repone por encima del total de la NC', async () => {
    // Datos viejos: NC consumida en un recibo cuando todavía no se descontaba
    // el saldo (quedó en NULL = total). Al anular ese recibo no hay nada que reponer.
    const { tx, estado } = txFalsa({ rec_saldo_disponible: null, total: 1000 });
    expect(await reponerSaldoNc(tx as any, 'nc1', 300)).toBe(1000);
    expect(estado.rec_saldo_disponible).toBe(1000);
  });
});
