// SMOKE de los fixes de la auditoria legal (2026-07-23), contra la BD VIVA:
//  (A) cerrar_negocio nuevo: borra llaves push y comprobante de mesa.
//  (C) EF limpiar-datos-viejos + RPCs: archivos viejos borrados del bucket,
//      pedidos viejos anonimizados, punteros sueltos.
// Usa el restaurante DEMO y LIMPIA todo. Correr: node scripts/test_limpieza_datos.mjs
import { createClient } from '@supabase/supabase-js';
import { readFileSync } from 'node:fs';

const URL = 'https://szzhhlevtrcambcoytiz.supabase.co';
const ANON = readFileSync('.env.production', 'utf8').match(/VITE_SUPABASE_ANON_KEY=(.+)/)[1].trim();
const PAT = readFileSync('.sb_token', 'utf8').trim();
const keys = await (
  await fetch('https://api.supabase.com/v1/projects/szzhhlevtrcambcoytiz/api-keys?reveal=true', {
    headers: { Authorization: `Bearer ${PAT}` },
  })
).json();
const SERVICE = keys.find((k) => k.name === 'service_role').api_key;
// El secreto del cron sale del job ya programado (no se imprime).
const { rows } = await (
  await fetch('https://api.supabase.com/v1/projects/szzhhlevtrcambcoytiz/database/query', {
    method: 'POST',
    headers: { Authorization: `Bearer ${PAT}`, 'Content-Type': 'application/json' },
    body: JSON.stringify({ query: "SELECT command FROM cron.job WHERE jobname='limpiar-datos-viejos'" }),
  })
)
  .json()
  .then((r) => ({ rows: r }));
