-- Auditoria legal 2026-07-23, fixes de datos personales:
-- (A) cerrar_negocio ahora tambien borra el enlace del comprobante de los
--     PAGOS DE MESA (antes solo la referencia) y las llaves push del cliente
--     que quedaban vivas en pedidos. La Politica de Privacidad promete ocultar
--     los comprobantes al cierre; ahora el codigo cumple para mesa tambien.
-- (C) Red de seguridad de retencion: dos funciones SOLO service_role que usa
--     la Edge Function limpiar-datos-viejos (cron diario): anonimiza pedidos
--     con mas de N dias aunque el negocio nunca cierre jornada, y entrega/borra
--     los punteros de comprobantes viejos para eliminar sus archivos.

create or replace function public.cerrar_negocio()
 returns void
 language plpgsql
 security definer
 set search_path to 'public'
as $function$
declare v_rest uuid := fn_mi_restaurante();
begin
  if v_rest is null or not (fn_es_dueno_de(v_rest) or fn_es_admin()) then
    raise exception 'Sin permiso';
  end if;
  -- Cierra el negocio Y sella la jornada (desde aqui arranca la siguiente).
  update public.restaurantes set abierto = false, ultimo_cierre_en = now() where id = v_rest;
  -- ocultar datos personales (se conserva el pedido y sus totales)
  update public.pedidos
     set cliente_nombre     = 'Cliente',
         cliente_telefono   = '',
         cliente_cedula     = null,
         direccion          = null,
         direccion_latitud  = null,
         direccion_longitud = null,
         nota               = null,
         push_endpoint      = null,
         push_p256dh        = null,
         push_auth          = null
   where restaurante_id = v_rest
     and (cliente_telefono <> '' or push_endpoint is not null);
  update public.pagos
     set referencia = null, comprobante_url = null
   where pedido_id in (select id from public.pedidos where restaurante_id = v_rest);
  update public.pagos_mesa
     set referencia = null, comprobante_url = null
   where restaurante_id = v_rest
     and (referencia is not null or comprobante_url is not null);
  update public.repartidores set estado = 'disponible' where restaurante_id = v_rest and estado = 'ocupado';
end;
$function$;

-- (C1) Rutas de comprobantes viejos (para que la EF borre los ARCHIVOS antes
-- de soltar los punteros). Solo service_role.
create or replace function public.fn_comprobantes_viejos(p_dias integer default 90, p_max integer default 200)
 returns table (ruta text)
 language sql
 security definer
 set search_path to 'public'
as $function$
  select p.comprobante_url
    from public.pagos p
    join public.pedidos pe on pe.id = p.pedido_id
   where p.comprobante_url is not null
     and p.creado_en < now() - make_interval(days => p_dias)
  union all
  select pm.comprobante_url
    from public.pagos_mesa pm
   where pm.comprobante_url is not null
     and pm.creado_en < now() - make_interval(days => p_dias)
  limit greatest(p_max, 1);
$function$;

-- (C2) Anonimiza lo viejo y suelta los punteros. Solo service_role.
create or replace function public.fn_limpiar_datos_viejos(p_dias integer default 90)
 returns jsonb
 language plpgsql
 security definer
 set search_path to 'public'
as $function$
declare
  v_corte timestamptz := now() - make_interval(days => greatest(p_dias, 30));
  v_pedidos integer;
  v_pagos integer;
  v_pagos_mesa integer;
begin
  update public.pedidos
     set cliente_nombre     = 'Cliente',
         cliente_telefono   = '',
         cliente_cedula     = null,
         direccion          = null,
         direccion_latitud  = null,
         direccion_longitud = null,
         nota               = null,
         push_endpoint      = null,
         push_p256dh        = null,
         push_auth          = null
   where recibido_en < v_corte
     and (cliente_telefono <> '' or push_endpoint is not null);
  get diagnostics v_pedidos = row_count;

  update public.pagos p
     set referencia = null, comprobante_url = null
   where p.creado_en < v_corte
     and (p.referencia is not null or p.comprobante_url is not null);
  get diagnostics v_pagos = row_count;

  update public.pagos_mesa
     set referencia = null, comprobante_url = null
   where creado_en < v_corte
     and (referencia is not null or comprobante_url is not null);
  get diagnostics v_pagos_mesa = row_count;

  return jsonb_build_object('pedidos', v_pedidos, 'pagos', v_pagos, 'pagos_mesa', v_pagos_mesa);
end;
$function$;

-- Candado: estas dos son herramientas internas del cron, nadie mas las llama.
revoke all on function public.fn_comprobantes_viejos(integer, integer) from public, anon, authenticated;
revoke all on function public.fn_limpiar_datos_viejos(integer) from public, anon, authenticated;
grant execute on function public.fn_comprobantes_viejos(integer, integer) to service_role;
grant execute on function public.fn_limpiar_datos_viejos(integer) to service_role;
