// PRUEBA DEL ENRUTADOR DEL QR (2026-07-28)
// Corre la logica de la Pages Function contra la BD viva, sin desplegar nada:
// siembra un documento, lo consulta como lo haria el enrutador y comprueba que
// devuelve lo justo y NADA mas. Limpia lo que crea.
import { readFileSync } from 'node:fs';

const REF = 'szzhhlevtrcambcoytiz';
const PAT = readFileSync(new URL('../.sb_token', import.meta.url), 'utf8').trim();
const URL_BASE = 'https://szzhhlevtrcambcoytiz.supabase.co';

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

async function sql(query) {
  const r = await fetch(`https://api.supabase.com/v1/projects/${REF}/database/query`, {
    method: 'POST',
    headers: { Authorization: `Bearer ${PAT}`, 'Content-Type': 'application/json' },
    body: JSON.stringify({ query }),
  });
  const t = await r.text();
  if (!r.ok) throw new Error(t.slice(0, 200));
  return JSON.parse(t);
}

/** La service key no vive en ningun .env: se pide al vuelo y se descarta. */
async function serviceKey() {
  const r = await fetch(`https://api.supabase.com/v1/projects/${REF}/api-keys?reveal=true`, {
    headers: { Authorization: `Bearer ${PAT}` },
  });
  const j = await r.json();
  return j.find((k) => k.name === 'service_role').api_key;
}

// RIF DE PRUEBAS, JAMAS el de un cliente real de la imprenta: la limpieza de
// este test borra el emisor COMPLETO. El 2026-07-31 una corrida con
// J-50856106-6 (ya dado de alta real como EF-00006-0) barrio el alta del
// piloto: llaves, respaldo del libro y estacion. Ademas, limpiar() ahora
// ABORTA si el RIF tiene libro respaldado en la nube.
const RIF = 'V-22606827-5';
const lit = (s) => `'${String(s).replace(/'/g, "''")}'`;

const limpiar = async () => {
  const real = await sql(`select count(*)::int as n from fiscal.respaldo r join fiscal.emisores e on e.id = r.emisor_id where e.rif = ${lit(RIF)}`);
  if (real[0]?.n > 0) throw new Error(`FRENO: el emisor ${RIF} tiene ${real[0].n} lineas de libro respaldadas: es un cliente REAL, este test no lo toca`);
  await sql(`delete from fiscal.consultas_qr where token in (select token from fiscal.documentos d join fiscal.emisores e on e.id=d.emisor_id where e.rif=${lit(RIF)});
             delete from fiscal.documentos where emisor_id in (select id from fiscal.emisores where rif=${lit(RIF)});
             delete from fiscal.series where emisor_id in (select id from fiscal.emisores where rif=${lit(RIF)});
             delete from fiscal.emisores where rif=${lit(RIF)};`);
};

try {
  await limpiar();
  const KEY = await serviceKey();

  await sql(`insert into fiscal.emisores (rif, razon_social, domicilio_fiscal, llave_hash)
             values (${lit(RIF)}, 'Arepa Power de prueba', 'Araure, Portuguesa', 'llave')`);
  const doc = (await sql(`select * from fiscal.recibir_documento(${lit(RIF)}, 'A', 'factura', 1, 'hash-qr-1',
    now(), 1000.00, 160.00, 1160.00, '{"cliente":{"nombre":"Maria Rodriguez"},"renglones":[{"nombre":"Arepa Domino"}]}'::jsonb)`))[0];

  // Asi consulta el enrutador: por la puerta de servicio, nunca desde el navegador.
  const consultar = async (token, key = KEY) => {
    const r = await fetch(`${URL_BASE}/rest/v1/rpc/fn_validar_factura`, {
      method: 'POST',
      headers: { apikey: key, Authorization: `Bearer ${key}`, 'Content-Type': 'application/json' },
      body: JSON.stringify({ p_token: token, p_desde: '190.0.0.7' }),
    });
    return { estado: r.status, cuerpo: await r.json().catch(() => null) };
  };

  console.log('\n== 1. Con el token del QR, comprueba la factura ==');
  const ok = await consultar(doc.token);
  const f = ok.cuerpo?.[0];
  check(ok.estado === 200 && f?.valido === true, `responde que el documento es real (HTTP ${ok.estado})`);
  check(f.rif_emisor === RIF && f.razon_social === 'Arepa Power de prueba', 'con quien lo emitio');
  check(Number(f.numero_control) === 1 && Number(f.total_bs) === 1160, `su numero de control y su monto (${f.numero_control}, Bs ${f.total_bs})`);

  console.log('\n== 2. Y NO destapa lo que consumio el cliente ==');
  const texto = JSON.stringify(f);
  check(!texto.includes('Maria Rodriguez'), 'el nombre del cliente no sale');
  check(!texto.includes('Arepa Domino'), 'ni lo que se comio');
  check(!texto.includes(doc.token), 'ni devuelve el token de vuelta');

  console.log('\n== 3. Un token inventado no comprueba nada ==');
  const malo = await consultar('0'.repeat(32));
  check(malo.cuerpo?.[0]?.valido === false, 'responde que no existe, sin dar pistas');

  console.log('\n== 4. Desde el navegador NADIE puede consultar ==');
  const conAnon = await fetch(`${URL_BASE}/rest/v1/rpc/fn_validar_factura`, {
    method: 'POST',
    headers: {
      apikey: process.env.SUPABASE_ANON_KEY ?? 'sin-llave',
      Authorization: `Bearer ${process.env.SUPABASE_ANON_KEY ?? 'sin-llave'}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({ p_token: doc.token }),
  });
  check(conAnon.status === 401 || conAnon.status === 403 || conAnon.status === 404, `con llave publica rebota (HTTP ${conAnon.status})`);

  console.log('\n== 5. Cada escaneo queda registrado ==');
  const escaneos = (await sql(`select count(*)::int as n, max(desde) as ultimo from fiscal.consultas_qr where token=${lit(doc.token)}`))[0];
  check(escaneos.n >= 1, `quedo el rastro del escaneo (${escaneos.n})`);
  check(escaneos.ultimo === '190.0.0.7', 'con la direccion desde donde escanearon');

  console.log('\n== 6. El formato del token frena a quien anda probando ==');
  const formatoOk = /^[0-9a-f]{32}$/.test(doc.token);
  check(formatoOk, 'el token real es hexadecimal de 32, que es lo que filtra el enrutador antes de consultar');
} catch (e) {
  console.log('  XX  ' + String(e).slice(0, 200));
  fallos++;
} finally {
  await limpiar();
}

console.log(fallos === 0 ? '\nENRUTADOR DEL QR: TODO VERDE' : `\n${fallos} FALLO(S)`);
process.exit(fallos === 0 ? 0 : 1);
