-- Fix for recurring post/appreciate access issues for specific users
-- This migration ensures:
-- 1. All posts have valid visibility values
-- 2. Profile privacy settings are consistent
-- 3. RLS policies don't conflict
-- 4. Users can always see public posts regardless of their own privacy settings

-- Step 1: Ensure all posts have visibility set (fix any nulls)
UPDATE posts
SET visibility = 'public'
WHERE visibility IS NULL;

-- Step 2: Ensure profiles have consistent privacy settings
UPDATE profiles
SET is_private = false
WHERE is_private IS NULL;

-- Step 2b: Official accounts should always be public (is_private = false)
-- This is because official/verified accounts are meant to be publicly accessible
UPDATE profiles
SET is_private = false
WHERE is_official = true AND is_private = true;

-- Step 3: Drop ALL conflicting policies and create a unified one
DROP POLICY IF EXISTS posts_select_private_model ON posts;
DROP POLICY IF EXISTS posts_select_policy ON posts;
DROP POLICY IF EXISTS posts_visibility_policy ON posts;
DROP POLICY IF EXISTS posts_select_unified ON posts;

-- Unified SELECT policy that combines both models:
-- ANY authenticated user can see post if:
--   a) They are the author (always see own posts)
--   b) Post visibility is 'public' (ANYONE can see public posts)
--   c) Post visibility is 'followers' AND user has accepted follow to author
--   d) Author's profile is NOT private (legacy backward compat - treat as public)
--
-- IMPORTANT: The viewer's own is_private setting does NOT affect what they can see.
-- is_private only affects whether OTHERS can see YOUR posts without following you.
CREATE POLICY posts_select_unified ON posts
  FOR SELECT
  USING (
    -- Author can always see their own posts
    auth.uid() = author_id
    -- Public posts visible to ALL authenticated users
    OR visibility = 'public'
    -- Followers-only posts visible to accepted followers
    OR (
      visibility = 'followers'
      AND EXISTS (
        SELECT 1
        FROM follows f
        WHERE f.follower_id = auth.uid()
          AND f.following_id = posts.author_id
          AND f.status = 'accepted'
      )
    )
    -- Legacy: If author's profile is NOT private, treat their non-private posts as visible
    -- This handles posts created before visibility column existed
    OR (
      visibility IS DISTINCT FROM 'private'
      AND EXISTS (
        SELECT 1
        FROM profiles p
        WHERE p.id = posts.author_id
          AND p.is_private = false
      )
    )
  );

-- Step 4: Ensure INSERT policy exists for posts
DROP POLICY IF EXISTS posts_insert_policy ON posts;
CREATE POLICY posts_insert_policy ON posts
  FOR INSERT
  WITH CHECK (auth.uid() = author_id);

-- Step 5: Ensure UPDATE policy exists for posts
DROP POLICY IF EXISTS posts_update_policy ON posts;
CREATE POLICY posts_update_policy ON posts
  FOR UPDATE
  USING (auth.uid() = author_id)
  WITH CHECK (auth.uid() = author_id);

-- Step 6: Ensure DELETE policy exists for posts
DROP POLICY IF EXISTS posts_delete_policy ON posts;
CREATE POLICY posts_delete_policy ON posts
  FOR DELETE
  USING (auth.uid() = author_id);

-- Step 7: Fix post_likes table RLS
ALTER TABLE IF EXISTS post_likes ENABLE ROW LEVEL SECURITY;

DROP POLICY IF EXISTS post_likes_select_policy ON post_likes;
CREATE POLICY post_likes_select_policy ON post_likes
  FOR SELECT
  USING (true);  -- Anyone can see likes (needed for like counts)

DROP POLICY IF EXISTS post_likes_insert_policy ON post_likes;
CREATE POLICY post_likes_insert_policy ON post_likes
  FOR INSERT
  WITH CHECK (auth.uid() = user_id);

DROP POLICY IF EXISTS post_likes_delete_policy ON post_likes;
CREATE POLICY post_likes_delete_policy ON post_likes
  FOR DELETE
  USING (auth.uid() = user_id);

-- Step 8: Create index for faster RLS checks
CREATE INDEX IF NOT EXISTS idx_follows_follower_following_status
  ON follows(follower_id, following_id, status);

CREATE INDEX IF NOT EXISTS idx_posts_author_visibility
  ON posts(author_id, visibility);

-- Step 7b: Fix post_saves table RLS (same pattern as post_likes)
ALTER TABLE IF EXISTS post_saves ENABLE ROW LEVEL SECURITY;

DROP POLICY IF EXISTS post_saves_select_policy ON post_saves;
CREATE POLICY post_saves_select_policy ON post_saves
  FOR SELECT
  USING (auth.uid() = user_id);  -- Users can only see their own saves

DROP POLICY IF EXISTS post_saves_insert_policy ON post_saves;
CREATE POLICY post_saves_insert_policy ON post_saves
  FOR INSERT
  WITH CHECK (auth.uid() = user_id);

DROP POLICY IF EXISTS post_saves_delete_policy ON post_saves;
CREATE POLICY post_saves_delete_policy ON post_saves
  FOR DELETE
  USING (auth.uid() = user_id);

-- Step 9: Grant necessary permissions
GRANT SELECT, INSERT, UPDATE, DELETE ON posts TO authenticated;
GRANT SELECT, INSERT, DELETE ON post_likes TO authenticated;
GRANT SELECT, INSERT, DELETE ON post_saves TO authenticated;
