-- Harden default skills so platform-provided skills do not weaken quota/RLS guarantees.

CREATE OR REPLACE VIEW public.user_skill_limits
WITH (security_invoker = true)
AS
SELECT
  p.id AS user_id,
  pl.slug AS plan_slug,
  CASE
    WHEN pl.slug IS NULL THEN NULL::integer
    WHEN pl.slug = 'basic' THEN 5
    WHEN pl.slug = 'starter' THEN 15
    WHEN pl.slug = 'professional' THEN 50
    WHEN pl.slug = 'enterprise' THEN 999999
    ELSE NULL::integer
  END AS max_skills,
  (
    SELECT count(*)::integer
      FROM public.skills sk
     WHERE sk.user_id = p.id
       AND sk.status <> 'archived'
       AND COALESCE(sk.is_default, false) = false
  ) AS current_skills_count
FROM public.profiles p
LEFT JOIN public.subscriptions s
  ON s.user_id = p.id
 AND s.status = ANY (ARRAY['active'::text, 'trialing'::text])
LEFT JOIN public.plans pl ON pl.id = s.plan_id;

GRANT SELECT ON public.user_skill_limits TO authenticated;
GRANT SELECT ON public.user_skill_limits TO service_role;

CREATE OR REPLACE FUNCTION public.enforce_skill_limit()
RETURNS trigger
LANGUAGE plpgsql
SECURITY DEFINER
SET search_path = public
AS $$
DECLARE
  v_max int;
  v_count int;
  v_request_role text := COALESCE(current_setting('request.jwt.claim.role', true), '');
BEGIN
  IF COALESCE(NEW.is_default, false) THEN
    IF v_request_role = 'service_role' THEN
      RETURN NEW;
    END IF;

    NEW.is_default := false;
  END IF;

  SELECT max_skills, current_skills_count
    INTO v_max, v_count
  FROM public.user_skill_limits
  WHERE user_id = NEW.user_id;

  IF v_max IS NULL THEN
    RAISE EXCEPTION 'Sem assinatura ativa para criar skills'
      USING ERRCODE = 'P0001';
  END IF;

  IF v_count >= v_max THEN
    RAISE EXCEPTION 'Limite de skills atingido para o plano'
      USING ERRCODE = 'P0002';
  END IF;

  RETURN NEW;
END;
$$;

CREATE OR REPLACE FUNCTION public.protect_skill_default_flag()
RETURNS trigger
LANGUAGE plpgsql
SECURITY DEFINER
SET search_path = public
AS $$
DECLARE
  v_request_role text := COALESCE(current_setting('request.jwt.claim.role', true), '');
BEGIN
  IF v_request_role = 'service_role' THEN
    RETURN NEW;
  END IF;

  IF TG_OP = 'INSERT' THEN
    NEW.is_default := false;
  ELSIF TG_OP = 'UPDATE' THEN
    NEW.is_default := OLD.is_default;
  END IF;

  RETURN NEW;
END;
$$;

DROP TRIGGER IF EXISTS trigger_protect_skill_default_flag ON public.skills;
CREATE TRIGGER trigger_protect_skill_default_flag
  BEFORE INSERT OR UPDATE ON public.skills
  FOR EACH ROW EXECUTE FUNCTION public.protect_skill_default_flag();

REVOKE EXECUTE ON FUNCTION public.enforce_skill_limit() FROM anon, authenticated, public;
REVOKE EXECUTE ON FUNCTION public.protect_skill_default_flag() FROM anon, authenticated, public;
