-- ============================================================
-- Gustito Express — la anon key sale del codigo y pasa a Vault.
--
-- El trigger de push llama a la Edge Function con pg_net y necesita
-- mandar la apikey. Estaba escrita a mano dentro del cuerpo de la
-- funcion. La clave anon es PUBLICA por diseño (viaja en el navegador
-- de cada cliente), asi que esto no cierra ninguna fuga; es politica
-- del repo: ningun archivo versionado lleva algo con forma de token.
--
-- Ventaja real: si algun dia la anon rota, se actualiza el secreto en
-- Vault y el push sigue funcionando sin tocar la base ni redeployar.
--
-- El valor vive en vault.secrets con nombre 'anon_key' (se cargo con
-- vault.create_secret fuera del repo). Si en un entorno nuevo no
-- existe, el push simplemente no sale: nunca rompe el pedido.
-- ============================================================
create or replace function public.tg_notificar_push()
returns trigger
language plpgsql security definer set search_path to 'public'
as $function$
declare
  v_eventos text[] := '{}';
  v_evento text;
  v_secret text;
  v_url text := 'https://szzhhlevtrcambcoytiz.supabase.co/functions/v1/enviar-push';
  v_anon text;
begin
  if TG_OP = 'INSERT' then
    v_eventos := array_append(v_eventos, 'nuevo_pedido');
  elsif TG_OP = 'UPDATE' then
    -- Repartidores
    if new.tipo_entrega = 'delivery' and new.estado = 'listo' and new.repartidor_id is null
       and old.estado is distinct from 'listo' then
      v_eventos := array_append(v_eventos, 'listo_pool');
    end if;
    if new.repartidor_id is not null and old.repartidor_id is null and new.estado <> 'en_camino' then
      v_eventos := array_append(v_eventos, 'asignado');
    end if;
    -- Cliente (segun cambio de estado de SU pedido)
    if old.estado is distinct from new.estado then
      if new.estado = 'confirmado' then
        v_eventos := array_append(v_eventos, 'cliente_preparando');
      elsif new.estado = 'en_camino' then
        v_eventos := array_append(v_eventos, 'cliente_en_camino');
      elsif new.estado = 'listo' and new.tipo_entrega <> 'delivery' then
        v_eventos := array_append(v_eventos, 'cliente_listo');
      end if;
    end if;
  end if;

  if array_length(v_eventos, 1) is null then return null; end if;

  begin
    select decrypted_secret into v_secret from vault.decrypted_secrets where name = 'push_secret' limit 1;
    select decrypted_secret into v_anon   from vault.decrypted_secrets where name = 'anon_key'    limit 1;
    foreach v_evento in array v_eventos loop
      perform net.http_post(
        url := v_url,
        headers := jsonb_build_object(
          'Content-Type', 'application/json',
          'apikey', coalesce(v_anon, ''),
          'x-push-secret', coalesce(v_secret, '')
        ),
        body := jsonb_build_object('pedido_id', new.id, 'evento', v_evento)
      );
    end loop;
  exception when others then
    -- El push es best-effort: nunca dejar que rompa el insert/update del pedido.
    null;
  end;

  return null;
end;
$function$;
