import {
  calcularRiesgo,
  conservarHasta,
  detectarFraccionamiento,
  faltantesParaAprobar,
  riesgoFinal,
  vigenciaLegajo,
} from './cumplimiento-reglas';

const base = {
  tipo_persona: 'FISICA' as const,
  actividad: 'Médico',
  origen_fondos: 'Honorarios',
  pep: false,
  beneficiarios_finales: [],
};
const sinAntecedentes = { inusuales_reportadas: 0, inusuales_abiertas: 0 };

describe('cumplimiento — reglas', () => {
  it('riesgo: PEP o beneficiario PEP es alto; jurídica, medio; persona común, bajo', () => {
    expect(calcularRiesgo(base, sinAntecedentes)).toBe('BAJO');
    expect(calcularRiesgo({ ...base, pep: true }, sinAntecedentes)).toBe('ALTO');
    expect(
      calcularRiesgo(
        { ...base, tipo_persona: 'JURIDICA', beneficiarios_finales: [{ nombre: 'X', pct: 50, pep: true }] },
        sinAntecedentes,
      ),
    ).toBe('ALTO');
    expect(calcularRiesgo({ ...base, tipo_persona: 'JURIDICA' }, sinAntecedentes)).toBe('MEDIO');
    expect(calcularRiesgo(base, { inusuales_reportadas: 1, inusuales_abiertas: 0 })).toBe('ALTO');
    expect(calcularRiesgo(base, { inusuales_reportadas: 0, inusuales_abiertas: 2 })).toBe('MEDIO');
  });

  it('el riesgo se puede subir a mano, nunca bajar', () => {
    expect(riesgoFinal('MEDIO', 'ALTO')).toBe('ALTO');
    expect(riesgoFinal('ALTO', 'BAJO')).toBe('ALTO');
    expect(riesgoFinal('BAJO', null)).toBe('BAJO');
  });

  it('para aprobar: actividad, origen de fondos, cédula o RUC; jurídica con beneficiario final y estatuto; PEP con declaración', () => {
    expect(faltantesParaAprobar(base, [])).toEqual(['la copia de la cédula o del RUC']);
    expect(faltantesParaAprobar(base, [{ tipo: 'CEDULA', anulado: false }])).toEqual([]);
    expect(faltantesParaAprobar(base, [{ tipo: 'CEDULA', anulado: true }])).toHaveLength(1);
    const juridica = { ...base, tipo_persona: 'JURIDICA' as const, beneficiarios_finales: [{ nombre: 'Ana', pct: 5 }] };
    expect(faltantesParaAprobar(juridica, [{ tipo: 'RUC', anulado: false }])).toHaveLength(2);
    expect(
      faltantesParaAprobar({ ...juridica, beneficiarios_finales: [{ nombre: 'Ana', pct: 60 }] }, [
        { tipo: 'RUC', anulado: false },
        { tipo: 'ESTATUTO', anulado: false },
      ]),
    ).toEqual([]);
    expect(faltantesParaAprobar({ ...base, pep: true }, [{ tipo: 'CEDULA', anulado: false }])).toEqual([
      'la declaración jurada de PEP',
    ]);
    expect(
      faltantesParaAprobar({ ...base, actividad: '', origen_fondos: null }, [{ tipo: 'CEDULA', anulado: false }]),
    ).toHaveLength(2);
  });

  it('vigencia: aprobado y sin vencer', () => {
    expect(vigenciaLegajo(null, '2026-10-11').vigente).toBe(false);
    expect(vigenciaLegajo({ estado: 'PENDIENTE', vence: null }, '2026-10-11').vigente).toBe(false);
    expect(vigenciaLegajo({ estado: 'APROBADO', vence: '2027-01-01' }, '2026-10-11')).toEqual({
      vigente: true,
      motivo: null,
    });
    expect(
      vigenciaLegajo({ estado: 'APROBADO', vence: new Date('2026-10-10T00:00:00Z') }, '2026-10-11').motivo,
    ).toMatch(/venció/);
  });

  it('fraccionamiento: varios pagos que suman el umbral sin que ninguno lo alcance', () => {
    const r = detectarFraccionamiento(
      [
        { cliente_id: 'a', monto_gs: 40_000_000 },
        { cliente_id: 'a', monto_gs: 40_000_000 },
        { cliente_id: 'b', monto_gs: 80_000_000 },
        { cliente_id: 'b', monto_gs: 1_000_000 },
        { cliente_id: 'c', monto_gs: 30_000_000 },
      ],
      75_000_000,
    );
    expect(r).toEqual([{ cliente_id: 'a', total: 80_000_000, cantidad: 2 }]);
  });

  it('archivo: 5 años desde la última actividad', () => {
    expect(conservarHasta('2026-10-11')).toBe('2031-10-11');
    expect(conservarHasta(null)).toBeNull();
  });
});
