// LA PANTALLA DE LA IMPRENTA DIGITAL (2026-07-30).
//
// Antes la imprenta solo se podia conectar editando el archivo de config a
// mano: para un cliente eso es como no existir. Esta prueba cubre la pantalla
// nueva, con el servidor de verdad andando:
//   - La configuracion muestra el selector de proveedor y con cual emite.
//   - Guardar credenciales las deja escritas y la estacion las toma.
//   - Probar la conexion toca la puerta SIN emitir (practica responde que no
//     emite; HKA con credenciales malas responde que no sirven).
//   - El salvavidas se guarda aparte y el cambio es MANUAL.
//   - No se puede pasar a un respaldo que no existe.
//   - Todo lo que se toca queda en la bitacora.
import { mkdtempSync, readFileSync, rmSync } from 'node:fs';
import { tmpdir } from 'node:os';
import { join } from 'node:path';
import { iniciarServidor } from '../dist/servidor.js';
import { Acceso } from '../dist/acceso.js';

let fallos = 0;
const check = (cond, msg) => {
  console.log((cond ? '  OK  ' : '  XX  ') + msg);
  if (!cond) fallos++;
};

const dir = mkdtempSync(join(tmpdir(), 'fiscal-imprenta-'));
const PUERTO = 8758;
const base = `http://127.0.0.1:${PUERTO}`;
let servidor;

const CLAVE_DUENO = 'clave-del-dueno-2026';
new Acceso(join(dir, 'estado', 'acceso.json')).fijarClave('dueno', CLAVE_DUENO);
let galleta = '';
const forma = (datos) => ({
  method: 'POST',
  headers: { cookie: galleta, 'content-type': 'application/x-www-form-urlencoded' },
  body: new URLSearchParams(datos).toString(),
  redirect: 'manual',
});
const leerCfg = () => JSON.parse(readFileSync(join(dir, 'fiscal.config.json'), 'utf8'));

