// Verifica 2 features nuevas pedidas por Gilberto:
// A) subir comprobante desde el POS del mesero (registrar_comprobante + storage).
// B) reporte_pagos: el DUEÑO filtra por metodo y ve cada pago con su referencia,
//    uniendo pagos (mostrador/delivery) y pagos_mesa (mesa); un mesero NO puede.
// Usa el restaurante DEMO, mesa TF98, 1 dueño temporal + 1 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 = 'TF98';

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 = 'staff.test.comprobante@gustitoxpress.app';
const EMAIL_DUENO = 'dueno.test.reporte@gustitoxpress.app';
const CLAVE = 'CompRep2026!';
let uidStaff, uidDueno;
const pedidosCreados = [];
const rutasSubidas = [];
let cuentaMesaId;

const limpiar = async () => {
  for (const ruta of rutasSubidas) await svc.storage.from('comprobantes').remove([ruta]).catch(() => {});
  for (const id of pedidosCreados) {
    await svc.from('pagos').delete().eq('pedido_id', id);
    await svc.from('pedido_items').delete().eq('pedido_id', id);
    await svc.from('pedidos').delete().eq('id', id);
  }
  if (cuentaMesaId) {
    await svc.from('pagos_mesa').delete().eq('cuenta_id', cuentaMesaId);
    await svc.from('pedidos').update({ cuenta_id: null }).eq('cuenta_id', cuentaMesaId);
    await svc.from('cuentas_mesa').delete().eq('id', cuentaMesaId);
  }
  if (uidStaff) await svc.auth.admin.deleteUser(uidStaff).catch(() => {});
  if (uidDueno) await svc.auth.admin.deleteUser(uidDueno).catch(() => {});
};

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

  const { data: uS, error: eS } = await svc.auth.admin.createUser({ email: EMAIL_STAFF, password: CLAVE, email_confirm: true });
  if (eS) throw new Error('createUser staff: ' + eS.message);
  uidStaff = uS.user.id;
  await svc.from('perfiles').upsert({ id: uidStaff, rol: 'staff', restaurante_id: REST, nombre: 'Staff Comprobante Test' });

  const { data: uD, error: eD } = await svc.auth.admin.createUser({ email: EMAIL_DUENO, password: CLAVE, email_confirm: true });
  if (eD) throw new Error('createUser dueno: ' + eD.message);
  uidDueno = uD.user.id;
  // Ojo: el demo YA tiene un dueño real; para no chocar, este dueño de prueba
  // se crea de OTRO restaurante ficticio -- pero reporte_pagos exige fn_es_dueno_de
  // del restaurante DEMO, asi que hay que asignarlo como dueno del MISMO REST.
  // Esto simula un segundo admin/dueno del mismo negocio (escenario valido).
  await svc.from('perfiles').upsert({ id: uidDueno, rol: 'dueno', restaurante_id: REST, nombre: 'Dueño Reporte Test' });

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

  // --- A) Comprobante desde el POS: crear pedido, subir imagen, registrar ---
  const { data: pm, error: ePm } = await staff.rpc('crear_pedido', {
    p_restaurante_id: REST,
    p_cliente_nombre: 'Cliente Comprobante Test',
    p_cliente_telefono: '04120005555',
    p_tipo_entrega: 'pickup',
    p_metodo_pago: 'pago_movil',
    p_items: [{ producto_id: PROD_ID, cantidad: 1 }],
    p_referencia: '00199999999',
  });
  check(!ePm && !!pm?.[0]?.pedido_id, 'crear_pedido con pago_movil funciona' + (ePm ? ' -> ' + ePm.message : ''));
  const pedidoId = pm?.[0]?.pedido_id;
  if (pedidoId) pedidosCreados.push(pedidoId);

  const fakeImg = new Blob([new Uint8Array([0xff, 0xd8, 0xff, 0xdb, 0, 0, 0])], { type: 'image/jpeg' });
  const ruta = `${pedidoId}/${crypto.randomUUID()}.jpg`;
  rutasSubidas.push(ruta);
  const { error: eUp } = await staff.storage.from('comprobantes').upload(ruta, fakeImg, { contentType: 'image/jpeg' });
  check(!eUp, 'el mesero (autenticado) puede subir al bucket comprobantes' + (eUp ? ' -> ' + eUp.message : ''));

  const { error: eReg } = await staff.rpc('registrar_comprobante', {
    p_pedido_id: pedidoId,
    p_referencia: '',
    p_comprobante_url: ruta,
  });
  check(!eReg, 'registrar_comprobante funciona para un mesero autenticado' + (eReg ? ' -> ' + eReg.message : ''));
  const { data: pagoFila } = await svc.from('pagos').select('comprobante_url,estado,referencia').eq('pedido_id', pedidoId).maybeSingle();
  check(pagoFila?.comprobante_url === ruta, `comprobante_url queda guardado (vino: ${pagoFila?.comprobante_url})`);
  check(pagoFila?.estado === 'verificando', `el estado pasa a 'verificando' al subir comprobante (vino: ${pagoFila?.estado})`);
  check(pagoFila?.referencia === '00199999999', 'la referencia original NO se pisa (mando vacio a registrar_comprobante)');

  // --- B) reporte_pagos: dueño ve el pago recien creado, filtrado por pago_movil ---
  const desde = new Date(Date.now() - 60 * 60 * 1000).toISOString();
  const { data: rep, error: eRep } = await dueno.rpc('reporte_pagos', {
    p_restaurante_id: REST,
    p_desde: desde,
    p_metodo: 'pago_movil',
  });
  check(!eRep, 'dueño puede llamar reporte_pagos' + (eRep ? ' -> ' + eRep.message : ''));
  const filaPedido = (rep ?? []).find((r) => r.descripcion === (pm?.[0]?.codigo));
  check(!!filaPedido, 'el pago del pedido de mostrador aparece en el reporte filtrado por pago_movil');
  check(filaPedido?.referencia === '00199999999', `trae la referencia correcta (vino: ${filaPedido?.referencia})`);
  check(filaPedido?.comprobante_url === ruta, 'trae el comprobante_url correcto');

  // --- Mesero NO puede ver el reporte (es gerencial) ---
  const { error: eRepStaff } = await staff.rpc('reporte_pagos', { p_restaurante_id: REST, p_desde: desde });
  check(!!eRepStaff, 'un mesero NO puede llamar reporte_pagos (sin permiso)');

  // --- Unifica tambien pagos de MESA: abrir mesa, cobrar con pago_movil, debe aparecer ---
  const { data: cId } = await staff.rpc('abrir_mesa', { p_mesa: MESA, p_comensales: 1, p_modo: 'unica' });
  cuentaMesaId = cId;
  const { data: pedMesa } = await staff.rpc('crear_pedido', {
    p_restaurante_id: REST,
    p_cliente_nombre: 'Cliente Mesa Test',
    p_cliente_telefono: '04120006666',
    p_tipo_entrega: 'mesa',
    p_metodo_pago: 'efectivo',
    p_items: [{ producto_id: PROD_ID, cantidad: 1 }],
    p_mesa: MESA,
  });
  const { error: eCobrar } = await staff.rpc('cobrar_y_cerrar_mesa', {
    p_cuenta_id: cuentaMesaId,
    p_metodo: 'pago_movil',
    p_referencia: '00277777777',
  });
  check(!eCobrar, 'cobrar la mesa con pago_movil funciona' + (eCobrar ? ' -> ' + eCobrar.message : ''));

  const { data: rep2, error: eRep2 } = await dueno.rpc('reporte_pagos', {
    p_restaurante_id: REST,
    p_desde: desde,
    p_metodo: 'pago_movil',
  });
  check(!eRep2, 'reporte_pagos vuelve a funcionar tras el cobro de mesa');
  const filaMesa = (rep2 ?? []).find((r) => r.descripcion === `Mesa ${MESA}` && r.referencia === '00277777777');
  check(!!filaMesa, 'el pago de la MESA (pagos_mesa) tambien aparece unificado en el reporte');
  check(filaMesa?.origen === 'mesa', `el origen queda marcado como 'mesa' (vino: ${filaMesa?.origen})`);
} catch (e) {
  console.log('  XX  Excepción: ' + e.message);
  fallos++;
} finally {
  await limpiar();
  console.log('\nLimpieza hecha (pedidos, pagos, mesa, comprobante y usuarios de prueba fuera)');
}

console.log(fallos === 0 ? '\nCOMPROBANTE + REPORTE PAGOS OK' : `\nCOMPROBANTE + REPORTE PAGOS: ${fallos} FALLO(S)`);
process.exit(fallos === 0 ? 0 : 1);
