// Verifica el fix del "coje culo" reportado por Gilberto: una mesa con
// TODO entregado y sin cobro debe verse marcada como "falta cobrar" en
// mis_cuentas_mesa (todo_entregado=true), y crear_pedido para mesa siempre
// guarda metodo_pago='efectivo' (el POS ya no deja elegir uno decorativo).
// Usa el restaurante DEMO, mesa TF96, un staff temporal, 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 = 'TF96';

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 = 'staff.test.faltacobrar@gustitoxpress.app';
const CLAVE = 'FaltaCobrar2026!';
let staffUid, cuentaId;

const limpiar = async () => {
  if (cuentaId) {
    await svc.from('pagos_mesa').delete().eq('cuenta_id', cuentaId);
    await svc.from('pedidos').update({ cuenta_id: null }).eq('cuenta_id', cuentaId);
    await svc.from('cuentas_mesa').delete().eq('id', cuentaId);
  }
  if (staffUid) await svc.auth.admin.deleteUser(staffUid).catch(() => {});
};

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

  const { data: u, error: eU } = await svc.auth.admin.createUser({ email: EMAIL, password: CLAVE, email_confirm: true });
  if (eU) throw new Error('createUser: ' + eU.message);
  staffUid = u.user.id;
  await svc.from('perfiles').upsert({ id: staffUid, rol: 'staff', restaurante_id: REST, nombre: 'Staff Falta Cobrar Test' });

  const staff = nuevo();
  await staff.auth.signInWithPassword({ email: EMAIL, password: CLAVE });

  const { data: cId, error: eAbrir } = await staff.rpc('abrir_mesa', { p_mesa: MESA, p_comensales: 1, p_modo: 'unica' });
  check(!eAbrir && !!cId, 'abre la mesa' + (eAbrir ? ' -> ' + eAbrir.message : ''));
  cuentaId = cId;

  // Simula lo que el POS manda ahora: p_metodo_pago siempre 'efectivo' para mesa,
  // aunque el mesero "hubiera elegido" otra cosa (ya no puede, pero el backend
  // no debe depender de que el frontend lo mande bien).
  const { data: ped, error: eCrear } = await staff.rpc('crear_pedido', {
    p_restaurante_id: REST,
    p_cliente_nombre: 'Cliente Falta Cobrar Test',
    p_cliente_telefono: '04120008888',
    p_tipo_entrega: 'mesa',
    p_metodo_pago: 'efectivo',
    p_items: [{ producto_id: PROD_ID, cantidad: 1 }],
    p_mesa: MESA,
  });
  check(!eCrear && !!ped?.[0]?.pedido_id, 'toma el pedido en la mesa' + (eCrear ? ' -> ' + eCrear.message : ''));
  const pedidoId = ped?.[0]?.pedido_id;

  // Antes de entregar: todo_entregado debe ser false (el pedido sigue 'confirmado').
  const { data: lista1 } = await staff.rpc('mis_cuentas_mesa', { p_restaurante_id: REST });
  const fila1 = (lista1 ?? []).find((c) => c.mesa === MESA);
  check(fila1?.todo_entregado === false, `antes de entregar, todo_entregado es false (vino: ${fila1?.todo_entregado})`);

  // Marca el pedido como entregado (preparando -> listo -> entregado, mesa no es delivery).
  await staff.rpc('cambiar_estado_pedido', { p_pedido_id: pedidoId, p_nuevo_estado: 'preparando' });
  await staff.rpc('cambiar_estado_pedido', { p_pedido_id: pedidoId, p_nuevo_estado: 'listo' });
  const { error: eEntregar } = await staff.rpc('cambiar_estado_pedido', { p_pedido_id: pedidoId, p_nuevo_estado: 'entregado' });
  check(!eEntregar, 'marca el pedido como entregado' + (eEntregar ? ' -> ' + eEntregar.message : ''));

  // Ahora, sin ningun cobro registrado: todo_entregado debe ser true.
  const { data: lista2 } = await staff.rpc('mis_cuentas_mesa', { p_restaurante_id: REST });
  const fila2 = (lista2 ?? []).find((c) => c.mesa === MESA);
  check(fila2?.todo_entregado === true, `tras entregar sin cobrar, todo_entregado es true (vino: ${fila2?.todo_entregado})`);
  check(Number(fila2?.pagado_usd ?? -1) === 0, 'pagado_usd sigue en 0 (nadie cobro)');

  // Si se cobra y libera la mesa, deja de aparecer en mis_cuentas_mesa (se cierra).
  const { error: eCobrar } = await staff.rpc('cobrar_y_cerrar_mesa', { p_cuenta_id: cuentaId, p_metodo: 'efectivo' });
  check(!eCobrar, 'cobrar y liberar funciona normalmente' + (eCobrar ? ' -> ' + eCobrar.message : ''));
  const { data: lista3 } = await staff.rpc('mis_cuentas_mesa', { p_restaurante_id: REST });
  const fila3 = (lista3 ?? []).find((c) => c.mesa === MESA);
  check(!fila3, 'tras cobrar, la mesa ya no aparece como activa (se cerro)');
} catch (e) {
  console.log('  XX  Excepción: ' + e.message);
  fallos++;
} finally {
  await limpiar();
  console.log('\nLimpieza hecha (mesa, pedido y usuario de prueba fuera)');
}

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