// Horario por categoria: bloquea la venta EN LINEA, el personal vende igual.
// Corre contra la BD viva usando el restaurante DEMO (Dona Carmen). Siembra el
// horario, prueba los dos caminos y deja todo como estaba.
//
//   SUPABASE_URL=... SUPABASE_ANON=... SUPABASE_SERVICE_KEY=... node scripts/test_horario_categoria.mjs
import { createClient } from '@supabase/supabase-js';

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

const REST = '52057e85-f82a-4aaa-8577-3a75d269eb65'; // demo-gustito
const PRODUCTO = '86506731-73b0-4b23-b70f-08c28ca33210'; // Arepa Domino
const CATEGORIA = 'a9bc4156-e432-4f6d-9d88-f2db91f4e8a2'; // Arepas (demo)
const DUENO = { email: 'demo.negocio@gustitoxpress.app', password: 'GustitoDemo2026' };

const admin = createClient(URL, SERVICE, { auth: { persistSession: false } });
const anon = createClient(URL, ANON, { auth: { persistSession: false } });

let ok = 0, fail = 0;
const chk = (n, cond, extra = '') => {
  if (cond) { ok++; console.log(`  ok   ${n}${extra ? ' · ' + extra : ''}`); }
  else { fail++; console.log(`  FAIL ${n}${extra ? ' · ' + extra : ''}`); }
};

const pedido = (cli, extra = {}) =>
  cli.rpc('crear_pedido', {
    p_restaurante_id: REST,
    p_cliente_nombre: 'Prueba horario ' + Math.random().toString(36).slice(2, 7),
    p_cliente_telefono: '0412' + String(Date.now()).slice(-7),
    p_tipo_entrega: 'pickup',
    p_metodo_pago: 'efectivo',
    p_items: [{ producto_id: PRODUCTO, cantidad: 1 }],
    ...extra,
  });

// Si el update falla (tipico: PostgREST con la cache de esquema vieja tras un
// ALTER TABLE) hay que reventar aqui, no seguir probando contra un horario que
// nunca se guardo: eso da falsos verdes.
const setHorario = async (dias, desde, hasta) => {
  const { data, error } = await admin
    .from('categorias')
    .update({ dias_semana: dias, hora_desde: desde, hora_hasta: hasta })
    .eq('id', CATEGORIA)
    .select('dias_semana,hora_desde,hora_hasta');
  if (error) throw new Error('no se pudo sembrar el horario: ' + error.message);
  if (!data?.length) throw new Error('el horario no se guardo (0 filas): revisa la llave o el id de la categoria');
  console.log(`     [horario sembrado: dias=${JSON.stringify(data[0].dias_semana)} desde=${data[0].hora_desde} hasta=${data[0].hora_hasta}]`);
};

const creados = [];
const guardar = (id) => { if (id) creados.push(id); };

try {
  const hoy = new Date(new Date().toLocaleString('en-US', { timeZone: 'America/Caracas' })).getDay();
  const manana = (hoy + 1) % 7;
  console.log(`Hoy en Venezuela es el dia ${hoy} (0=domingo)`);

  // 0) Sin horario puesto, todo el mundo vende
  await setHorario(null, null, null);
  let r = await pedido(anon);
  chk('sin horario, el cliente compra normal', !r.error, r.error?.message);
  guardar(r.data);

  // 1) Categoria solo para MANANA: el cliente no puede
  await setHorario([manana], null, null);
  r = await pedido(anon);
  chk('otro dia: el cliente en linea queda bloqueado', !!r.error, r.error?.message ?? 'paso sin error');
  chk('el mensaje nombra el producto', /Arepa Domin/i.test(r.error?.message ?? ''), r.error?.message);

  // 2) El personal SI vende ese mismo dia
  const staff = createClient(URL, ANON, { auth: { persistSession: false } });
  const { error: eLogin } = await staff.auth.signInWithPassword(DUENO);
  chk('entra el dueno del negocio', !eLogin, eLogin?.message);
  r = await pedido(staff);
  chk('el personal vende igual fuera del dia', !r.error, r.error?.message);
  guardar(r.data);

  // 3) Hora: solo a partir de una hora que todavia no llega
  const enDosHoras = new Date(Date.now() + 2 * 3600e3)
    .toLocaleTimeString('en-GB', { timeZone: 'America/Caracas', hour12: false });
  await setHorario(null, enDosHoras, null);
  r = await pedido(anon);
  chk('antes de la hora: el cliente queda bloqueado', !!r.error, r.error?.message ?? 'paso sin error');
  r = await pedido(staff);
  chk('antes de la hora: el personal vende igual', !r.error, r.error?.message);
  guardar(r.data);

  // 4) Franja que cruza la medianoche (17:00 a 02:00) con la hora actual dentro
  const ahora = new Date().toLocaleTimeString('en-GB', { timeZone: 'America/Caracas', hour12: false });
  const unaAntes = new Date(Date.now() - 3600e3).toLocaleTimeString('en-GB', { timeZone: 'America/Caracas', hour12: false });
  const unaDespues = new Date(Date.now() + 3600e3).toLocaleTimeString('en-GB', { timeZone: 'America/Caracas', hour12: false });
  await setHorario(null, unaAntes, unaDespues);
  r = await pedido(anon);
  chk('dentro de la franja: el cliente compra', !r.error, r.error?.message);
  guardar(r.data);

  const { data: cruza } = await admin.rpc('fn_categoria_en_horario', {
    p_dias: null, p_desde: '23:00:00', p_hasta: '02:00:00',
  });
  const dentroDeCruce = ahora >= '23:00:00' || ahora <= '02:00:00';
  chk('franja que cruza la medianoche calcula bien', cruza === dentroDeCruce, `ahora ${ahora}, dio ${cruza}`);

  // 5) Bebidas del demo (sin horario) no se ven afectadas
  await setHorario([manana], null, null);
  r = await anon.rpc('crear_pedido', {
    p_restaurante_id: REST,
    p_cliente_nombre: 'Prueba horario ' + Math.random().toString(36).slice(2, 7),
    p_cliente_telefono: '0412' + String(Date.now()).slice(-7),
    p_tipo_entrega: 'pickup',
    p_metodo_pago: 'efectivo',
    p_items: [{ producto_id: 'c8949986-f063-47a3-8971-331b11e2e7a5', cantidad: 1 }],
  });
  chk('otra categoria sin horario sigue vendiendo', !r.error, r.error?.message);
  guardar(r.data);
} catch (e) {
  fail++;
  console.log('  FAIL excepcion: ' + e.message);
} finally {
  await setHorario(null, null, null);
  for (const id of creados) {
    await admin.from('pedido_items').delete().eq('pedido_id', id);
    await admin.from('pagos').delete().eq('pedido_id', id);
    await admin.from('pedidos').delete().eq('id', id);
  }
  console.log(`\nlimpieza: ${creados.length} pedidos de prueba borrados`);
  console.log(`${ok} ok / ${fail} fail`);
  process.exit(fail ? 1 : 0);
}
