// Verifica las acciones nuevas de la EF gestionar-mesero contra la BD viva:
// editar (nombre/telefono) y resetear_clave, con el candado de que solo el
// DUEÑO administra (un mesero no puede editarse ni cambiarse la clave solo).
// 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);
}

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 { data: rest } = await svc.from('restaurantes').select('id').eq('slug', 'demo-gustito').maybeSingle();
if (!rest?.id) {
  console.log('Demo no disponible');
  process.exit(1);
}
const REST = rest.id;

const EMAIL_DUE = 'admin.test.mesero@gustitoxpress.app';
const EMAIL_MES = 'staff.test.mesero@gustitoxpress.app';
const CLAVE_DUE = 'AdminTest2026!';
const CLAVE1 = 'Mesero1Test!';
const CLAVE2 = 'Mesero2Nueva!';
let duenoUid, meseroUid;

const limpiar = async () => {
  try {
    const { data: list } = await svc.auth.admin.listUsers({ page: 1, perPage: 1000 });
    for (const u of list?.users ?? []) {
      if (u.email === EMAIL_DUE || u.email === EMAIL_MES) await svc.auth.admin.deleteUser(u.id).catch(() => {});
    }
  } catch {
    /* ignore */
  }
  if (duenoUid) await svc.auth.admin.deleteUser(duenoUid).catch(() => {});
  if (meseroUid) await svc.auth.admin.deleteUser(meseroUid).catch(() => {});
};

// Invoca la EF con la sesion de `cli`; devuelve {error} legible.
const invocar = async (cli, body) => {
  const { data, error } = await cli.functions.invoke('gestionar-mesero', { body });
  if (error) {
    let m = error.message;
    try {
      m = (await error.context.json()).error ?? m;
    } catch {
      /* sin cuerpo */
    }
    return { error: m };
  }
  if (data?.error) return { error: data.error };
  return { data };
};

try {
  await limpiar();
  // Dueño del demo.
  const { data: ud } = await svc.auth.admin.createUser({ email: EMAIL_DUE, password: CLAVE_DUE, email_confirm: true });
  duenoUid = ud.user.id;
  await svc.from('perfiles').upsert({ id: duenoUid, rol: 'dueno', restaurante_id: REST, nombre: 'Admin Test' });

  const dueno = nuevo();
  await dueno.auth.signInWithPassword({ email: EMAIL_DUE, password: CLAVE_DUE });
  console.log('Dueño listo\n');

  // ===== Crear el mesero via EF =====
  const rCrear = await invocar(dueno, { accion: 'crear', nombre: 'Mesero Uno', email: EMAIL_MES, password: CLAVE1, telefono: '04140000000' });
  check(!rCrear.error && rCrear.data?.mesero_id, 'Dueño crea el mesero' + (rCrear.error ? ' -> ' + rCrear.error : ''));
  meseroUid = rCrear.data?.mesero_id;

  // ===== Editar nombre/telefono =====
  const rEdit = await invocar(dueno, { accion: 'editar', mesero_id: meseroUid, nombre: 'Mesero Editado', telefono: '04249999999' });
  check(!rEdit.error, 'Dueño edita nombre y telefono' + (rEdit.error ? ' -> ' + rEdit.error : ''));
  const { data: perf } = await svc.from('perfiles').select('nombre,telefono').eq('id', meseroUid).maybeSingle();
  check(perf?.nombre === 'Mesero Editado' && perf?.telefono === '04249999999', 'El perfil quedo actualizado en la BD');

  // ===== El MESERO no puede administrarse solo =====
  const mesero = nuevo();
  const inMes1 = await mesero.auth.signInWithPassword({ email: EMAIL_MES, password: CLAVE1 });
  check(!inMes1.error && inMes1.data?.session, 'El mesero entra con su clave original');
  const rMesEdit = await invocar(mesero, { accion: 'editar', mesero_id: meseroUid, nombre: 'Hacker' });
  check(!!rMesEdit.error, 'Un mesero NO puede editar (solo el dueño): ' + (rMesEdit.error ?? 'SIN CANDADO!'));
  const rMesClave = await invocar(mesero, { accion: 'resetear_clave', mesero_id: meseroUid, password: 'loQueSea9' });
  check(!!rMesClave.error, 'Un mesero NO puede resetear claves: ' + (rMesClave.error ?? 'SIN CANDADO!'));

  // ===== Resetear la clave (dueño) y verificar login =====
  const rReset = await invocar(dueno, { accion: 'resetear_clave', mesero_id: meseroUid, password: CLAVE2 });
  check(!rReset.error, 'Dueño resetea la clave del mesero' + (rReset.error ? ' -> ' + rReset.error : ''));
  const inNueva = await nuevo().auth.signInWithPassword({ email: EMAIL_MES, password: CLAVE2 });
  check(!inNueva.error && inNueva.data?.session, 'El mesero entra con la clave NUEVA');
  const inVieja = await nuevo().auth.signInWithPassword({ email: EMAIL_MES, password: CLAVE1 });
  check(!!inVieja.error, 'La clave VIEJA ya no sirve');

  // ===== Clave corta rechazada =====
  const rCorta = await invocar(dueno, { accion: 'resetear_clave', mesero_id: meseroUid, password: '123' });
  check(!!rCorta.error, 'Rechaza clave de menos de 6 caracteres: ' + (rCorta.error ?? 'LA ACEPTO!'));
} catch (e) {
  console.log('  XX  Excepción: ' + e.message);
  fallos++;
} finally {
  await limpiar();
  console.log('\nLimpieza hecha');
}

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