-- ============================================================
-- schema.sql – схема базы данных PostgreSQL для RAG-сервера
-- Поддерживает личные, глобальные и комнатные документы,
-- а также историю диалогов (личных и групповых).
-- Используется единой базой данных для всех ботов.
-- =================-- ============================================================
-- schema.sql – схема базы данных PostgreSQL для RAG-сервера
-- Добавлена поддержка флага indexed для транзакционности индексации
-- ============================================================

-- ------------------------------------------------------------------
-- 1. Таблица documents (метаданные загруженных документов)
-- ------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS documents (
    id SERIAL PRIMARY KEY,
    source_name VARCHAR(255) NOT NULL,
    upload_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    owner_jid VARCHAR(255) NOT NULL,
    is_global BOOLEAN DEFAULT FALSE,
    metadata JSONB,                         -- PostgreSQL JSONB
    room_jid VARCHAR(255) DEFAULT NULL,    -- NULL – личный/глобальный; иначе JID комнаты
    file_hash VARCHAR(64) DEFAULT NULL,    -- SHA-256 хеш содержимого (для обновления версий)
    indexed BOOLEAN DEFAULT FALSE          -- TRUE, если чанки успешно загружены в Qdrant
);

-- Индексы для ускорения запросов
CREATE INDEX IF NOT EXISTS idx_documents_owner ON documents(owner_jid);
CREATE INDEX IF NOT EXISTS idx_documents_global ON documents(is_global);
CREATE INDEX IF NOT EXISTS idx_documents_room ON documents(room_jid);
CREATE INDEX IF NOT EXISTS idx_documents_indexed ON documents(indexed);   -- новый индекс

-- Полнотекстовый индекс (GIN) для source_name (русский язык)
CREATE INDEX IF NOT EXISTS ft_source_name ON documents USING GIN (to_tsvector('russian', source_name));

-- ------------------------------------------------------------------
-- 2. Таблица document_access (права доступа к личным документам)
-- ------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS document_access (
    doc_id INT,
    user_jid VARCHAR(255),
    PRIMARY KEY (doc_id, user_jid)
);

CREATE INDEX IF NOT EXISTS idx_access_user ON document_access(user_jid);

-- ------------------------------------------------------------------
-- 3. Таблица history (история диалогов)
-- ------------------------------------------------------------------
DO $$ BEGIN
    CREATE TYPE history_role AS ENUM ('user', 'assistant');
EXCEPTION
    WHEN duplicate_object THEN NULL;
END $$;

CREATE TABLE IF NOT EXISTS history (
    id SERIAL PRIMARY KEY,
    user_jid VARCHAR(255) NOT NULL,
    role history_role NOT NULL,
    content TEXT,
    timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    room_jid VARCHAR(255) DEFAULT NULL     -- NULL – личный диалог; иначе JID комнаты
);

CREATE INDEX IF NOT EXISTS idx_history_user ON history(user_jid);
CREATE INDEX IF NOT EXISTS idx_history_room ON history(room_jid);
CREATE INDEX IF NOT EXISTS idx_history_time ON history(timestamp);

-- ------------------------------------------------------------------
-- 4. Таблица rooms (список MUC комнат, в которых бот должен состоять)
-- ------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS rooms (
    room_jid VARCHAR(255) PRIMARY KEY
);

-- ------------------------------------------------------------------
-- 5. Таблица room_templates (шаблоны коробочных решений, сохранённые в комнатах)
-- ------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS room_templates (
    room_jid VARCHAR(255) NOT NULL,
    name VARCHAR(255) NOT NULL,
    file_path TEXT NOT NULL,
    file_hash VARCHAR(64),
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    PRIMARY KEY (room_jid, name)
);

-- ------------------------------------------------------------------
-- 6. Таблица feedback (оценки пользователей) – для будущего сбора обратной связи
-- ------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS feedback (
    id SERIAL PRIMARY KEY,
    user_jid VARCHAR(255) NOT NULL,
    rating VARCHAR(50) NOT NULL,
    comment TEXT,
    room_jid VARCHAR(255) DEFAULT NULL,
    timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

CREATE INDEX IF NOT EXISTS idx_feedback_user ON feedback(user_jid);

-- ============================================================
-- Миграции (если переезжаете с предыдущей версии)
-- ============================================================

-- Добавление колонки room_jid в documents (если отсутствует)
DO $$
BEGIN
    IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name='documents' AND column_name='room_jid') THEN
        ALTER TABLE documents ADD COLUMN room_jid VARCHAR(255) DEFAULT NULL;
    END IF;
END $$;

-- Добавление колонки file_hash в documents
DO $$
BEGIN
    IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name='documents' AND column_name='file_hash') THEN
        ALTER TABLE documents ADD COLUMN file_hash VARCHAR(64) DEFAULT NULL;
    END IF;
END $$;

-- Добавление колонки room_jid в history
DO $$
BEGIN
    IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name='history' AND column_name='room_jid') THEN
        ALTER TABLE history ADD COLUMN room_jid VARCHAR(255) DEFAULT NULL;
    END IF;
END $$;

-- Добавление колонки indexed (новое)
DO $$
BEGIN
    IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name='documents' AND column_name='indexed') THEN
        ALTER TABLE documents ADD COLUMN indexed BOOLEAN DEFAULT FALSE;
        -- Для существующих документов считаем, что они уже проиндексированы
        UPDATE documents SET indexed = TRUE;
        -- Создаём индекс
        CREATE INDEX IF NOT EXISTS idx_documents_indexed ON documents(indexed);
    END IF;
