
-- Create roles if they don't exist
DO $$
BEGIN
  IF NOT EXISTS (SELECT FROM pg_catalog.pg_roles WHERE rolname = 'authenticated') THEN
    CREATE ROLE authenticated NOLOGIN;
  END IF;
  IF NOT EXISTS (SELECT FROM pg_catalog.pg_roles WHERE rolname = 'anon') THEN
    CREATE ROLE anon NOLOGIN;
  END IF;
END
$$;

CREATE SCHEMA IF NOT EXISTS storage;

-- Grant usage
GRANT USAGE ON SCHEMA storage TO authenticated, anon;
GRANT USAGE ON SCHEMA public TO authenticated, anon;

CREATE TABLE IF NOT EXISTS storage.buckets (
    id TEXT PRIMARY KEY,
    name TEXT NOT NULL,
    public BOOLEAN DEFAULT false,
    owner UUID REFERENCES auth.users(id),
    created_at TIMESTAMPTZ DEFAULT now(),
    updated_at TIMESTAMPTZ DEFAULT now()
);

CREATE TABLE IF NOT EXISTS storage.objects (
    id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
    bucket_id TEXT REFERENCES storage.buckets(id),
    name TEXT NOT NULL,
    owner UUID REFERENCES auth.users(id),
    created_at TIMESTAMPTZ DEFAULT now(),
    updated_at TIMESTAMPTZ DEFAULT now(),
    last_accessed_at TIMESTAMPTZ DEFAULT now(),
    metadata JSONB,
    UNIQUE (bucket_id, name)
);

-- Grant table access (RLS will filter rows)
GRANT ALL ON TABLE storage.buckets TO authenticated, anon;
GRANT ALL ON TABLE storage.objects TO authenticated, anon;

ALTER TABLE storage.buckets ENABLE ROW LEVEL SECURITY;
ALTER TABLE storage.objects ENABLE ROW LEVEL SECURITY;

-- Helper to allow public access to public buckets
CREATE POLICY "Public Buckets are viewable by everyone" 
ON storage.buckets FOR SELECT 
USING ( public = true );

-- Helper to allow authenticated users to view their own buckets
CREATE POLICY "Users can view their own buckets" 
ON storage.buckets FOR SELECT 
TO authenticated 
USING ( owner = current_setting('request.jwt.claim.sub', true)::uuid );

-- Objects policies depend on bucket public status or object owner
CREATE POLICY "Public Objects are viewable by everyone" 
ON storage.objects FOR SELECT 
USING ( bucket_id IN (SELECT id FROM storage.buckets WHERE public = true) );

CREATE POLICY "Users can view their own objects" 
ON storage.objects FOR SELECT 
TO authenticated 
USING ( owner = current_setting('request.jwt.claim.sub', true)::uuid );

CREATE POLICY "Users can insert their own objects" 
ON storage.objects FOR INSERT 
TO authenticated 
WITH CHECK ( owner = current_setting('request.jwt.claim.sub', true)::uuid );
