CREATE OR REPLACE FUNCTION public.user_belongs_to_association(_user_id uuid, _association_id uuid)
RETURNS boolean
LANGUAGE sql
STABLE
SECURITY DEFINER
SET search_path = public
AS $$
  SELECT
    public.has_role(_user_id, 'admin'::public.app_role)
    OR public.has_role(_user_id, 'manager'::public.app_role)
    OR EXISTS (
      SELECT 1
      FROM public.owners o
      WHERE o.user_id = _user_id
        AND o.association_id = _association_id
    )
    OR EXISTS (
      SELECT 1
      FROM public.board_members bm
      WHERE bm.user_id = _user_id
        AND bm.association_id = _association_id
    )
$$;

CREATE OR REPLACE FUNCTION public.can_comment_on_status_update(_user_id uuid, _status_update_id uuid)
RETURNS boolean
LANGUAGE sql
STABLE
SECURITY DEFINER
SET search_path = public
AS $$
  SELECT EXISTS (
    SELECT 1
    FROM public.status_updates su
    WHERE su.id = _status_update_id
      AND public.user_belongs_to_association(_user_id, su.association_id)
  )
$$;

CREATE OR REPLACE FUNCTION public.can_comment_on_entity(_user_id uuid, _entity_type text, _entity_id uuid)
RETURNS boolean
LANGUAGE sql
STABLE
SECURITY DEFINER
SET search_path = public
AS $$
  SELECT CASE _entity_type
    WHEN 'board_vote' THEN EXISTS (
      SELECT 1 FROM public.board_votes bv
      WHERE bv.id = _entity_id
        AND public.user_belongs_to_association(_user_id, bv.association_id)
    )
    WHEN 'legal_matter' THEN EXISTS (
      SELECT 1 FROM public.legal_matters lm
      WHERE lm.id = _entity_id
        AND public.user_belongs_to_association(_user_id, lm.association_id)
    )
    WHEN 'bid_quote' THEN EXISTS (
      SELECT 1 FROM public.bids_quotes bq
      WHERE bq.id = _entity_id
        AND public.user_belongs_to_association(_user_id, bq.association_id)
    )
    WHEN 'arc_application' THEN EXISTS (
      SELECT 1 FROM public.arc_applications aa
      WHERE aa.id = _entity_id
        AND public.user_belongs_to_association(_user_id, aa.association_id)
    )
    WHEN 'client_request' THEN EXISTS (
      SELECT 1 FROM public.client_requests cr
      WHERE cr.id = _entity_id
        AND public.user_belongs_to_association(_user_id, cr.association_id)
    )
    WHEN 'status_update' THEN public.can_comment_on_status_update(_user_id, _entity_id)
    ELSE false
  END
$$;

ALTER POLICY "Authenticated users can insert status_update_comments"
ON public.status_update_comments
WITH CHECK (
  auth.uid() = user_id
  AND public.can_comment_on_status_update(auth.uid(), status_update_id)
);

ALTER POLICY "Authenticated users can insert own entity_comments"
ON public.entity_comments
WITH CHECK (
  auth.uid() = user_id
  AND public.can_comment_on_entity(auth.uid(), entity_type, entity_id)
);