try {
  servidor = await iniciarServidor({ base: dir, puerto: PUERTO, log: () => {} });
  const entrar = await fetch(`${base}/entrar`, {
    method: 'POST',
    headers: { 'content-type': 'application/x-www-form-urlencoded' },
    body: new URLSearchParams({ clave: CLAVE_DUENO }).toString(),
    redirect: 'manual',
  });
  galleta = (entrar.headers.get('set-cookie') ?? '').split(';')[0];

  console.log('\n== 1. Sin datos del negocio no se conecta imprenta ==');
  const temprano = await fetch(`${base}/imprenta`, forma({ p_adaptador: 'hka' }));
  check(temprano.status === 400, `avisa que primero van los datos del negocio (HTTP ${temprano.status})`);

  await fetch(`${base}/configurar`, forma({
    rif: 'J-50856106-6', razon_social: 'Arepa Power Restaurant', domicilio_fiscal: 'Araure',
    alicuota_general: '16', serie: 'A', equipo: 'IMP-01',
  }));

  console.log('\n== 2. La pantalla muestra el selector y con cual se emite ==');
  const pantalla = await (await fetch(`${base}/configurar`, { headers: { cookie: galleta } })).text();
  check(/name="p_adaptador"/.test(pantalla), 'sale el selector de proveedor');
  check(/The Factory HKA/.test(pantalla) && /Imprenta Digital Gustito/.test(pantalla), 'con los proveedores que existen');
  check(/Emitiendo con/.test(pantalla), 'y dice con cual esta emitiendo ahorita');
  check(/Proveedor de respaldo/i.test(pantalla), 'ademas del proveedor de respaldo (continuidad del servicio)');

  console.log('\n== 3. Guardar credenciales las deja escritas ==');
  const g = await fetch(`${base}/imprenta`, forma({
    p_adaptador: 'hka', p_url: 'https://demoemisionv2.thefactoryhka.com.ve',
    p_usuario: 'usuario-de-prueba', p_clave: 'clave-de-prueba', p_token: '',
  }));
  check(g.status === 302, `guarda y vuelve a Configuracion (HTTP ${g.status})`);
  const cfg1 = leerCfg();
  check(cfg1.imprenta.adaptador === 'hka' && cfg1.imprenta.usuario === 'usuario-de-prueba', 'las credenciales quedaron en la configuracion');
  check(cfg1.imprenta.nombre.includes('HKA'), `con el nombre del proveedor (${cfg1.imprenta.nombre})`);

  console.log('\n== 4. Probar la conexion toca la puerta SIN emitir ==');
  const malas = await (await fetch(`${base}/api/probar-imprenta`, {
    method: 'POST', headers: { cookie: galleta, 'content-type': 'application/json' }, body: JSON.stringify({ cual: 'imprenta' }),
  })).json();
  check(malas.ok === false, 'con credenciales malas responde que NO sirven');
  check(typeof malas.detalle === 'string' && malas.detalle.length > 5, `y explica por que (${String(malas.detalle).slice(0, 60)}...)`);
  const docs = leerCfg();
  check(!docs.documentos, 'y no emitio ningun documento en el intento');

  console.log('\n== 4.1 Con TOKEN FIJO tampoco se cree: lo prueba contra la imprenta ==');
  // Hay imprentas que entregan el token ya hecho. Tenerlo no basta: uno
  // vencido se ve igual de bonito que uno bueno, asi que se comprueba.
  await fetch(`${base}/imprenta`, forma({
    p_adaptador: 'hka', p_url: 'https://demoemisionv2.thefactoryhka.com.ve',
    p_usuario: '', p_clave: '', p_token: 'token-inventado-que-no-sirve',
  }));
  const conToken = await (await fetch(`${base}/api/probar-imprenta`, {
    method: 'POST', headers: { cookie: galleta, 'content-type': 'application/json' }, body: JSON.stringify({ cual: 'imprenta' }),
  })).json();
  check(conToken.ok === false, 'un token inventado NO pasa como bueno');
  check(/vencido|no acepta/i.test(conToken.detalle), `y dice que hay que pedir uno nuevo (${String(conToken.detalle).slice(0, 50)}...)`);

  console.log('\n== 5. El salvavidas se guarda aparte, y el cambio es MANUAL ==');
  const sinRespaldo = await fetch(`${base}/imprenta`, forma({ cual: 'cambiar', usando: 'respaldo' }));
  check(sinRespaldo.status === 400, 'no se puede pasar a un respaldo que no existe');
  await fetch(`${base}/imprenta`, forma({ cual: 'respaldo', p_adaptador: 'practica' }));
  const cfg2 = leerCfg();
  check(cfg2.respaldo?.adaptador === 'practica', 'el respaldo quedo guardado aparte');
  check(cfg2.imprenta.adaptador === 'hka', 'sin tocar la imprenta principal');
  check(cfg2.usando === 'imprenta', 'y NO se cambio solo: sigue emitiendo con la principal');
  await fetch(`${base}/imprenta`, forma({ cual: 'cambiar', usando: 'respaldo' }));
  check(leerCfg().usando === 'respaldo', 'el cambio ocurre cuando el dueño lo pide');
  const practica = await (await fetch(`${base}/api/probar-imprenta`, {
    method: 'POST', headers: { cookie: galleta, 'content-type': 'application/json' }, body: JSON.stringify({ cual: 'respaldo' }),
  })).json();
  check(practica.ok === true && /practica/i.test(practica.detalle), 'la de practica avisa que no emite documentos validos');

  console.log('\n== 6. Todo queda en la bitacora ==');
  const movs = await (await fetch(`${base}/movimientos`, { headers: { cookie: galleta } })).text();
  check(/imprenta_configurada/.test(movs), 'quien configuro la imprenta');
  check(/imprenta_cambiada/.test(movs), 'y quien cambio al respaldo');

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