// PRUEBA VIVA DEL TIEMPO REAL DEL PANEL (2026-08-01)
//
// Cubre los dos defectos que se arreglaron el 01-08 y que no se pueden repetir:
//
//   1. RAFAGA. Cada aviso de cambio traia su pedido con una consulta propia. Una
//      tanda de cambios era una tanda de consultas y el navegador se quedaba sin
//      recursos (ERR_INSUFFICIENT_RESOURCES), con lo que la pantalla se congelaba
//      y hasta se caia el tiempo real. Ahora los avisos de un mismo respiro salen
//      en UNA sola consulta.
//
//   2. LA PANTALLA SE ENTERA. El empalme escribia en la clave de tres tramos
//      ['pedidos', id, ''] cuando la lista ya se guardaba con cuatro. Escribia en
//      una gaveta inexistente: un pedido nuevo NO aparecia hasta recargar a mano.
//      Es el defecto peligroso de verdad, porque se pierde trabajo sin avisar.
//
// Corre contra produccion con el restaurante DEMO. No cambia ningun dato: los
// pedidos se tocan y se devuelven a su estado original al terminar.
//
// Uso: node scripts/test_panel_tiempo_real.mjs
import { readFileSync } from 'node:fs';
import { chromium } from 'file:///C:/Users/10/zafraclic/web/node_modules/playwright/index.mjs';

const RAIZ = new URL('..', import.meta.url).pathname.replace(/^\//, '');
const env = readFileSync(new URL('../.env.production', import.meta.url), 'utf8');
const URL_SB = env.match(/VITE_SUPABASE_URL=(\S+)/)[1];
const ANON = env.match(/VITE_SUPABASE_ANON_KEY=(\S+)/)[1];
const PAT = readFileSync(new URL('../.sb_token', import.meta.url), 'utf8').trim();
const REF = URL_SB.match(/https:\/\/([^.]+)/)[1];
const PANEL = process.env.PANEL_WEB ?? 'https://gustitoxpress.app';
const DEMO = '52057e85-f82a-4aaa-8577-3a75d269eb65'; // Arepas Doña Carmen, el demo
const CORREO = process.env.DEMO_CORREO ?? 'demo.negocio@gustitoxpress.app';
const CLAVE = process.env.DEMO_CLAVE ?? 'GustitoDemo2026';

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

const sql = async (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(`SQL ${r.status}: ${t.slice(0, 200)}`);
  return JSON.parse(t);
};

let navegador;
let original = null;

try {
  const r = await fetch(`${URL_SB}/auth/v1/token?grant_type=password`, {
    method: 'POST',
    headers: { apikey: ANON, 'Content-Type': 'application/json' },
    body: JSON.stringify({ email: CORREO, password: CLAVE }),
  });
  const sesion = await r.json();
  if (!sesion.access_token) throw new Error('no se pudo entrar con la cuenta demo');

  navegador = await chromium.launch();
  const p = await navegador.newPage({ viewport: { width: 1500, height: 950 } });
  await p.addInitScript(([k, v]) => window.localStorage.setItem(k, v), [`sb-${REF}-auth-token`, JSON.stringify(sesion)]);

  const consultas = [];
  p.on('request', (q) => {
    const u = q.url();
    if (!u.includes('/rest/v1/pedidos')) return;
    // OJO con el patron: hay que exigir el separador de delante (? o &), porque
    // `restaurante_id=eq.` TAMBIEN contiene `id=eq.` y se contaba como si fuera
    // una consulta de una en una. Esa confusion ya dio un susto falso.
    if (/[?&]id=eq\./.test(u)) consultas.push('una-por-una');
    else if (/[?&]id=in\./.test(u)) consultas.push('agrupada');
  });

  await p.goto(`${PANEL}/panel`, { waitUntil: 'domcontentloaded' });
  await p.waitForTimeout(5000);
  await p.click('nav >> text=Pedidos').catch(() => {});
  await p.waitForSelector('text=Activos', { timeout: 20000 });
  await p.waitForTimeout(4000);
  check(true, 'el panel abrio en la pantalla de Pedidos');

  console.log('\n== 1. Una rafaga de cambios se pide en UNA sola consulta ==');
  const lote = await sql(`select id from public.pedidos where restaurante_id = '${DEMO}'
    order by recibido_en desc limit 8;`);
  consultas.length = 0;
  // Todos de un golpe, sin cambiarles nada (estado = estado): asi llegan los
  // avisos juntos, como cuando un proceso toca varios pedidos a la vez.
  await sql(`update public.pedidos set estado = estado
    where id in (${lote.map((x) => `'${x.id}'`).join(',')});`);
  await p.waitForTimeout(9000);
  const unaPorUna = consultas.filter((c) => c === 'una-por-una').length;
  const agrupadas = consultas.filter((c) => c === 'agrupada').length;
  check(unaPorUna === 0, `ninguna consulta de una en una (${unaPorUna})`);
  check(agrupadas >= 1 && agrupadas <= 2, `${lote.length} cambios se resolvieron en ${agrupadas} consulta(s)`);

  console.log('\n== 2. La pantalla se entera sola, sin recargar ==');
  const [pedido] = await sql(`select id, codigo, estado from public.pedidos
    where restaurante_id = '${DEMO}' order by recibido_en desc limit 1;`);
  original = pedido;
  const seViaAntes = await p.evaluate((c) => document.body.innerText.includes(c), pedido.codigo);
  const destino = pedido.estado === 'confirmado' ? 'recibido' : 'confirmado';
  await sql(`update public.pedidos set estado = '${destino}' where id = '${pedido.id}';`);
  const aparecio = await p
    .waitForFunction((c) => document.body.innerText.includes(c), pedido.codigo, { timeout: 20000 })
    .then(() => true)
    .catch(() => false);
  check(aparecio, `${pedido.codigo} aparece solo en la lista (antes se veia: ${seViaAntes ? 'si' : 'no'})`);
} catch (e) {
  console.log('  XX  ' + e.message);
  fallos++;
} finally {
  if (original) {
    await sql(`update public.pedidos set estado = '${original.estado}' where id = '${original.id}';`).catch(() => {});
    const [vuelto] = await sql(`select estado from public.pedidos where id = '${original.id}';`).catch(() => [null]);
    console.log(
      vuelto?.estado === original.estado
        ? `  OK  ${original.codigo} quedo como estaba ('${original.estado}')`
        : `  XX  OJO: ${original.codigo} quedo en '${vuelto?.estado}' y era '${original.estado}'`,
    );
    if (vuelto?.estado !== original.estado) fallos++;
  }
  if (navegador) await navegador.close();
}

console.log(fallos === 0 ? '\nTIEMPO REAL DEL PANEL: 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
