-- 00002_rls_policies.sql
-- MovieDice: Row Level Security policies for all tables

-- =============================================================================
-- Enable RLS on all tables
-- =============================================================================
ALTER TABLE public.users ENABLE ROW LEVEL SECURITY;
ALTER TABLE public.groups ENABLE ROW LEVEL SECURITY;
ALTER TABLE public.group_members ENABLE ROW LEVEL SECURITY;
ALTER TABLE public.movies ENABLE ROW LEVEL SECURITY;
ALTER TABLE public.landing_reel_posters ENABLE ROW LEVEL SECURITY;

-- =============================================================================
-- users: SELECT/UPDATE own row only
-- =============================================================================
CREATE POLICY users_select_own ON public.users
  FOR SELECT USING (auth.uid() = id);

CREATE POLICY users_update_own ON public.users
  FOR UPDATE USING (auth.uid() = id)
  WITH CHECK (auth.uid() = id);

-- =============================================================================
-- groups: SELECT only if user is a member
-- =============================================================================
CREATE POLICY groups_select_member ON public.groups
  FOR SELECT USING (
    EXISTS (
      SELECT 1 FROM public.group_members
      WHERE group_members.group_id = groups.id
        AND group_members.user_id = auth.uid()
    )
  );

-- =============================================================================
-- group_members: complex policies
-- =============================================================================

-- SELECT: can see members of groups you belong to
CREATE POLICY group_members_select ON public.group_members
  FOR SELECT USING (
    EXISTS (
      SELECT 1 FROM public.group_members AS gm
      WHERE gm.group_id = group_members.group_id
        AND gm.user_id = auth.uid()
    )
  );

-- INSERT: blocked for anon users (server-side via service role key only)
-- No INSERT policy = denied by default with RLS enabled

-- DELETE: admin of the group OR self (leaving)
CREATE POLICY group_members_delete ON public.group_members
  FOR DELETE USING (
    group_members.user_id = auth.uid()
    OR EXISTS (
      SELECT 1 FROM public.group_members AS gm
      WHERE gm.group_id = group_members.group_id
        AND gm.user_id = auth.uid()
        AND gm.role = 'admin'
    )
  );

-- UPDATE: prevent role escalation
-- Only admins of the group can update roles, and only they can set role to 'admin'
CREATE POLICY group_members_update ON public.group_members
  FOR UPDATE USING (
    EXISTS (
      SELECT 1 FROM public.group_members AS gm
      WHERE gm.group_id = group_members.group_id
        AND gm.user_id = auth.uid()
        AND gm.role = 'admin'
    )
  )
  WITH CHECK (
    -- Only allow setting role to 'admin' if the current user is an admin of this group
    role = 'member'
    OR EXISTS (
      SELECT 1 FROM public.group_members AS gm
      WHERE gm.group_id = group_members.group_id
        AND gm.user_id = auth.uid()
        AND gm.role = 'admin'
    )
  );

-- =============================================================================
-- movies: full CRUD for group members
-- =============================================================================

-- SELECT: only if member of the owning group
CREATE POLICY movies_select ON public.movies
  FOR SELECT USING (
    EXISTS (
      SELECT 1 FROM public.group_members
      WHERE group_members.group_id = movies.group_id
        AND group_members.user_id = auth.uid()
    )
  );

-- INSERT: member of group + added_by must be auth.uid()
CREATE POLICY movies_insert ON public.movies
  FOR INSERT WITH CHECK (
    added_by = auth.uid()
    AND EXISTS (
      SELECT 1 FROM public.group_members
      WHERE group_members.group_id = movies.group_id
        AND group_members.user_id = auth.uid()
    )
  );

-- UPDATE: member of group + cannot change added_by
CREATE POLICY movies_update ON public.movies
  FOR UPDATE USING (
    EXISTS (
      SELECT 1 FROM public.group_members
      WHERE group_members.group_id = movies.group_id
        AND group_members.user_id = auth.uid()
    )
  )
  WITH CHECK (
    added_by IS NOT DISTINCT FROM (
      SELECT m.added_by FROM public.movies m WHERE m.id = movies.id
    )
    AND EXISTS (
      SELECT 1 FROM public.group_members
      WHERE group_members.group_id = movies.group_id
        AND group_members.user_id = auth.uid()
    )
  );

-- DELETE: member of the owning group
CREATE POLICY movies_delete ON public.movies
  FOR DELETE USING (
    EXISTS (
      SELECT 1 FROM public.group_members
      WHERE group_members.group_id = movies.group_id
        AND group_members.user_id = auth.uid()
    )
  );

-- =============================================================================
-- landing_reel_posters: public read, no client write
-- =============================================================================
CREATE POLICY landing_reel_posters_select ON public.landing_reel_posters
  FOR SELECT USING (true);

-- No INSERT/UPDATE/DELETE policies = service role only (RLS bypassed by service role key)
