// Verificacion del MODO MESERO contra la BD viva (nube).
// Crea 2 meseros de prueba en el restaurante DEMO, ejercita el flujo completo
// (estampado de identidad, mesa compartida sin cruce, candados de rol) y
// limpia TODO al final. Requiere env: SUPABASE_URL, SUPABASE_ANON_KEY, SUPABASE_SERVICE_KEY.
import { createClient } from '@supabase/supabase-js';

const URL = process.env.SUPABASE_URL || process.env.VITE_SUPABASE_URL;
const ANON = process.env.SUPABASE_ANON_KEY || process.env.VITE_SUPABASE_ANON_KEY;
const SERVICE = process.env.SUPABASE_SERVICE_KEY;
if (!URL || !ANON || !SERVICE) {
  console.log('Faltan SUPABASE_URL / SUPABASE_ANON_KEY / SUPABASE_SERVICE_KEY');
  process.exit(1);
}

const MESA = 'T91'; // mesa que no existe en la sala real del demo
let fallos = 0;
const check = (cond, msg) => {
  console.log((cond ? '  OK  ' : '  XX  ') + msg);
  if (!cond) fallos++;
};
const nuevo = () => createClient(URL, ANON, { auth: { persistSession: false } });
const svc = createClient(URL, SERVICE, { auth: { persistSession: false } });

// ---- Restaurante demo ----
const { data: rest } = await svc.from('restaurantes').select('id,slug,abierto').eq('slug', 'demo-gustito').maybeSingle();
if (!rest?.id || !rest.abierto) {
  console.log('Demo no disponible (existe/abierto):', JSON.stringify(rest));
  process.exit(1);
}
const REST = rest.id;
const { data: prods } = await svc.from('productos').select('id,nombre').eq('restaurante_id', REST).eq('disponible', true).limit(1);
if (!prods?.length) {
  console.log('El demo no tiene productos disponibles');
  process.exit(1);
}
const PROD_ID = prods[0].id;

// ---- Setup: 2 meseros de prueba (staff del demo) ----
const CLAVE = 'MeseroTest2026!';
async function crearMesero(email, nombre) {
  const { data, error } = await svc.auth.admin.createUser({ email, password: CLAVE, email_confirm: true });
  if (error) throw new Error('createUser ' + email + ': ' + error.message);
  const id = data.user.id;
  const { error: e2 } = await svc.from('perfiles').upsert({ id, rol: 'staff', restaurante_id: REST, nombre });
  if (e2) throw new Error('perfil ' + email + ': ' + e2.message);
  return id;
}
const limpiar = async (ids, cuentaId) => {
  if (cuentaId) {
    await svc.from('pedidos').delete().eq('cuenta_id', cuentaId);
    await svc.from('cuentas_mesa').delete().eq('id', cuentaId);
  }
  // por si quedo basura de corridas anteriores en la mesa de prueba
  const { data: viejas } = await svc.from('cuentas_mesa').select('id').eq('restaurante_id', REST).eq('mesa', MESA);
  for (const v of viejas ?? []) {
    await svc.from('pedidos').delete().eq('cuenta_id', v.id);
    await svc.from('cuentas_mesa').delete().eq('id', v.id);
  }
  for (const id of ids) await svc.auth.admin.deleteUser(id).catch(() => {});
};

