// Verifica el pedido de Gilberto: "ver todas, tocar solo la tuya".
// - mis_cuentas_mesa/cuenta_mesa: cualquier staff del local ve TODAS las mesas
//   ocupadas (con quien las atiende), no solo la suya o las libres.
// - El candado de ESCRITURA sigue intacto: un mesero NO puede tomar pedido,
//   cobrar, ni quitar un renglon en la mesa de otro.
// - cuenta_mesa ahora trae 'id' por item (para poder quitarlo desde el modal).
// Usa el restaurante DEMO, mesa TF95, 2 staff temporales, y LIMPIA todo.
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 || process.env.SUPABASE_SERVICE_ROLE_KEY;
if (!URL || !ANON || !SERVICE) {
  console.log('Faltan SUPABASE_URL / SUPABASE_ANON_KEY / SUPABASE_SERVICE_KEY');
  process.exit(1);
}

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 } });
const MESA = 'TF95';

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

const EMAIL_A = 'staff.test.mesera.a@gustitoxpress.app';
const EMAIL_B = 'staff.test.mesera.b@gustitoxpress.app';
const CLAVE = 'VisMesas2026!';
let uidA, uidB, cuentaId, itemId;

const limpiar = async () => {
  const { data: ctas } = await svc.from('cuentas_mesa').select('id').eq('restaurante_id', REST).eq('mesa', MESA);
  for (const c of ctas ?? []) {
    await svc.from('pedidos').update({ cuenta_id: null }).eq('cuenta_id', c.id);
    await svc.from('cuentas_mesa').delete().eq('id', c.id);
  }
  if (uidA) await svc.auth.admin.deleteUser(uidA).catch(() => {});
  if (uidB) await svc.auth.admin.deleteUser(uidB).catch(() => {});
};

try {
  await limpiar();
  if (!PROD_ID) throw new Error('Demo sin productos disponibles');

  const { data: uA, error: eA } = await svc.auth.admin.createUser({ email: EMAIL_A, password: CLAVE, email_confirm: true });
  if (eA) throw new Error('createUser A: ' + eA.message);
  uidA = uA.user.id;
  await svc.from('perfiles').upsert({ id: uidA, rol: 'staff', restaurante_id: REST, nombre: 'Mariangel Test' });

  const { data: uB, error: eB } = await svc.auth.admin.createUser({ email: EMAIL_B, password: CLAVE, email_confirm: true });
  if (eB) throw new Error('createUser B: ' + eB.message);
  uidB = uB.user.id;
  await svc.from('perfiles').upsert({ id: uidB, rol: 'staff', restaurante_id: REST, nombre: 'Otra Mesera Test' });

  const meseraA = nuevo();
  await meseraA.auth.signInWithPassword({ email: EMAIL_A, password: CLAVE });
  const meseraB = nuevo();
  await meseraB.auth.signInWithPassword({ email: EMAIL_B, password: CLAVE });

  // Mariangel (A) abre la mesa y toma un pedido.
  const { data: cId, error: eAbrir } = await meseraA.rpc('abrir_mesa', { p_mesa: MESA, p_comensales: 2, p_modo: 'unica' });
  check(!eAbrir && !!cId, 'mesera A abre la mesa' + (eAbrir ? ' -> ' + eAbrir.message : ''));
  cuentaId = cId;

  const { data: creado, error: eCrear } = await meseraA.rpc('crear_pedido', {
    p_restaurante_id: REST,
    p_cliente_nombre: 'Cliente Visibilidad Test',
    p_cliente_telefono: '04120004444',
    p_tipo_entrega: 'mesa',
    p_metodo_pago: 'efectivo',
    p_items: [{ producto_id: PROD_ID, cantidad: 2 }],
    p_mesa: MESA,
  });
  check(!eCrear && !!creado?.[0]?.pedido_id, 'mesera A toma el pedido' + (eCrear ? ' -> ' + eCrear.message : ''));
  const pedidoId = creado?.[0]?.pedido_id;
  const { data: itemsFila } = await svc.from('pedido_items').select('id').eq('pedido_id', pedidoId).limit(1);
  itemId = itemsFila?.[0]?.id;

  // --- LECTURA: mesera B ahora SI ve la mesa de A (antes no aparecia ni rastro) ---
  const { data: listaB, error: eListaB } = await meseraB.rpc('mis_cuentas_mesa', { p_restaurante_id: REST });
  const filaB = (listaB ?? []).find((c) => c.mesa === MESA);
  check(!eListaB && !!filaB, 'mesera B VE la mesa de A en mis_cuentas_mesa' + (eListaB ? ' -> ' + eListaB.message : ''));
  check(filaB?.mesero_nombre === 'Mariangel Test', `mis_cuentas_mesa trae mesero_nombre correcto (vino: ${filaB?.mesero_nombre})`);

  const { data: detalleB, error: eDetB } = await meseraB.rpc('cuenta_mesa', { p_cuenta_id: cuentaId });
  const detB = detalleB?.[0];
  check(!eDetB && !!detB, 'mesera B puede leer el detalle completo (cuenta_mesa) de la mesa de A' + (eDetB ? ' -> ' + eDetB.message : ''));
  const itemsDetB = detB?.pedidos?.[0]?.items ?? [];
  check(itemsDetB.length > 0 && !!itemsDetB[0]?.id, 'cuenta_mesa trae el id de cada item (para poder quitarlo)');

  // --- ESCRITURA: el candado real sigue intacto, mesera B NO puede operar la mesa de A ---
  const { error: eTomarB } = await meseraB.rpc('crear_pedido', {
    p_restaurante_id: REST,
    p_cliente_nombre: 'Intento ajeno',
    p_cliente_telefono: '04120005555',
    p_tipo_entrega: 'mesa',
    p_metodo_pago: 'efectivo',
    p_items: [{ producto_id: PROD_ID, cantidad: 1 }],
    p_mesa: MESA,
  });
  check(!!eTomarB, 'mesera B NO puede tomar pedido en la mesa de A (bloqueado por el trigger de guardia)');

  const { error: eQuitarB } = await meseraB.rpc('quitar_item_pedido', { p_item_id: itemId });
  check(!!eQuitarB, 'mesera B NO puede quitar un renglon del pedido de A (bloqueado)');

  // Mariangel (A) SI puede quitar su propio renglon, y el total se recalcula.
  const { data: pedidoAntes } = await svc.from('pedidos').select('total_usd').eq('id', pedidoId).maybeSingle();
  const { error: eQuitarA } = await meseraA.rpc('quitar_item_pedido', { p_item_id: itemId });
  check(!eQuitarA, 'mesera A SI puede quitar su propio renglon' + (eQuitarA ? ' -> ' + eQuitarA.message : ''));
  const { data: pedidoDespues } = await svc.from('pedidos').select('total_usd,estado').eq('id', pedidoId).maybeSingle();
  check(
    pedidoDespues?.estado === 'cancelado' || Number(pedidoDespues?.total_usd) < Number(pedidoAntes?.total_usd),
    `el total se recalcula tras quitar el renglon (antes ${pedidoAntes?.total_usd}, despues ${pedidoDespues?.total_usd}, estado ${pedidoDespues?.estado})`
  );
} catch (e) {
  console.log('  XX  Excepción: ' + e.message);
  fallos++;
} finally {
  await limpiar();
  console.log('\nLimpieza hecha (cuenta, pedidos y usuarios de prueba fuera)');
}

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