-- Advanced RLS Configuration with User Authentication
-- This provides more granular control over data access

-- First, create a users table if it doesn't exist
CREATE TABLE IF NOT EXISTS public.users (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    email TEXT UNIQUE NOT NULL,
    role TEXT NOT NULL DEFAULT 'viewer', -- viewer, editor, admin
    created_at TIMESTAMPTZ DEFAULT NOW(),
    updated_at TIMESTAMPTZ DEFAULT NOW()
);

-- Add user_id columns to track ownership (if not exists)
DO $$
BEGIN
    -- Add user_id to datasources if not exists
    IF NOT EXISTS (SELECT 1 FROM information_schema.columns
                   WHERE table_schema = 'public'
                   AND table_name = 'datasources'
                   AND column_name = 'user_id') THEN
        ALTER TABLE public.datasources ADD COLUMN user_id UUID REFERENCES public.users(id);
    END IF;

    -- Add user_id to documents if not exists
    IF NOT EXISTS (SELECT 1 FROM information_schema.columns
                   WHERE table_schema = 'public'
                   AND table_name = 'documents'
                   AND column_name = 'user_id') THEN
        ALTER TABLE public.documents ADD COLUMN user_id UUID REFERENCES public.users(id);
    END IF;

    -- Add user_id to collections if not exists
    IF NOT EXISTS (SELECT 1 FROM information_schema.columns
                   WHERE table_schema = 'public'
                   AND table_name = 'collections'
                   AND column_name = 'user_id') THEN
        ALTER TABLE public.collections ADD COLUMN user_id UUID REFERENCES public.users(id);
    END IF;

    -- Add user_id to chat_logs if not exists
    IF NOT EXISTS (SELECT 1 FROM information_schema.columns
                   WHERE table_schema = 'public'
                   AND table_name = 'chat_logs'
                   AND column_name = 'user_id') THEN
        ALTER TABLE public.chat_logs ADD COLUMN user_id UUID REFERENCES public.users(id);
    END IF;
END $$;

-- Enable RLS on users table
ALTER TABLE public.users ENABLE ROW LEVEL SECURITY;

-- Drop existing policies if they exist (to avoid conflicts)
DROP POLICY IF EXISTS "Service role can manage agents" ON public.agents;
DROP POLICY IF EXISTS "Service role can manage agent versions" ON public.agent_versions;
DROP POLICY IF EXISTS "Service role can manage datasources" ON public.datasources;
DROP POLICY IF EXISTS "Service role can manage documents" ON public.documents;
DROP POLICY IF EXISTS "Service role can manage chunks" ON public.chunks;
DROP POLICY IF EXISTS "Service role can manage embeddings" ON public.embeddings;
DROP POLICY IF EXISTS "Service role can manage collections" ON public.collections;
DROP POLICY IF EXISTS "Service role can manage collection items" ON public.collection_items;
DROP POLICY IF EXISTS "Service role can manage pipeline runs" ON public.pipeline_runs;
DROP POLICY IF EXISTS "Service role can manage chat logs" ON public.chat_logs;

-- Users table policies
CREATE POLICY "Users can read their own profile" ON public.users
    FOR SELECT
    USING (auth.uid() = id OR auth.role() = 'service_role');

CREATE POLICY "Service role can manage all users" ON public.users
    FOR ALL
    USING (auth.role() = 'service_role')
    WITH CHECK (auth.role() = 'service_role');

-- Datasources policies (user-owned)
CREATE POLICY "Users can read their own datasources" ON public.datasources
    FOR SELECT
    USING (
        auth.role() = 'service_role' OR
        user_id = auth.uid() OR
        user_id IS NULL -- For backward compatibility
    );

CREATE POLICY "Users can create their own datasources" ON public.datasources
    FOR INSERT
    WITH CHECK (
        auth.role() = 'service_role' OR
        user_id = auth.uid()
    );

CREATE POLICY "Users can update their own datasources" ON public.datasources
    FOR UPDATE
    USING (
        auth.role() = 'service_role' OR
        user_id = auth.uid()
    );

CREATE POLICY "Users can delete their own datasources" ON public.datasources
    FOR DELETE
    USING (
        auth.role() = 'service_role' OR
        user_id = auth.uid()
    );

-- Documents policies (user-owned through datasource)
CREATE POLICY "Users can read documents from their datasources" ON public.documents
    FOR SELECT
    USING (
        auth.role() = 'service_role' OR
        user_id = auth.uid() OR
        user_id IS NULL OR
        EXISTS (
            SELECT 1 FROM public.datasources
            WHERE datasources.id = documents.datasource_id
            AND (datasources.user_id = auth.uid() OR datasources.user_id IS NULL)
        )
    );

