-- =============================================================================
-- Migration: 20260419000003_delete_plan_safe
-- V#36 — DELETE de plans sem checagem de assinaturas ativas pode quebrar tenants.
--
-- Cria RPC delete_plan_safe(plan_id) que:
--  - Valida saas_admin
--  - Conta subscriptions ativas (status='active') no plano
--  - Se houver, RAISE EXCEPTION descritivo com a contagem
--  - Se OK, desativa prices ativos e deleta o plano (atomic)
-- =============================================================================

CREATE OR REPLACE FUNCTION public.delete_plan_safe(
  p_plan_id uuid
)
RETURNS jsonb
LANGUAGE plpgsql
SECURITY DEFINER
SET search_path TO 'public'
AS $function$
DECLARE
  v_active_count int;
  v_plan_key     text;
BEGIN
  IF auth.uid() IS NULL THEN
    RAISE EXCEPTION 'Não autenticado' USING ERRCODE = '28000';
  END IF;

  IF NOT public.is_saas_admin() THEN
    RAISE EXCEPTION 'Apenas saas_admin pode deletar planos' USING ERRCODE = '42501';
  END IF;

  IF p_plan_id IS NULL THEN
    RAISE EXCEPTION 'plan_id obrigatório' USING ERRCODE = '22023';
  END IF;

  SELECT key INTO v_plan_key FROM public.plans WHERE id = p_plan_id;
  IF v_plan_key IS NULL THEN
    RAISE EXCEPTION 'plano não encontrado' USING ERRCODE = '22023';
  END IF;

  SELECT COUNT(*) INTO v_active_count
  FROM public.subscriptions
  WHERE plan_id = p_plan_id
    AND status = 'active';

  IF v_active_count > 0 THEN
    RAISE EXCEPTION 'Plano % tem % assinatura(s) ativa(s); migre os tenants antes de deletar.',
      v_plan_key, v_active_count
      USING ERRCODE = 'P0001';
  END IF;

  -- desativa preços ativos antes de deletar
  UPDATE public.plan_prices
     SET is_active = false,
         active_to = now()
   WHERE plan_id = p_plan_id
     AND is_active = true;

  DELETE FROM public.plans WHERE id = p_plan_id;

  RETURN jsonb_build_object(
    'deleted',  true,
    'plan_key', v_plan_key
  );
END;
$function$;

REVOKE ALL ON FUNCTION public.delete_plan_safe(uuid) FROM PUBLIC;
GRANT  EXECUTE ON FUNCTION public.delete_plan_safe(uuid) TO authenticated;
