/**
 * scripts/test_rips_sondeo.js — node scripts/test_rips_sondeo.js
 *
 * Pruebas del sondeo RIPS contra el código real de recepcion.php.
 *
 * El defecto que esto vigila: la consulta a RIPS se hacía UNA vez al vincular
 * al paciente, y en 7 días 547 de 549 registros llegaron después de esa única
 * consulta. El sondeo reintenta cada 10 s hasta 10 minutos y debe detenerse
 * al encontrar, al limpiar la ficha, o al agotar los intentos.
 */
const fs = require('fs');
let fallos = 0;
const ok = (d, c) => { console.log((c ? '  ok    ' : '  FALLA ') + d); if (!c) fallos++; };

const src = fs.readFileSync(__dirname + '/../modules/turnero/views/recepcion.php', 'utf8')
  .replace(/<\?(php|=)[\s\S]*?\?>/g, '"PHP"');

// Se extraen exactamente las tres piezas del control de sondeo
const m = src.match(/let _ripsSondeoId[\s\S]*?function detenerSondeoRips\(\) \{[\s\S]*?\n\}/);
if (!m) { console.log('  FALLA no se encontró el bloque de sondeo'); process.exit(1); }

function armar() {
  let consultas = 0;
  const intervalos = new Map();
  let proximoId = 1;
  const setIntervalFake = (fn, ms) => { const id = proximoId++; intervalos.set(id, { fn, ms }); return id; };
  const clearIntervalFake = (id) => intervalos.delete(id);

  const api = new Function(
    'setInterval', 'clearInterval', 'INTERVALOS', 'CONTADOR',
    'let _ripsData = null;' +
    'const consultarExamenesRips = (c) => { CONTADOR.n++; };' +
    m[0] + `;
     return {
       iniciar: iniciarSondeoRips,
       detener: detenerSondeoRips,
       tic() { for (const v of [...INTERVALOS.values()]) v.fn(); },
       activo() { return _ripsSondeoId !== null; },
       encontrado() { _ripsData = { encontrados: [1] }; },
     };`
  )(setIntervalFake, clearIntervalFake, intervalos, (globalThis.__c = { n: 0 }));
  return { api, contador: globalThis.__c, intervalos };
}

// ── 1. Consulta de inmediato y reintenta ────────────────────────────────
{
  const { api, contador } = armar();
  api.iniciar('12345678');
  ok('consulta de inmediato al vincular', contador.n === 1);
  api.tic(); api.tic(); api.tic();
  ok('reintenta en cada ciclo mientras no encuentra', contador.n === 4);
}

// ── 2. Al encontrar, deja de sondear ────────────────────────────────────
{
  const { api, contador } = armar();
  api.iniciar('12345678');
  api.tic();
  api.encontrado();
  api.tic();                       // este ciclo detecta _ripsData y se apaga
  const n = contador.n;
  api.tic(); api.tic();
  ok('al encontrar los exámenes se apaga y no consulta más',
     contador.n === n && !api.activo());
}

// ── 3. Limpiar la ficha lo detiene ──────────────────────────────────────
{
  const { api, contador } = armar();
  api.iniciar('12345678');
  api.detener();
  const n = contador.n;
  api.tic(); api.tic();
  ok('limpiar la ficha detiene el sondeo en seco', contador.n === n && !api.activo());
}

// ── 4. Tope de intentos: no sondea para siempre ─────────────────────────
{
  const { api, contador } = armar();
  api.iniciar('12345678');
  for (let i = 0; i < 80; i++) api.tic();
  ok('se rinde tras ~60 intentos (10 min), no queda sondeando eternamente',
     contador.n <= 61 && !api.activo());
}

// ── 5. Vincular a otro paciente reinicia sin duplicar intervalos ────────
{
  const { api, contador, intervalos } = armar();
  api.iniciar('11111111');
  api.iniciar('22222222');
  ok('re-vincular no deja dos sondeos corriendo a la vez', intervalos.size === 1);
}

// ── 6. Sin cédula no arranca ────────────────────────────────────────────
{
  const { api, contador } = armar();
  api.iniciar('');
  ok('sin cédula no consulta ni deja intervalos', contador.n === 0 && !api.activo());
}

// ── 7. Guardián de ficha: una respuesta tardía no aterriza en otro paciente ──
// La respuesta del fetch puede llegar DESPUÉS de que la recepcionista cambió
// de ficha. Este caso vigila que el código compare la cédula de la respuesta
// contra la de quien está en pantalla ANTES de cargar nada. Es estructural
// (el código real usa fetch y DOM), pero si alguien borra el guardián, falla.
{
  const i = src.indexOf('get_examenes_rips.php?cedula=');
  const j = src.indexOf('cedulaEnPantalla', i);
  const k = src.indexOf("d.fuente === 'cache'", i);
  ok('el guardián de cédula existe y corre ANTES de cargar los exámenes',
     i > -1 && j > -1 && k > -1 && j < k);
  ok('el guardián descarta y detiene el sondeo si la ficha cambió',
     /cedulaEnPantalla !== cedula\) \{ detenerSondeoRips\(\); return; \}/.test(src));
}

console.log();
console.log(fallos === 0 ? 'Todo correcto.' : fallos + ' pruebas fallaron.');
process.exit(fallos === 0 ? 0 : 1);
