import { calcularEstadoCuenta, CuotaEstado } from './estado-cuenta';

const cuota = (p: Partial<CuotaEstado>): CuotaEstado => ({
  id: `c${p.nro}`,
  nro: 1,
  tipo: 'CUOTA',
  descripcion: null,
  fecha_vencimiento: null,
  hito_id: null,
  monto: 1000,
  monto_cobrado: 0,
  estado: 'PENDIENTE',
  ...p,
});

describe('calcularEstadoCuenta', () => {
  const base = {
    hoy: '2026-12-31',
    hitosCumplidos: new Map<string, string>(),
    tasaMoraMensual: 3,
    decimales: 2,
    precio: 4000,
  };

  it('vencido, días de atraso, mora y porcentaje pagado', () => {
    const ec = calcularEstadoCuenta(
      [
        cuota({ nro: 1, tipo: 'SENA', fecha_vencimiento: '2026-10-01', monto_cobrado: 1000, estado: 'PAGADA' }),
        cuota({ nro: 2, fecha_vencimiento: '2026-12-01', monto_cobrado: 400, estado: 'PARCIAL' }),
        cuota({ nro: 3, fecha_vencimiento: '2027-01-01' }),
        cuota({ nro: 4, tipo: 'POSESION' }),
      ],
      base,
    );
    expect(ec.resumen).toEqual(
      expect.objectContaining({
        cobrado: 1400,
        saldo: 2600,
        pct_pagado: 35,
        vencido: 600,
        cuotas_vencidas: 1,
        dias_atraso_max: 30,
      }),
    );
    // 600 × 3 % / 30 × 30 días
    expect(ec.resumen.mora_estimada).toBe(18);
    expect(ec.resumen.proxima).toEqual(expect.objectContaining({ nro: 3, fecha: '2027-01-01' }));
    expect(ec.cuotas[3]).toEqual(expect.objectContaining({ vencida: false, exigible_desde: null }));
  });

  it('la cuota contra hito vence cuando el hito se cumple', () => {
    const c = [cuota({ nro: 1, tipo: 'HITO', hito_id: 'h1' })];
    expect(calcularEstadoCuenta(c, base).resumen.vencido).toBe(0);
    const ec = calcularEstadoCuenta(c, { ...base, hitosCumplidos: new Map([['h1', '2026-12-21']]) });
    expect(ec.cuotas[0]).toEqual(
      expect.objectContaining({ vencida: true, dias_atraso: 10, exigible_desde: '2026-12-21' }),
    );
  });

  it('las anuladas no cuentan como vencidas', () => {
    const ec = calcularEstadoCuenta([cuota({ nro: 1, estado: 'ANULADA', fecha_vencimiento: '2026-01-01' })], base);
    expect(ec.cuotas).toHaveLength(0);
    expect(ec.resumen.vencido).toBe(0);
  });

  it('antes del boleto sólo existe la seña, pero el saldo es todo el precio', () => {
    const ec = calcularEstadoCuenta(
      [
        cuota({
          nro: 1,
          tipo: 'SENA',
          monto: 400,
          monto_cobrado: 400,
          estado: 'PAGADA',
          fecha_vencimiento: '2026-12-01',
        }),
      ],
      base,
    );
    expect(ec.resumen).toEqual(expect.objectContaining({ cobrado: 400, saldo: 3600, pct_pagado: 10 }));
  });
});
