// PRUEBA DEL BUZON DE CARPETA (2026-07-29)
//
// La via de intercambio para administrativos sin API: un archivo .json por
// venta en intercambio/entrada, con el MISMO contrato de la guia. Lo que se
// comprueba: que selle y responda, que mueva sin borrar, que el JSON dañado y
// la venta coja vayan a rechazadas con su porque, que duplicar no duplique, y
// que un archivo recien escrito se deje quieto (el respiro anti-mitades).
import { mkdtempSync, readdirSync, readFileSync, rmSync, utimesSync, writeFileSync } from 'node:fs';
import { tmpdir } from 'node:os';
import { join } from 'node:path';
import { EstacionFiscal } from '../dist/estacion.js';
import { guardarConfig } from '../dist/config.js';
import { prepararCarpetas, procesarCarpeta } from '../dist/intercambio.js';

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

const CONFIG = {
  emisor: {
    rif: 'J-50856106-6',
    razon_social: 'Arepa Power de prueba',
    domicilio_fiscal: 'Araure, Portuguesa',
    precios_con_iva: true,
    alicuota_general: 16,
  },
  serie: 'A',
  sucursal: '1',
  equipo: 'BUZON-01',
  imprenta: { adaptador: 'practica', nombre: 'Practica' },
  respaldo: null,
  usando: 'imprenta',
};

const venta = (id) => ({
  origen_id: id,
  canal: 'caja',
  cliente: { nombre: 'Consumidor final' },
  renglones: [{ nombre: 'Almuerzo', cantidad: 1, precio_usd: 10, alicuota: 16 }],
  tasa_bs: 742.23,
  pago: { metodo: 'efectivo' },
});

/** Escribe el archivo y le pone fecha vieja: ya paso el respiro. */
function dejar(c, nombre, contenido) {
  const ruta = join(c.entrada, nombre);
  writeFileSync(ruta, typeof contenido === 'string' ? contenido : JSON.stringify(contenido));
  const hace10s = new Date(Date.now() - 10_000);
  utimesSync(ruta, hace10s, hace10s);
  return ruta;
}

const respuesta = (c, nombre) => JSON.parse(readFileSync(join(c.respuestas, `${nombre}.respuesta.json`), 'utf8'));

try {
  console.log('\n== 1. Las carpetas del buzon se crean solas ==');
  const c = prepararCarpetas(dir);
  check(readdirSync(join(dir, 'intercambio')).length === 4, 'entrada, procesadas, rechazadas y respuestas existen');

  guardarConfig(dir, CONFIG);
  const est = await EstacionFiscal.abrir(dir);

  console.log('\n== 2. Una venta en entrada queda sellada y respondida ==');
  dejar(c, 'v-001.json', venta('carp-001'));
  const r1 = await procesarCarpeta(est, dir);
  check(r1.selladas === 1, 'la ronda sella 1');
  const a1 = respuesta(c, 'v-001.json');
  check(a1.sellada === true && a1.serie === 'A' && a1.numero === 1, `la respuesta trae su numero (${a1.serie}-${a1.numero})`);
  check(!!a1.numeroControl, `y el numero de control (${a1.numeroControl})`);
  check(readdirSync(c.entrada).length === 0, 'entrada quedo vacia');
  check(readdirSync(c.procesadas).length === 1, 'el archivo se movio a procesadas (no se borro)');

  console.log('\n== 3. JSON dañado y venta coja van a rechazadas con su porque ==');
  dejar(c, 'v-rota.json', '{esto no es json');
  dejar(c, 'v-coja.json', { origen_id: 'carp-coja', renglones: [] });
  const r2 = await procesarCarpeta(est, dir);
  check(r2.rechazadas === 2 && r2.selladas === 0, 'las dos rechazadas, ninguna sellada');
  check(/JSON valido/i.test(respuesta(c, 'v-rota.json').problema), 'la rota dice que no es JSON');
  check(/renglones/i.test(respuesta(c, 'v-coja.json').problema), 'la coja dice que le faltan renglones');
  check(readdirSync(c.rechazadas).length === 2, 'ambas movidas a rechazadas');

  console.log('\n== 4. Duplicar el mismo origen_id NO duplica documentos ==');
  dejar(c, 'v-002.json', venta('carp-001'));
  const r3 = await procesarCarpeta(est, dir);
  const a2 = respuesta(c, 'v-002.json');
  check(r3.selladas === 1 && a2.numero === 1, `devuelve el documento que ya existia (${a2.serie}-${a2.numero})`);

  console.log('\n== 5. Un archivo recien escrito se deja quieto (el respiro) ==');
  writeFileSync(join(c.entrada, 'v-fresca.json'), JSON.stringify(venta('carp-003')));
  const r4 = await procesarCarpeta(est, dir);
  check(r4.esperando === 1 && r4.selladas === 0, 'recien escrito: espera, no se toca');
  check(readdirSync(c.entrada).length === 1, 'sigue en entrada');
  const vieja = new Date(Date.now() - 10_000);
  utimesSync(join(c.entrada, 'v-fresca.json'), vieja, vieja);
  const r5 = await procesarCarpeta(est, dir);
  check(r5.selladas === 1, 'pasado el respiro, se sella normal');

  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);
