-- Revert the previous policy and implement proper security model
-- The filtered_profiles view should be the ONLY way to view other users' profiles

-- Remove the policy that allows direct profile viewing
DROP POLICY IF EXISTS "Authenticated users can view public profiles" ON public.profiles;

-- Change filtered_profiles view to use SECURITY DEFINER
-- This allows it to bypass RLS and implement its own access control
DROP VIEW IF EXISTS public.filtered_profiles;

CREATE VIEW public.filtered_profiles
WITH (security_invoker = off, security_barrier = true)
AS
SELECT 
  p.id,
  p.user_id,
  p.username,
  p.display_name,
  p.privacy_level,
  p.created_at,
  p.updated_at,
  -- Conditionally show bio based on privacy
  CASE 
    WHEN can_view_profile_field(COALESCE(auth.uid(), '00000000-0000-0000-0000-000000000000'::uuid), p.user_id, 'bio') 
    THEN p.bio 
    ELSE NULL 
  END AS bio,
  -- Conditionally show avatar based on privacy
  CASE 
    WHEN can_view_profile_field(COALESCE(auth.uid(), '00000000-0000-0000-0000-000000000000'::uuid), p.user_id, 'avatar_url') 
    THEN p.avatar_url 
    ELSE NULL 
  END AS avatar_url,
  CASE 
    WHEN can_view_profile_field(COALESCE(auth.uid(), '00000000-0000-0000-0000-000000000000'::uuid), p.user_id, 'avatar_image_id') 
    THEN p.avatar_image_id 
    ELSE NULL 
  END AS avatar_image_id,
  -- Conditionally show pronouns based on privacy
  CASE 
    WHEN can_view_profile_field(COALESCE(auth.uid(), '00000000-0000-0000-0000-000000000000'::uuid), p.user_id, 'preferred_pronouns') 
    THEN p.preferred_pronouns 
    ELSE NULL 
  END AS preferred_pronouns,
  CASE 
    WHEN can_view_profile_field(COALESCE(auth.uid(), '00000000-0000-0000-0000-000000000000'::uuid), p.user_id, 'preferred_pronouns') 
    THEN p.show_pronouns 
    ELSE false 
  END AS show_pronouns,
  -- Conditionally show location based on privacy
  CASE 
    WHEN can_view_profile_field(COALESCE(auth.uid(), '00000000-0000-0000-0000-000000000000'::uuid), p.user_id, 'personal_location') 
    THEN p.personal_location 
    ELSE NULL 
  END AS personal_location,
  CASE 
    WHEN can_view_profile_field(COALESCE(auth.uid(), '00000000-0000-0000-0000-000000000000'::uuid), p.user_id, 'location_id') 
    THEN p.location_id 
    ELSE NULL 
  END AS location_id,
  -- Conditionally show home park based on privacy
  CASE 
    WHEN can_view_profile_field(COALESCE(auth.uid(), '00000000-0000-0000-0000-000000000000'::uuid), p.user_id, 'home_park_id') 
    THEN p.home_park_id 
    ELSE NULL 
  END AS home_park_id,
  -- Conditionally show date of birth based on privacy
  CASE 
    WHEN can_view_profile_field(COALESCE(auth.uid(), '00000000-0000-0000-0000-000000000000'::uuid), p.user_id, 'date_of_birth') 
    THEN p.date_of_birth 
    ELSE NULL 
  END AS date_of_birth,
  -- Always show safe fields
  p.timezone,
  p.preferred_language,
  p.theme_preference,
  -- Conditionally show activity stats based on privacy
  CASE 
    WHEN can_view_profile_field(COALESCE(auth.uid(), '00000000-0000-0000-0000-000000000000'::uuid), p.user_id, 'ride_count') 
    THEN p.ride_count 
    ELSE 0 
  END AS ride_count,
  CASE 
    WHEN can_view_profile_field(COALESCE(auth.uid(), '00000000-0000-0000-0000-000000000000'::uuid), p.user_id, 'ride_count') 
    THEN p.coaster_count 
    ELSE 0 
  END AS coaster_count,
  CASE 
    WHEN can_view_profile_field(COALESCE(auth.uid(), '00000000-0000-0000-0000-000000000000'::uuid), p.user_id, 'ride_count') 
    THEN p.park_count 
    ELSE 0 
  END AS park_count,
  CASE 
    WHEN can_view_profile_field(COALESCE(auth.uid(), '00000000-0000-0000-0000-000000000000'::uuid), p.user_id, 'ride_count') 
    THEN p.review_count 
    ELSE 0 
  END AS review_count,
  CASE 
    WHEN can_view_profile_field(COALESCE(auth.uid(), '00000000-0000-0000-0000-000000000000'::uuid), p.user_id, 'ride_count') 
    THEN p.reputation_score 
    ELSE 0 
  END AS reputation_score,
  -- Only show banned status to owner and moderators
  CASE 
    WHEN (auth.uid() = p.user_id) OR is_moderator(COALESCE(auth.uid(), '00000000-0000-0000-0000-000000000000'::uuid)) 
    THEN p.banned 
    ELSE false 
  END AS banned
FROM public.profiles p
WHERE 
  -- Hide banned profiles unless viewer is owner or moderator
  ((NOT p.banned) OR (auth.uid() = p.user_id) OR is_moderator(COALESCE(auth.uid(), '00000000-0000-0000-0000-000000000000'::uuid)))
  AND 
  -- Only show public profiles OR owner's own profile OR moderator viewing
  ((p.privacy_level = 'public') OR (auth.uid() = p.user_id) OR is_moderator(COALESCE(auth.uid(), '00000000-0000-0000-0000-000000000000'::uuid)));

-- Grant access to the filtered_profiles view
GRANT SELECT ON public.filtered_profiles TO authenticated, anon;

-- Add explanatory comment
COMMENT ON VIEW public.filtered_profiles IS 
'Privacy-safe profile view that enforces field-level access control.
Uses security_invoker=off (SECURITY DEFINER) to bypass RLS and implement custom filtering.
Sensitive fields are conditionally shown based on user privacy settings.
Users can only see public non-banned profiles, their own profile, or all profiles if they are moderators.
All client code should query this view instead of the profiles table directly.';