-- ============================================================
-- Gustito Xpress — el CLIENTE abre/ocupa su mesa al escanear.
--
-- Antes la mesa solo se "ocupaba" al hacer el primer pedido; si el cliente
-- escaneaba y aun no pedia, en el panel salia LIBRE. Ahora, al escanear, el
-- cliente pone su nombre y eso ABRE la mesa (crea la cuenta, sin mesero), asi
-- el mesero la ve ocupada de una. La primera persona queda registrada.
--
-- mis_cuentas_mesa gana "abierta_por": el nombre de quien abrio la mesa (primer
-- comensal, o si no, el nombre del primer pedido) para mostrarlo en el panel.
-- ============================================================

-- ---- abrir_mesa_cliente: el cliente ocupa la mesa con su nombre ----
create or replace function public.abrir_mesa_cliente(p_restaurante_id uuid, p_mesa text, p_nombre text)
returns uuid
language plpgsql security definer set search_path to 'public'
as $function$
declare
  v_rest      public.restaurantes%rowtype;
  v_cuenta_id uuid;
begin
  select * into v_rest from public.restaurantes where id = p_restaurante_id;
  if not found or not v_rest.activo or not v_rest.publicado then
    raise exception 'Restaurante no disponible';
  end if;
  if not v_rest.abierto then
    raise exception 'El restaurante esta cerrado en este momento';
  end if;
  if coalesce(nullif(trim(p_mesa), ''), '') = '' then
    raise exception 'Falta el numero de mesa';
  end if;

  insert into public.cuentas_mesa (restaurante_id, mesa)
    values (p_restaurante_id, trim(p_mesa))
    on conflict (restaurante_id, mesa) where (estado <> 'cerrada') do nothing;
  select id into v_cuenta_id from public.cuentas_mesa
   where restaurante_id = p_restaurante_id and mesa = trim(p_mesa) and estado <> 'cerrada' limit 1;

  -- Primera persona de la mesa (solo si aun no hay comensales y dio nombre).
  if nullif(trim(coalesce(p_nombre, '')), '') is not null
     and not exists (select 1 from public.comensales_mesa where cuenta_id = v_cuenta_id) then
    insert into public.comensales_mesa (cuenta_id, restaurante_id, nombre, orden)
      values (v_cuenta_id, p_restaurante_id, trim(p_nombre), 0);
  end if;

  return v_cuenta_id;
end;
$function$;
grant execute on function public.abrir_mesa_cliente(uuid, text, text) to anon, authenticated;

-- ---- mis_cuentas_mesa: + abierta_por (a nombre de quien esta la mesa) ----
drop function if exists public.mis_cuentas_mesa(uuid);
create function public.mis_cuentas_mesa(p_restaurante_id uuid)
returns table(
  id uuid, mesa text, estado text, total_usd numeric, tasa_bs numeric,
  abierta_en timestamptz, pago_solicitado_en timestamptz, metodo_pago text,
  referencia text, comprobante_url text, n_pedidos integer,
  mesero_id uuid, mesero_nombre text, pagado_usd numeric,
  comensales integer, modo_cuenta text, por_revisar_usd numeric, abierta_por text
)
language sql stable security definer set search_path to 'public'
as $function$
  select c.id, c.mesa, c.estado,
    coalesce((select sum(p.total_usd) from public.pedidos p where p.cuenta_id = c.id and p.estado <> 'cancelado'), 0),
    r.tasa_bs, c.abierta_en, c.pago_solicitado_en, c.metodo_pago, c.referencia, c.comprobante_url,
    (select count(*)::int from public.pedidos p where p.cuenta_id = c.id and p.estado <> 'cancelado'),
    c.mesero_id, c.mesero_nombre,
    coalesce((select sum(pm.monto_usd) from public.pagos_mesa pm where pm.cuenta_id = c.id and pm.verificado), 0),
    c.comensales, c.modo_cuenta,
    coalesce((select sum(pm.monto_usd) from public.pagos_mesa pm where pm.cuenta_id = c.id and not pm.verificado), 0),
    coalesce(
      (select cm.nombre from public.comensales_mesa cm where cm.cuenta_id = c.id order by cm.orden limit 1),
      (select p.cliente_nombre from public.pedidos p where p.cuenta_id = c.id and p.estado <> 'cancelado' order by p.recibido_en limit 1)
    )
  from public.cuentas_mesa c
  join public.restaurantes r on r.id = c.restaurante_id
  where c.restaurante_id = p_restaurante_id
    and c.estado <> 'cerrada'
    and (fn_es_staff_de(c.restaurante_id) or fn_es_admin())
  order by c.abierta_en;
$function$;
grant execute on function public.mis_cuentas_mesa(uuid) to anon, authenticated;