let joseId, mariaId, cuentaId;
try {
  joseId = await crearMesero('mesero.test.jose@gustitoxpress.app', 'José Prueba');
  mariaId = await crearMesero('mesero.test.maria@gustitoxpress.app', 'María Prueba');
  console.log('Setup listo: 2 meseros de prueba en el demo\n');

  // 0) Mesa de prueba sin cuenta activa
  const anon0 = nuevo();
  const { data: sinCuenta } = await anon0.rpc('cuenta_mesa_activa', { p_restaurante_id: REST, p_mesa: MESA });
  check((sinCuenta?.length ?? 0) === 0, 'Mesa de prueba arranca sin cuenta activa');

  // 1) José (staff) toma pedido en la mesa -> queda estampado y dueño de la cuenta
  const jose = nuevo();
  const { error: eJose } = await jose.auth.signInWithPassword({ email: 'mesero.test.jose@gustitoxpress.app', password: CLAVE });
  check(!eJose, 'José inicia sesión');
  const { data: r1, error: e1 } = await jose.rpc('crear_pedido', {
    p_restaurante_id: REST, p_cliente_nombre: 'Mesa', p_cliente_telefono: '',
    p_tipo_entrega: 'mesa', p_metodo_pago: 'efectivo',
    p_items: [{ producto_id: PROD_ID, cantidad: 1, _c: 'jose1' }], p_mesa: MESA,
  });
  check(!e1 && r1?.[0]?.pedido_id, 'José crea pedido en la mesa ' + MESA + (e1 ? ' -> ' + e1.message : ''));
  cuentaId = r1?.[0]?.cuenta_id;
  const { data: ped1 } = await svc.from('pedidos').select('mesero_id,mesero_nombre').eq('id', r1[0].pedido_id).maybeSingle();
  check(ped1?.mesero_id === joseId && ped1?.mesero_nombre === 'José Prueba', 'Pedido 1 firmado por José (server-side)');
  const { data: cta1 } = await svc.from('cuentas_mesa').select('mesero_id,mesero_nombre').eq('id', cuentaId).maybeSingle();
  check(cta1?.mesero_id === joseId, 'La cuenta de la mesa quedó a nombre de José');

  // 2) AISLAMIENTO ESTRICTO (2026-07-22): María NO puede pedir en la mesa de José.
  //    Cada quien lo suyo; la cuenta sigue siendo de José, intacta.
  void mariaId;
  const maria = nuevo();
  await maria.auth.signInWithPassword({ email: 'mesero.test.maria@gustitoxpress.app', password: CLAVE });
  const { error: e2 } = await maria.rpc('crear_pedido', {
    p_restaurante_id: REST, p_cliente_nombre: 'Mesa', p_cliente_telefono: '',
    p_tipo_entrega: 'mesa', p_metodo_pago: 'efectivo',
    p_items: [{ producto_id: PROD_ID, cantidad: 2, _c: 'maria1' }], p_mesa: MESA,
  });
  check(!!e2, 'María NO puede sumar a la mesa de José (aislamiento): ' + (e2?.message ?? 'LA DEJO!'));
  const { data: cta2 } = await svc.from('cuentas_mesa').select('mesero_id,mesero_nombre').eq('id', cuentaId).maybeSingle();
  check(cta2?.mesero_id === joseId, 'La cuenta sigue siendo de José, intacta');

  // 3) Cliente por QR (anon) pide en la misma mesa -> sin firma de mesero, misma cuenta
  const { data: r3, error: e3 } = await anon0.rpc('crear_pedido', {
    p_restaurante_id: REST, p_cliente_nombre: 'Comensal QR', p_cliente_telefono: '04140000000',
    p_tipo_entrega: 'mesa', p_metodo_pago: 'efectivo',
    p_items: [{ producto_id: PROD_ID, cantidad: 1, _c: 'qr1' }], p_mesa: MESA,
  });
  check(!e3 && r3?.[0]?.cuenta_id === cuentaId, 'Cliente QR cae en la misma cuenta');
  const { data: ped3 } = await svc.from('pedidos').select('mesero_id,mesero_nombre').eq('id', r3[0].pedido_id).maybeSingle();
  check(ped3?.mesero_id === null && ped3?.mesero_nombre === null, 'Pedido del cliente SIN firma de mesero');

  // 4) El cliente ve quien lo atiende
  const { data: act } = await anon0.rpc('cuenta_mesa_activa', { p_restaurante_id: REST, p_mesa: MESA });
  check(act?.[0]?.mesero_nombre === 'José Prueba', 'cuenta_mesa_activa devuelve "Te atiende: José"');
  const { data: cm } = await anon0.rpc('cuenta_mesa', { p_cuenta_id: cuentaId });
  check(cm?.[0]?.mesero_nombre === 'José Prueba', 'cuenta_mesa (pantalla cliente) devuelve el mesero');

  // 5) Panel: mis_cuentas_mesa trae el mesero de cada mesa
  const { data: mcm } = await jose.rpc('mis_cuentas_mesa', { p_restaurante_id: REST });
  const fila = (mcm ?? []).find((c) => c.mesa === MESA);
  check(fila?.mesero_id === joseId && fila?.mesero_nombre === 'José Prueba', 'mis_cuentas_mesa incluye quien atiende');

  // 6) CANDADOS: el mesero NO tiene poderes de dueño
  const { data: updRest } = await jose.from('restaurantes').update({ nombre: 'HACKED' }).eq('id', REST).select();
  check((updRest?.length ?? 0) === 0, 'Mesero NO puede editar el negocio (RLS)');
  const { data: updProd } = await jose.from('productos').update({ precio_usd: 999 }).eq('id', PROD_ID).select();
  check((updProd?.length ?? 0) === 0, 'Mesero NO puede cambiar precios (RLS)');
  const { error: eCierre } = await jose.rpc('cerrar_negocio');
  check(!!eCierre, 'Mesero NO puede cerrar el negocio (' + (eCierre?.message ?? 'sin error!') + ')');
  const { data: updMeseros } = await jose.rpc('mis_meseros');
  check((updMeseros?.length ?? 0) === 0, 'Mesero NO lista el equipo (eso es del dueño)');
  const { data: verFlota } = await jose.rpc('mis_repartidores');
  check(Array.isArray(verFlota), 'Mesero SÍ ve la flota (selector del POS)');

  // 7) EF gestionar-mesero desplegada y protegida
  const efRes = await fetch(URL + '/functions/v1/gestionar-mesero', {
    method: 'POST', headers: { 'Content-Type': 'application/json', apikey: ANON },
    body: JSON.stringify({ accion: 'crear' }),
  });
  check(efRes.status === 401, 'EF gestionar-mesero viva y exige sesión (HTTP ' + efRes.status + ')');
} catch (e) {
  console.log('  XX  Excepción: ' + e.message);
  fallos++;
} finally {
  await limpiar([joseId, mariaId].filter(Boolean), cuentaId);
  console.log('\nLimpieza hecha (pedidos, cuenta y usuarios de prueba fuera)');
}

console.log(fallos === 0 ? '\nMODO MESERO OK' : `\nMODO MESERO: ${fallos} FALLO(S)`);
process.exit(fallos === 0 ? 0 : 1);
