-- ============================================================
-- Gustito Express — Experiencia del repartidor.
-- La RLS solo deja al repartidor VER sus pedidos asignados. Para el board de
-- entregas disponibles usamos RPCs SECURITY DEFINER acotados a SU restaurante,
-- y la toma es atomica (evita que dos repartidores agarren el mismo pedido).
-- ============================================================

-- Datos del repartidor logueado + su restaurante (punto de retiro).
create or replace function public.mi_perfil_repartidor()
returns table (repartidor_id uuid, estado text, restaurante_id uuid, restaurante_nombre text)
language sql stable security definer set search_path = public
as $$
  select r.id, r.estado, r.restaurante_id, res.nombre
  from public.repartidores r
  join public.restaurantes res on res.id = r.restaurante_id
  where r.perfil_id = auth.uid();
$$;
grant execute on function public.mi_perfil_repartidor() to authenticated;

-- Entregas disponibles: delivery en 'listo' sin repartidor, del/los restaurante(s)
-- donde trabaja el repartidor. Nunca ve pedidos de otro restaurante.
create or replace function public.entregas_disponibles()
returns table (
  pedido_id          uuid,
  codigo             text,
  cliente_nombre     text,
  direccion          text,
  direccion_latitud  double precision,
  direccion_longitud double precision,
  total_usd          numeric,
  restaurante_nombre text,
  listo_en           timestamptz
)
language sql stable security definer set search_path = public
as $$
  select p.id, p.codigo, p.cliente_nombre, p.direccion,
         p.direccion_latitud, p.direccion_longitud, p.total_usd, res.nombre, p.listo_en
  from public.pedidos p
  join public.restaurantes res on res.id = p.restaurante_id
  where p.tipo_entrega = 'delivery'
    and p.estado = 'listo'
    and p.repartidor_id is null
    and p.restaurante_id in (select restaurante_id from public.repartidores where perfil_id = auth.uid())
  order by p.listo_en asc nulls last, p.recibido_en asc;
$$;
grant execute on function public.entregas_disponibles() to authenticated;

-- Tomar una entrega: asignacion atomica al repartidor logueado.
create or replace function public.tomar_pedido(p_pedido_id uuid)
returns text language plpgsql security definer set search_path = public
as $$
declare v_rest uuid; v_rep_id uuid;
begin
  select restaurante_id into v_rest from public.pedidos where id = p_pedido_id;
  if not found then raise exception 'Pedido no existe'; end if;
  select id into v_rep_id from public.repartidores
    where perfil_id = auth.uid() and restaurante_id = v_rest;
  if v_rep_id is null then raise exception 'No eres repartidor de este restaurante'; end if;
  -- solo si sigue libre y listo (carrera entre repartidores)
  update public.pedidos
     set repartidor_id = v_rep_id, estado = 'en_camino', en_camino_en = now()
   where id = p_pedido_id and repartidor_id is null and estado = 'listo' and tipo_entrega = 'delivery';
  if not found then raise exception 'Otro repartidor ya tomo este pedido'; end if;
  update public.repartidores set estado = 'ocupado' where id = v_rep_id;
  return 'en_camino';
end;
$$;
grant execute on function public.tomar_pedido(uuid) to authenticated;

-- Disponibilidad online (disponible) / offline. No pisa 'ocupado' (en entrega).
create or replace function public.cambiar_disponibilidad(p_disponible boolean)
returns text language plpgsql security definer set search_path = public
as $$
declare v_nuevo text;
begin
  v_nuevo := case when p_disponible then 'disponible' else 'offline' end;
  update public.repartidores set estado = v_nuevo
   where perfil_id = auth.uid() and estado <> 'ocupado';
  return v_nuevo;
end;
$$;
grant execute on function public.cambiar_disponibilidad(boolean) to authenticated;
