-- Міграція для Memory Service
-- Створює таблиці: user_facts, dialog_summaries, agent_memory_events, agent_memory_facts_vector

-- Розширення для UUID та vector
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
CREATE EXTENSION IF NOT EXISTS "vector";

-- ========== User Facts ==========
CREATE TABLE IF NOT EXISTS user_facts (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    user_id TEXT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
    team_id TEXT REFERENCES teams(id) ON DELETE CASCADE,
    
    -- Ключ факту (наприклад: "language", "is_donor", "is_validator", "top_contributor")
    fact_key TEXT NOT NULL,
    
    -- Значення факту
    fact_value TEXT,
    fact_value_json JSONB,
    
    -- Метадані
    metadata JSONB NOT NULL DEFAULT '{}'::jsonb,
    
    -- Токен-гейт
    token_gated BOOLEAN NOT NULL DEFAULT false,
    token_requirements JSONB,
    
    -- Таймстемпи
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMPTZ,
    expires_at TIMESTAMPTZ
);

CREATE INDEX IF NOT EXISTS idx_user_facts_user_id ON user_facts(user_id);
CREATE INDEX IF NOT EXISTS idx_user_facts_team_id ON user_facts(team_id);
CREATE INDEX IF NOT EXISTS idx_user_facts_user_key ON user_facts(user_id, fact_key);
CREATE INDEX IF NOT EXISTS idx_user_facts_token_gated ON user_facts(token_gated);
CREATE INDEX IF NOT EXISTS idx_user_facts_expires_at ON user_facts(expires_at) WHERE expires_at IS NOT NULL;

-- ========== Dialog Summaries ==========
CREATE TABLE IF NOT EXISTS dialog_summaries (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    
    -- Контекст діалогу
    team_id TEXT NOT NULL REFERENCES teams(id) ON DELETE CASCADE,
    channel_id TEXT REFERENCES channels(id) ON DELETE CASCADE,
    agent_id TEXT REFERENCES agents(id) ON DELETE CASCADE,
    user_id TEXT REFERENCES users(id) ON DELETE CASCADE,
    
    -- Період
    period_start TIMESTAMPTZ NOT NULL,
    period_end TIMESTAMPTZ NOT NULL,
    
    -- Підсумок
    summary_text TEXT NOT NULL,
    summary_json JSONB,
    
    -- Статистика
    message_count INTEGER NOT NULL DEFAULT 0,
    participant_count INTEGER NOT NULL DEFAULT 0,
    
    -- Ключові теми
    topics JSONB,
    
    -- Метадані
    metadata JSONB NOT NULL DEFAULT '{}'::jsonb,
    
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE INDEX IF NOT EXISTS idx_dialog_summaries_team_id ON dialog_summaries(team_id);
CREATE INDEX IF NOT EXISTS idx_dialog_summaries_channel_id ON dialog_summaries(channel_id);
CREATE INDEX IF NOT EXISTS idx_dialog_summaries_agent_id ON dialog_summaries(agent_id);
CREATE INDEX IF NOT EXISTS idx_dialog_summaries_user_id ON dialog_summaries(user_id);
CREATE INDEX IF NOT EXISTS idx_dialog_summaries_team_period ON dialog_summaries(team_id, period_start, period_end);
CREATE INDEX IF NOT EXISTS idx_dialog_summaries_created_at ON dialog_summaries(created_at);

-- ========== Agent Memory Events ==========
CREATE TABLE IF NOT EXISTS agent_memory_events (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    
    agent_id TEXT NOT NULL REFERENCES agents(id) ON DELETE CASCADE,
    team_id TEXT NOT NULL REFERENCES teams(id) ON DELETE CASCADE,
    channel_id TEXT REFERENCES channels(id) ON DELETE CASCADE,
    user_id TEXT REFERENCES users(id) ON DELETE CASCADE,
    
    -- Scope: short_term, mid_term, long_term
    scope TEXT NOT NULL CHECK (scope IN ('short_term', 'mid_term', 'long_term')),
    
    -- Kind: message, fact, summary, note
    kind TEXT NOT NULL CHECK (kind IN ('message', 'fact', 'summary', 'note')),
    
    -- Тіло події
    body_text TEXT,
    body_json JSONB,
    
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE INDEX IF NOT EXISTS idx_agent_memory_events_agent_id ON agent_memory_events(agent_id);
CREATE INDEX IF NOT EXISTS idx_agent_memory_events_team_id ON agent_memory_events(team_id);
CREATE INDEX IF NOT EXISTS idx_agent_memory_events_channel_id ON agent_memory_events(channel_id);
CREATE INDEX IF NOT EXISTS idx_agent_memory_events_user_id ON agent_memory_events(user_id);
CREATE INDEX IF NOT EXISTS idx_agent_memory_events_agent_team_scope ON agent_memory_events(agent_id, team_id, scope);
CREATE INDEX IF NOT EXISTS idx_agent_memory_events_channel ON agent_memory_events(agent_id, channel_id);
CREATE INDEX IF NOT EXISTS idx_agent_memory_events_created_at ON agent_memory_events(created_at);

-- ========== Agent Memory Facts Vector (для RAG) ==========
CREATE TABLE IF NOT EXISTS agent_memory_facts_vector (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    
    agent_id TEXT NOT NULL REFERENCES agents(id) ON DELETE CASCADE,
    team_id TEXT NOT NULL REFERENCES teams(id) ON DELETE CASCADE,
    
    fact_text TEXT NOT NULL,
    embedding vector(1536),  -- OpenAI ada-002 embedding size
    
    metadata JSONB NOT NULL DEFAULT '{}'::jsonb,
    
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE INDEX IF NOT EXISTS idx_agent_memory_facts_vector_agent_id ON agent_memory_facts_vector(agent_id);
CREATE INDEX IF NOT EXISTS idx_agent_memory_facts_vector_team_id ON agent_memory_facts_vector(team_id);
CREATE INDEX IF NOT EXISTS idx_agent_memory_facts_vector_agent_team ON agent_memory_facts_vector(agent_id, team_id);

-- Індекс для векторного пошуку (використовується pgvector)
-- Примітка: Створіть цей індекс після того, як у вас буде достатньо даних
-- CREATE INDEX IF NOT EXISTS idx_agent_memory_facts_vector_embedding 
-- ON agent_memory_facts_vector USING ivfflat (embedding vector_cosine_ops)
-- WITH (lists = 100);

