-- Add `programmer` role to admin-level access checks without granting approval privileges.
--
-- NOTE: This role should have the same access as admins in the UI and for
-- non-approval data access. However, it must NOT be able to approve/reject
-- pass slips, leave applications, swap requests, etc.

-- NOTE: The `programmer` enum value is added in a prior migration so
-- it can safely be used in RLS policies and other schema objects.

-- Teams: allow programmers to manage teams like admins.
DROP POLICY IF EXISTS "Admins can manage teams (select)" ON public.teams;
DROP POLICY IF EXISTS "Admins can manage teams (write)" ON public.teams;

CREATE POLICY "Admins can manage teams (select)" ON public.teams
  FOR SELECT
  USING (
    EXISTS (
      SELECT 1 FROM public.profiles p WHERE p.id = auth.uid() AND p.role IN ('admin', 'programmer')
    )
  );

CREATE POLICY "Admins can manage teams (write)" ON public.teams
  FOR ALL
  USING (
    EXISTS (
      SELECT 1 FROM public.profiles p WHERE p.id = auth.uid() AND p.role IN ('admin', 'programmer')
    )
  )
  WITH CHECK (
    EXISTS (
      SELECT 1 FROM public.profiles p WHERE p.id = auth.uid() AND p.role IN ('admin', 'programmer')
    )
  );

-- Team members: allow programmers to view/insert like admins.
DROP POLICY IF EXISTS "Admins can manage team_members (select)" ON public.team_members;
DROP POLICY IF EXISTS "Admins can manage team_members (write)" ON public.team_members;

CREATE POLICY "Admins can manage team_members (select)" ON public.team_members
  FOR SELECT
  USING (
    EXISTS (
      SELECT 1 FROM public.profiles p WHERE p.id = auth.uid() AND p.role IN ('admin', 'programmer')
    )
  );

CREATE POLICY "Admins can manage team_members (write)" ON public.team_members
  FOR ALL
  USING (
    EXISTS (
      SELECT 1 FROM public.profiles p WHERE p.id = auth.uid() AND p.role IN ('admin', 'programmer')
    )
  )
  WITH CHECK (
    EXISTS (
      SELECT 1 FROM public.profiles p WHERE p.id = auth.uid() AND p.role IN ('admin', 'programmer')
    )
  );

-- Pass slips: allow programmers to view all slips like admins/dispatchers.
DROP POLICY IF EXISTS "pass_slips_select" ON pass_slips;
CREATE POLICY "pass_slips_select" ON pass_slips FOR SELECT TO authenticated
USING (
  user_id = auth.uid()
  OR EXISTS (
    SELECT 1 FROM profiles p WHERE p.id = auth.uid() AND p.role IN ('admin', 'dispatcher', 'programmer')
  )
);

-- Leaves: allow programmers to view/file leaves like admins/dispatchers/it_staff.
DROP POLICY IF EXISTS "Privileged users can view all leaves" ON leave_of_absence;
CREATE POLICY "Privileged users can view all leaves"
  ON leave_of_absence FOR SELECT
  USING (
    EXISTS (
      SELECT 1 FROM profiles
      WHERE profiles.id = auth.uid()
        AND profiles.role IN ('admin', 'dispatcher', 'it_staff', 'programmer')
    )
  );

DROP POLICY IF EXISTS "Privileged users can file own leaves" ON leave_of_absence;
CREATE POLICY "Privileged users can file own leaves"
  ON leave_of_absence FOR INSERT
  WITH CHECK (
    user_id = auth.uid()
    AND filed_by = auth.uid()
    AND EXISTS (
      SELECT 1 FROM profiles
      WHERE profiles.id = auth.uid()
        AND profiles.role IN ('admin', 'dispatcher', 'it_staff', 'programmer')
    )
  );

-- Swap request participants: allow programmers to view/insert participant rows.
DROP POLICY IF EXISTS "Swap participants: select" ON public.swap_request_participants;
CREATE POLICY "Swap participants: select" ON public.swap_request_participants
  FOR SELECT
  USING (
    user_id = auth.uid()
    OR EXISTS (
      SELECT 1 FROM public.profiles p WHERE p.id = auth.uid() AND p.role IN ('admin', 'dispatcher', 'programmer')
    )
    OR EXISTS (
      SELECT 1 FROM public.swap_requests s WHERE s.id = swap_request_id AND (s.requester_id = auth.uid() OR s.recipient_id = auth.uid())
    )
  );

DROP POLICY IF EXISTS "Swap participants: insert" ON public.swap_request_participants;
CREATE POLICY "Swap participants: insert" ON public.swap_request_participants
  FOR INSERT
  WITH CHECK (
    user_id = auth.uid()
    OR EXISTS (
      SELECT 1 FROM public.profiles p WHERE p.id = auth.uid() AND p.role IN ('admin', 'dispatcher', 'programmer')
    )
  );