CREATE POLICY "Service role can manage all documents" ON public.documents
    FOR ALL
    USING (auth.role() = 'service_role')
    WITH CHECK (auth.role() = 'service_role');

-- Chunks policies (read-only for users, managed by service)
CREATE POLICY "Users can read chunks from their documents" ON public.chunks
    FOR SELECT
    USING (
        auth.role() = 'service_role' OR
        EXISTS (
            SELECT 1 FROM public.documents
            WHERE documents.id = chunks.doc_id
            AND (
                documents.user_id = auth.uid() OR
                documents.user_id IS NULL OR
                EXISTS (
                    SELECT 1 FROM public.datasources
                    WHERE datasources.id = documents.datasource_id
                    AND (datasources.user_id = auth.uid() OR datasources.user_id IS NULL)
                )
            )
        )
    );

CREATE POLICY "Service role can manage all chunks" ON public.chunks
    FOR ALL
    USING (auth.role() = 'service_role')
    WITH CHECK (auth.role() = 'service_role');

-- Embeddings policies (read-only for users, managed by service)
CREATE POLICY "Users can read embeddings from their chunks" ON public.embeddings
    FOR SELECT
    USING (
        auth.role() = 'service_role' OR
        EXISTS (
            SELECT 1 FROM public.chunks
            JOIN public.documents ON chunks.doc_id = documents.id
            WHERE chunks.id = embeddings.chunk_id
            AND (
                documents.user_id = auth.uid() OR
                documents.user_id IS NULL OR
                EXISTS (
                    SELECT 1 FROM public.datasources
                    WHERE datasources.id = documents.datasource_id
                    AND (datasources.user_id = auth.uid() OR datasources.user_id IS NULL)
                )
            )
        )
    );

CREATE POLICY "Service role can manage all embeddings" ON public.embeddings
    FOR ALL
    USING (auth.role() = 'service_role')
    WITH CHECK (auth.role() = 'service_role');

-- Collections policies (user-owned)
CREATE POLICY "Users can manage their own collections" ON public.collections
    FOR ALL
    USING (
        auth.role() = 'service_role' OR
        user_id = auth.uid() OR
        user_id IS NULL
    )
    WITH CHECK (
        auth.role() = 'service_role' OR
        user_id = auth.uid()
    );

-- Collection items policies
CREATE POLICY "Users can manage items in their collections" ON public.collection_items
    FOR ALL
    USING (
        auth.role() = 'service_role' OR
        EXISTS (
            SELECT 1 FROM public.collections
            WHERE collections.id = collection_items.collection_id
            AND (collections.user_id = auth.uid() OR collections.user_id IS NULL)
        )
    )
    WITH CHECK (
        auth.role() = 'service_role' OR
        EXISTS (
            SELECT 1 FROM public.collections
            WHERE collections.id = collection_items.collection_id
            AND (collections.user_id = auth.uid() OR collections.user_id IS NULL)
        )
    );

-- Chat logs policies (user-owned)
CREATE POLICY "Users can manage their own chat logs" ON public.chat_logs
    FOR ALL
    USING (
        auth.role() = 'service_role' OR
        user_id = auth.uid() OR
        user_id IS NULL
    )
    WITH CHECK (
        auth.role() = 'service_role' OR
        user_id = auth.uid()
    );

-- Agents policies (read-only for all authenticated users)
CREATE POLICY "All authenticated users can read agents" ON public.agents
    FOR SELECT
    USING (auth.role() IN ('authenticated', 'service_role'));

CREATE POLICY "Service role can manage agents" ON public.agents
    FOR ALL
    USING (auth.role() = 'service_role')
    WITH CHECK (auth.role() = 'service_role');

-- Agent versions policies (read-only for all authenticated users)
CREATE POLICY "All authenticated users can read agent versions" ON public.agent_versions
    FOR SELECT
    USING (auth.role() IN ('authenticated', 'service_role'));

CREATE POLICY "Service role can manage agent versions" ON public.agent_versions
    FOR ALL
    USING (auth.role() = 'service_role')
    WITH CHECK (auth.role() = 'service_role');

-- Pipeline runs policies (service role only)
CREATE POLICY "Service role can manage pipeline runs" ON public.pipeline_runs
    FOR ALL
    USING (auth.role() = 'service_role')
    WITH CHECK (auth.role() = 'service_role');

-- Create indexes for better performance
CREATE INDEX IF NOT EXISTS idx_datasources_user_id ON public.datasources(user_id);
CREATE INDEX IF NOT EXISTS idx_documents_user_id ON public.documents(user_id);
CREATE INDEX IF NOT EXISTS idx_collections_user_id ON public.collections(user_id);
CREATE INDEX IF NOT EXISTS idx_chat_logs_user_id ON public.chat_logs(user_id);
