// PRUEBA DE LOS COMPROBANTES DE RETENCION RECIBIDOS (2026-07-30)
//
// El credito fiscal que entregan los sujetos pasivos especiales al retener el
// IVA (Providencia 000054). Lo que se comprueba: que registre con validaciones
// de verdad, que no acepte duplicados, que la anulacion sea contramarca (nada
// se borra), que el resumen del mes sume solo lo vigente, y que todo sobreviva
// a cerrar y volver a abrir.
import { mkdtempSync, readFileSync, rmSync } from 'node:fs';
import { tmpdir } from 'node:os';
import { join } from 'node:path';
import { Retenciones } from '../dist/retenciones.js';

let fallos = 0;
const check = (cond, msg) => {
  console.log((cond ? '  OK  ' : '  XX  ') + msg);
  if (!cond) fallos++;
};
const dir = mkdtempSync(join(tmpdir(), 'fiscal-ret-'));

const COMPROBANTE = {
  numero: '20260700012345',
  fecha: '2026-07-15',
  agente_rif: 'J-50856106-6',
  agente_razon_social: 'Distribuidora Especial CA',
  facturas: 'A-00000042',
  iva_retenido_bs: 1250.5,
  porcentaje: 75,
};

try {
  const ret = new Retenciones(dir);

  console.log('\n== 1. Registrar con validaciones de verdad ==');
  const r1 = ret.registrar(COMPROBANTE, 'dueno');
  check(r1.periodo === '2026-07', `el periodo sale de la fecha (${r1.periodo})`);
  check(r1.iva_retenido_bs === 1250.5, `el monto queda como vino (${r1.iva_retenido_bs})`);
  const rebota = (datos, patron, msg) => {
    try {
      ret.registrar({ ...COMPROBANTE, numero: 'X' + Math.random(), ...datos }, 'dueno');
      check(false, msg);
    } catch (e) {
      check(patron.test(e.message), `${msg} ("${e.message.slice(0, 50)}")`);
    }
  };
  rebota({ agente_rif: 'J-11111111-1' }, /RIF/, 'RIF invalido rebota');
  rebota({ porcentaje: 50 }, /75 o 100/, 'porcentaje inventado rebota');
  rebota({ iva_retenido_bs: 0 }, /mayor que cero/, 'monto en cero rebota');
  rebota({ fecha: '15/07/2026' }, /AAAA-MM-DD/, 'fecha en formato criollo rebota');

  console.log('\n== 2. El mismo comprobante dos veces NO entra ==');
  try {
    ret.registrar(COMPROBANTE, 'dueno');
    check(false, 'duplicado rebota');
  } catch (e) {
    check(/ya esta registrado/.test(e.message), 'duplicado rebota');
  }
  // Con espacios y minusculas sigue siendo el mismo numero.
  try {
    ret.registrar({ ...COMPROBANTE, numero: ' 2026 0700012345 ' }, 'dueno');
    check(false, 'duplicado disfrazado rebota');
  } catch (e) {
    check(/ya esta registrado/.test(e.message), 'duplicado con espacios rebota igual');
  }

  console.log('\n== 3. Anular es contramarca, no borrado ==');
  ret.registrar({ ...COMPROBANTE, numero: '20260700099999', iva_retenido_bs: 500 }, 'dueno');
  ret.anular('20260700099999', 'se cargo con el monto equivocado', 'dueno');
  check(ret.listar().length === 1, 'el anulado ya no aparece en la lista');
  const crudo = readFileSync(join(dir, 'estado', 'retenciones.jsonl'), 'utf8').trim().split('\n');
  check(crudo.length === 3, `pero en el archivo estan las 3 lineas (${crudo.length}): nada se borro`);
  try {
    ret.anular('20260700099999', 'otra vez', 'dueno');
    check(false, 'anular dos veces rebota');
  } catch (e) {
    check(/ya esta anulado/.test(e.message), 'anular dos veces rebota');
  }

  console.log('\n== 4. El resumen del mes suma solo lo vigente ==');
  ret.registrar({ ...COMPROBANTE, numero: '20260800000001', fecha: '2026-08-02', iva_retenido_bs: 300 }, 'dueno');
  const jul = ret.resumen('2026-07');
  check(jul.comprobantes === 1 && jul.iva_retenido_bs === 1250.5, `julio: 1 comprobante, Bs 1250.50 (${jul.iva_retenido_bs})`);
  const ago = ret.resumen('2026-08');
  check(ago.comprobantes === 1 && ago.iva_retenido_bs === 300, `agosto: 1 comprobante, Bs 300 (${ago.iva_retenido_bs})`);

  console.log('\n== 5. Cerrar y volver a abrir: todo sigue ahi ==');
  const otra = new Retenciones(dir);
  check(otra.listar().length === 2, 'la nueva instancia lee lo mismo del disco');
  check(otra.resumen('2026-07').iva_retenido_bs === 1250.5, 'y el resumen cuadra igual');

  console.log(fallos === 0 ? '\nTODO EN VERDE' : `\n${fallos} FALLOS`);
} catch (e) {
  console.error('\nREVENTO:', e);
  fallos++;
} finally {
  rmSync(dir, { recursive: true, force: true });
}
process.exit(fallos ? 1 : 0);