END $$;

-- Создание индексов (если отсутствуют)
DO $$
BEGIN
    IF NOT EXISTS (SELECT 1 FROM pg_indexes WHERE indexname='idx_documents_room') THEN
        CREATE INDEX idx_documents_room ON documents(room_jid);
    END IF;
END $$;

DO $$
BEGIN
    IF NOT EXISTS (SELECT 1 FROM pg_indexes WHERE indexname='idx_history_room') THEN
        CREATE INDEX idx_history_room ON history(room_jid);
    END IF;
END $$;===========================================

-- ------------------------------------------------------------------
-- 1. Таблица documents (метаданные загруженных документов)
-- ------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS documents (
    id SERIAL PRIMARY KEY,
    source_name VARCHAR(255) NOT NULL,
    upload_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    owner_jid VARCHAR(255) NOT NULL,
    is_global BOOLEAN DEFAULT FALSE,
    metadata JSONB,                         -- PostgreSQL JSONB
    room_jid VARCHAR(255) DEFAULT NULL,    -- NULL – личный/глобальный; иначе JID комнаты
    file_hash VARCHAR(64) DEFAULT NULL     -- SHA-256 хеш содержимого (для обновления версий)
);

-- Индексы для ускорения запросов
CREATE INDEX IF NOT EXISTS idx_documents_owner ON documents(owner_jid);
CREATE INDEX IF NOT EXISTS idx_documents_global ON documents(is_global);
CREATE INDEX IF NOT EXISTS idx_documents_room ON documents(room_jid);

-- Полнотекстовый индекс (GIN) для source_name (русский язык)
CREATE INDEX IF NOT EXISTS ft_source_name ON documents USING GIN (to_tsvector('russian', source_name));

-- ------------------------------------------------------------------
-- 2. Таблица document_access (права доступа к личным документам)
-- ------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS document_access (
    doc_id INT,
    user_jid VARCHAR(255),
    PRIMARY KEY (doc_id, user_jid)
);

CREATE INDEX IF NOT EXISTS idx_access_user ON document_access(user_jid);

-- ------------------------------------------------------------------
-- 3. Таблица history (история диалогов)
-- ------------------------------------------------------------------
DO $$ BEGIN
    CREATE TYPE history_role AS ENUM ('user', 'assistant');
EXCEPTION
    WHEN duplicate_object THEN NULL;
END $$;

CREATE TABLE IF NOT EXISTS history (
    id SERIAL PRIMARY KEY,
    user_jid VARCHAR(255) NOT NULL,
    role history_role NOT NULL,
    content TEXT,
    timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    room_jid VARCHAR(255) DEFAULT NULL     -- NULL – личный диалог; иначе JID комнаты
);

CREATE INDEX IF NOT EXISTS idx_history_user ON history(user_jid);
CREATE INDEX IF NOT EXISTS idx_history_room ON history(room_jid);
CREATE INDEX IF NOT EXISTS idx_history_time ON history(timestamp);

-- ------------------------------------------------------------------
-- 4. Таблица rooms (список MUC комнат, в которых бот должен состоять)
-- ------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS rooms (
    room_jid VARCHAR(255) PRIMARY KEY
);

-- ------------------------------------------------------------------
-- 5. Таблица room_templates (шаблоны коробочных решений, сохранённые в комнатах)
-- ------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS room_templates (
    room_jid VARCHAR(255) NOT NULL,
    name VARCHAR(255) NOT NULL,
    file_path TEXT NOT NULL,
    file_hash VARCHAR(64),
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    PRIMARY KEY (room_jid, name)
);

-- ------------------------------------------------------------------
-- 6. Таблица feedback (оценки пользователей) – для будущего сбора обратной связи
-- ------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS feedback (
    id SERIAL PRIMARY KEY,
    user_jid VARCHAR(255) NOT NULL,
    rating VARCHAR(50) NOT NULL,
    comment TEXT,
    room_jid VARCHAR(255) DEFAULT NULL,
    timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

CREATE INDEX IF NOT EXISTS idx_feedback_user ON feedback(user_jid);

-- ============================================================
-- Миграции (если переезжаете с предыдущей версии)
-- ============================================================

-- Добавление колонки room_jid в documents (если отсутствует)
DO $$
BEGIN
    IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name='documents' AND column_name='room_jid') THEN
        ALTER TABLE documents ADD COLUMN room_jid VARCHAR(255) DEFAULT NULL;
    END IF;
END $$;

-- Добавление колонки file_hash в documents
DO $$
BEGIN
    IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name='documents' AND column_name='file_hash') THEN
        ALTER TABLE documents ADD COLUMN file_hash VARCHAR(64) DEFAULT NULL;
    END IF;
END $$;

-- Добавление колонки room_jid в history
DO $$
BEGIN
    IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name='history' AND column_name='room_jid') THEN
        ALTER TABLE history ADD COLUMN room_jid VARCHAR(255) DEFAULT NULL;
    END IF;
END $$;

-- Создание индексов (если отсутствуют)
DO $$
BEGIN
    IF NOT EXISTS (SELECT 1 FROM pg_indexes WHERE indexname='idx_documents_room') THEN
        CREATE INDEX idx_documents_room ON documents(room_jid);
    END IF;
END $$;

DO $$
BEGIN
    IF NOT EXISTS (SELECT 1 FROM pg_indexes WHERE indexname='idx_history_room') THEN
        CREATE INDEX idx_history_room ON history(room_jid);
    END IF;
END $$;