const SECRETO = (rows[0].command.match(/x-cron-secret['"]?\s*,\s*'([^']+)'/) ?? [])[1];
if (!SECRETO) {
  console.log('No pude extraer el secreto del cron');
  process.exit(1);
}

const svc = createClient(URL, SERVICE, { auth: { persistSession: false } });
let fallos = 0;
const check = (c, m) => {
  console.log((c ? '  OK  ' : '  XX  ') + m);
  if (!c) fallos++;
};

const { data: rest } = await svc.from('restaurantes').select('id').eq('slug', 'demo-gustito').maybeSingle();
const REST = rest.id;
const viejo = new Date(Date.now() - 100 * 86400_000).toISOString();
const marca = `LEGAL${String(Date.now()).slice(-6)}`;
let pedidoViejoId, pedidoFrescoId, cuentaId, duenoId;
const RUTA_A = `smoke-legal/${marca}-pago.txt`;
const RUTA_B = `smoke-legal/${marca}-mesa.txt`;

const limpiar = async () => {
  if (pedidoViejoId) await svc.from('pedidos').delete().eq('id', pedidoViejoId);
  if (pedidoFrescoId) await svc.from('pedidos').delete().eq('id', pedidoFrescoId);
  if (cuentaId) {
    await svc.from('pagos_mesa').delete().eq('cuenta_id', cuentaId);
    await svc.from('cuentas_mesa').delete().eq('id', cuentaId);
  }
  await svc.storage.from('comprobantes').remove([RUTA_A, RUTA_B]).catch(() => {});
  if (duenoId) await svc.auth.admin.deleteUser(duenoId).catch(() => {});
};

try {
  // ===== Escenario C: datos VIEJOS (100 dias) que la EF debe limpiar =====
  const archivo = new Blob(['captura de prueba'], { type: 'text/plain' });
  await svc.storage.from('comprobantes').upload(RUTA_A, archivo, { upsert: true });
  await svc.storage.from('comprobantes').upload(RUTA_B, archivo, { upsert: true });

  const { data: pv, error: ePv } = await svc
    .from('pedidos')
    .insert({
      restaurante_id: REST,
      codigo: `GD-${marca}A`,
      cliente_nombre: 'Viejo Cliente Legal',
      cliente_telefono: '04140000009',
      cliente_cedula: 'V12345678',
      direccion: 'Calle vieja 1',
      tipo_entrega: 'delivery',
      estado: 'entregado',
      metodo_pago: 'pago_movil',
      subtotal_usd: 10,
      total_usd: 10,
      recibido_en: viejo,
      push_endpoint: 'https://push.example/x',
      push_p256dh: 'claveP',
      push_auth: 'claveA',
    })
    .select('id')
    .maybeSingle();
  if (ePv) throw new Error('insert pedido viejo: ' + ePv.message);
  pedidoViejoId = pv?.id;
  await svc
    .from('pagos')
    .insert({ pedido_id: pedidoViejoId, metodo: 'pago_movil', monto_usd: 10, estado: 'confirmado', referencia: '9999', comprobante_url: RUTA_A, creado_en: viejo });

  const { data: cu } = await svc
    .from('cuentas_mesa')
    .insert({ restaurante_id: REST, mesa: '98', estado: 'cerrada', cerrada_en: viejo })
    .select('id')
    .maybeSingle();
  cuentaId = cu?.id;
  await svc
    .from('pagos_mesa')
    .insert({ cuenta_id: cuentaId, restaurante_id: REST, monto_usd: 5, metodo: 'pago_movil', referencia: '8888', comprobante_url: RUTA_B, creado_en: viejo });

  // Invocar la EF como lo hace el cron.
  const r = await fetch(`${URL}/functions/v1/limpiar-datos-viejos`, {
    method: 'POST',
    headers: { 'x-cron-secret': SECRETO, 'Content-Type': 'application/json' },
    body: '{}',
  });
  const j = await r.json();
  check(r.status === 200 && j.ok === true, `EF limpiar-datos-viejos responde ok (${JSON.stringify(j)})`);

  const { data: pvDespues } = await svc
    .from('pedidos')
    .select('cliente_nombre,cliente_telefono,cliente_cedula,direccion,push_endpoint')
    .eq('id', pedidoViejoId)
    .maybeSingle();
  check(
    pvDespues.cliente_nombre === 'Cliente' && pvDespues.cliente_telefono === '' && !pvDespues.cliente_cedula && !pvDespues.direccion,
    'pedido viejo ANONIMIZADO aunque el negocio nunca cerro jornada',
  );
  check(!pvDespues.push_endpoint, 'las llaves push del pedido viejo quedaron limpias');

  const { data: pgDespues } = await svc.from('pagos').select('referencia,comprobante_url').eq('pedido_id', pedidoViejoId);
  const { data: pmDespues } = await svc.from('pagos_mesa').select('referencia,comprobante_url').eq('cuenta_id', cuentaId);
  check(!pgDespues[0].referencia && !pgDespues[0].comprobante_url, 'pago viejo: referencia y puntero sueltos');
  check(!pmDespues[0].referencia && !pmDespues[0].comprobante_url, 'pago de MESA viejo: referencia y puntero sueltos');

  const { data: quedan } = await svc.storage.from('comprobantes').list('smoke-legal');
  const nombres = (quedan ?? []).map((f) => f.name);
  check(
    !nombres.includes(`${marca}-pago.txt`) && !nombres.includes(`${marca}-mesa.txt`),
    'los ARCHIVOS de ambos comprobantes fueron borrados del bucket',
  );

  // ===== Escenario A: cerrar_negocio con las columnas nuevas =====
  const { data: lista } = await svc.auth.admin.listUsers();
  for (const u of lista?.users ?? []) if (u.email === 'dueno.legal.test@gustitoxpress.app') await svc.auth.admin.deleteUser(u.id);
  const { data: du } = await svc.auth.admin.createUser({
    email: 'dueno.legal.test@gustitoxpress.app',
    password: 'LegalTest2026!',
    email_confirm: true,
  });
  duenoId = du.user.id;
  await svc.from('perfiles').upsert({ id: duenoId, rol: 'dueno', restaurante_id: REST, nombre: 'Dueno Legal Test' });

  const { data: pf, error: ePf } = await svc
    .from('pedidos')
    .insert({
      restaurante_id: REST,
      codigo: `GD-${marca}B`,
      cliente_nombre: 'Fresco Cliente',
      cliente_telefono: '04140000008',
      tipo_entrega: 'pickup',
      estado: 'entregado',
      metodo_pago: 'efectivo',
      subtotal_usd: 5,
      total_usd: 5,
      push_endpoint: 'https://push.example/y',
    })
    .select('id')
    .maybeSingle();
  if (ePf) throw new Error('insert pedido fresco: ' + ePf.message);
  pedidoFrescoId = pf?.id;

  const dueno = createClient(URL, ANON, { auth: { persistSession: false } });
  await dueno.auth.signInWithPassword({ email: 'dueno.legal.test@gustitoxpress.app', password: 'LegalTest2026!' });
  const { error: eCierre } = await dueno.rpc('cerrar_negocio');
  check(!eCierre, 'cerrar_negocio corre como dueño' + (eCierre ? ' -> ' + eCierre.message : ''));

  const { data: pfDespues } = await svc
    .from('pedidos')
    .select('cliente_nombre,push_endpoint')
    .eq('id', pedidoFrescoId)
    .maybeSingle();
  check(
    pfDespues.cliente_nombre === 'Cliente' && !pfDespues.push_endpoint,
    'el cierre de jornada tambien limpia las llaves push ahora',
  );
  // Dejar el demo abierto como estaba.
  await svc.from('restaurantes').update({ abierto: true }).eq('id', REST);
} catch (e) {
  console.log('  XX  Excepcion: ' + e.message);
  fallos++;
} finally {
  await limpiar();
  console.log('\nLimpieza hecha');
}
console.log(fallos === 0 ? '\nFIXES LEGALES OK' : `\n${fallos} FALLO(S)`);
process.exit(fallos === 0 ? 0 : 1);
