// PRUEBA DEL BLOQUE 7: LA ENTRADA DESDE GUSTITO (2026-07-28)
// Gustito entrega una venta ya cobrada y recibe el numero del documento. Nada
// mas. Lo que se prueba: que la venta no se pierda nunca (ni si la estacion
// esta sin configurar, ni si se cae el internet, ni si se apaga la laptop), y
// que Gustito no tenga que saber una palabra de impuestos.
import { mkdtempSync, rmSync } 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';

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

// Asi se ve una venta saliendo de Gustito: lo que se vendio y lo que se cobro.
// Ni una palabra de base imponible, alicuotas ni numeros de control.
const ventaDeGustito = (id, canal = 'mesa') => ({
  origen_id: id,
  canal,
  cliente: { nombre: 'Consumidor final' },
  renglones: [
    { nombre: 'Arepa Dominó', cantidad: 2, precio_usd: 5, alicuota: 16 },
    { nombre: 'Agua', cantidad: 1, precio_usd: 1, alicuota: 0 },
  ],
  tasa_bs: 742.23,
  pago: { metodo: 'efectivo' },
});

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: 'FISCAL-01',
  imprenta: { adaptador: 'practica', nombre: 'Practica' },
  respaldo: null,
  usando: 'imprenta',
};

try {
  console.log('\n== 1. Sin configurar, la estacion no abre y lo dice claro ==');
  let problema = '';
  try {
    await EstacionFiscal.abrir(dir);
  } catch (e) {
    problema = e.message;
  }
  check(/no esta lista/i.test(problema), `avisa que falta configurar: "${problema.slice(0, 60)}..."`);

  console.log('\n== 2. Configurada: Gustito manda la venta y recibe su numero ==');
  guardarConfig(dir, CONFIG);
  const est = await EstacionFiscal.abrir(dir);
  const r1 = await est.recibirVenta(ventaDeGustito('gx-001'));
  check(r1.sellada, 'la venta queda sellada');
  check(r1.numero === 1 && r1.serie === 'A', `con su numero de documento (${r1.serie}-${r1.numero})`);
  check(!!r1.numeroControl, `y el numero de control de la imprenta (${r1.numeroControl})`);
  check(r1.transmision === 'enviado', 'transmitida de una');

  console.log('\n== 3. Gustito no sabe nada de impuestos, y aun asi el documento cuadra ==');
  const doc = est.documentos()[0].documento;
  check(Math.round(doc.total_usd * 100) === 1100, `el total es lo que pago el cliente (${doc.total_usd})`);
  check(Math.round((doc.base_usd + doc.iva_usd) * 100) === 1100, 'base mas impuesto cuadra con el total');
  check(doc.por_alicuota.length === 2, 'con lo gravado y lo exento separados');
  check(doc.emisor.rif === 'J-50856106-6', 'y el RIF del negocio puesto por la estacion, no por Gustito');

  console.log('\n== 4. La misma venta dos veces no se factura dos veces ==');
  const r2 = await est.recibirVenta(ventaDeGustito('gx-001'));
  check(r2.numero === 1, `un reintento de Gustito devuelve el mismo documento (${r2.numero})`);
  check(est.documentos().length === 1, 'y el libro sigue con uno solo');

  console.log('\n== 5. Anular es nota de credito, nunca borrar ==');
  const sinMotivo = await est.anular(1, '   ');
  check(!sinMotivo.sellada, 'no deja anular sin escribir el motivo');
  const nc = await est.anular(1, 'Al cliente le cobraron de mas');
  check(nc.sellada && nc.numero === 1, `sale la nota de credito numero ${nc.numero}`);
  check(est.documentos().length === 2, 'el libro ahora tiene la factura Y su nota');
  check(est.documentos()[0].documento.total_usd === doc.total_usd, 'la factura original quedo intacta');
  const noExiste = await est.anular(99, 'motivo');
  check(!noExiste.sellada, 'y no se puede anular algo que no existe');

  console.log('\n== 6. El estado que ve el negocio ==');
  const e = est.estado();
  check(e.negocio === 'Arepa Power de prueba' && e.rif === 'J-50856106-6', 'muestra de que negocio es la estacion');
  check(e.documentos === 2 && e.pendientes === 0, `dos documentos, nada pendiente (${e.documentos}/${e.pendientes})`);
  check(e.libro_integro, 'y el libro integro');
  check(e.imprenta_real === false, 'avisa que la imprenta configurada es de practica');

  console.log('\n== 7. Nada se pierde: el buzon guarda la venta apenas llega ==');
  const buzon = est.buzon();
  check(buzon.length === 2, `las 2 ventas que mando Gustito quedaron en el buzon (${buzon.length})`);
  check(buzon[0].venta.origen_id === 'gx-001', 'con su identificacion de origen');

  console.log('\n== 8. Se apaga la laptop y se vuelve a abrir ==');
  const est2 = await EstacionFiscal.abrir(dir);
  const e2 = est2.estado();
  check(e2.documentos === 2, 'los documentos siguen ahi');
  check(e2.libro_integro, 'el libro sigue integro');
  const r3 = await est2.recibirVenta(ventaDeGustito('gx-002', 'delivery'));
  check(r3.numero === 2, `y la numeracion sigue donde iba (factura ${r3.numero})`);

  console.log('\n== 9. El fiscal ve todo lo que paso ==');
  const aud = est2.auditor('fiscal.seniat', '10.0.0.9');
  const t = aud.totales(new Date(Date.now() - 86400000), new Date(Date.now() + 86400000));
  check(t.documentos === 3, `ve las 2 facturas y la nota (${t.documentos})`);
  check(aud.comprobarIntegridad().integro, 'y puede comprobar el libro por su cuenta');
} catch (e) {
  console.log('  XX  ' + e.message);
  fallos++;
} finally {
  rmSync(dir, { recursive: true, force: true });
}

console.log(fallos === 0 ? '\nBLOQUE 7 (ENTRADA DESDE GUSTITO): TODO VERDE' : `\n${fallos} FALLO(S)`);
process.exitCode = fallos === 0 ? 0 : 1; // salida natural: process.exit() con undici cerrando revienta libuv en Node 24/Windows
