-- V014_create_conversation_embeddings.sql
-- Migration V014: Create conversation embeddings table with pgvector support

-- Enable pgvector extension for vector similarity search
CREATE EXTENSION IF NOT EXISTS vector;

-- Create conversation_embeddings table
CREATE TABLE IF NOT EXISTS conversation_embeddings (
    id VARCHAR(30) PRIMARY KEY,
    conversation_id VARCHAR(30) NOT NULL,
    user_id VARCHAR(30) NOT NULL,
    message_index INTEGER NOT NULL,
    message_role VARCHAR(20) NOT NULL,
    message_content TEXT NOT NULL,
    -- Vector embedding (1536 dimensions for OpenAI text-embedding-ada-002 or Azure equivalent)
    embedding vector(1536) NOT NULL,
    -- Metadata
    topics TEXT[], -- Extracted topics for filtering
    created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,

    -- Foreign key constraints
    CONSTRAINT fk_conversation
        FOREIGN KEY (conversation_id)
        REFERENCES ai_conversations(id)
        ON DELETE CASCADE,
    CONSTRAINT fk_user
        FOREIGN KEY (user_id)
        REFERENCES users(id)
        ON DELETE CASCADE
);

-- Create indexes for performance
CREATE INDEX idx_conversation_embeddings_conversation_id
    ON conversation_embeddings(conversation_id);

CREATE INDEX idx_conversation_embeddings_user_id
    ON conversation_embeddings(user_id);

CREATE INDEX idx_conversation_embeddings_created_at
    ON conversation_embeddings(created_at DESC);

-- Create vector similarity search index (HNSW - Hierarchical Navigable Small World)
-- This dramatically speeds up similarity searches
CREATE INDEX idx_conversation_embeddings_vector
    ON conversation_embeddings
    USING hnsw (embedding vector_cosine_ops)
    WITH (m = 16, ef_construction = 64);

-- Alternative: IVFFlat index (good for larger datasets)
-- CREATE INDEX idx_conversation_embeddings_vector_ivfflat
--     ON conversation_embeddings
--     USING ivfflat (embedding vector_cosine_ops)
--     WITH (lists = 100);

-- Create topics GIN index for fast topic filtering
CREATE INDEX idx_conversation_embeddings_topics
    ON conversation_embeddings
    USING GIN (topics);

-- Add comment
COMMENT ON TABLE conversation_embeddings IS
    'Stores vector embeddings of conversation messages for semantic similarity search and context retrieval';

COMMENT ON COLUMN conversation_embeddings.embedding IS
    'Vector embedding (1536 dimensions) generated by OpenAI text-embedding-ada-002 or Azure OpenAI embeddings model';

COMMENT ON COLUMN conversation_embeddings.topics IS
    'Array of extracted topics for filtering (feeding, sleep, diaper, health, development, etc.)';

-- Create function to search similar conversations
CREATE OR REPLACE FUNCTION search_similar_conversations(
    query_embedding vector(1536),
    user_id_param VARCHAR(30),
    similarity_threshold FLOAT DEFAULT 0.7,
    result_limit INTEGER DEFAULT 5
)
RETURNS TABLE (
    conversation_id VARCHAR(30),
    message_content TEXT,
    similarity FLOAT,
    created_at TIMESTAMP,
    topics TEXT[]
) AS $$
BEGIN
    RETURN QUERY
    SELECT
        ce.conversation_id,
        ce.message_content,
        1 - (ce.embedding <=> query_embedding) AS similarity,
        ce.created_at,
        ce.topics
    FROM conversation_embeddings ce
    WHERE
        ce.user_id = user_id_param
        AND 1 - (ce.embedding <=> query_embedding) > similarity_threshold
    ORDER BY ce.embedding <=> query_embedding
    LIMIT result_limit;
END;
$$ LANGUAGE plpgsql;

-- Create function to search by topic with similarity
CREATE OR REPLACE FUNCTION search_conversations_by_topic(
    query_embedding vector(1536),
    user_id_param VARCHAR(30),
    topic_filter TEXT,
    similarity_threshold FLOAT DEFAULT 0.6,
    result_limit INTEGER DEFAULT 5
)
RETURNS TABLE (
    conversation_id VARCHAR(30),
    message_content TEXT,
    similarity FLOAT,
    created_at TIMESTAMP,
    topics TEXT[]
) AS $$
BEGIN
    RETURN QUERY
    SELECT
        ce.conversation_id,
        ce.message_content,
        1 - (ce.embedding <=> query_embedding) AS similarity,
        ce.created_at,
        ce.topics
    FROM conversation_embeddings ce
    WHERE
        ce.user_id = user_id_param
        AND topic_filter = ANY(ce.topics)
        AND 1 - (ce.embedding <=> query_embedding) > similarity_threshold
    ORDER BY ce.embedding <=> query_embedding
    LIMIT result_limit;
END;
$$ LANGUAGE plpgsql;
