-- Пользователи
CREATE TABLE users (
                       id SERIAL PRIMARY KEY,
                       username VARCHAR(50) NOT NULL UNIQUE,
                       email VARCHAR(255) NOT NULL UNIQUE,
                       email_confirmation_token VARCHAR(255),
                       email_confirmed_at TIMESTAMP WITH TIME ZONE,
                       password VARCHAR(255) NOT NULL,
                       created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
                       updated_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW()
);

-- Устройства
CREATE TABLE devices (
                         id SERIAL PRIMARY KEY,
                         user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
                         name VARCHAR(100) NOT NULL,
                         ip_address VARCHAR(45) NOT NULL,
                         user_agent TEXT NOT NULL,
                         confirmation_token VARCHAR(255),
                         expires_at TIMESTAMP WITH TIME ZONE NOT NULL,
                         created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW()
);

-- Сессии
CREATE TABLE sessions (
                          id SERIAL PRIMARY KEY,
                          user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
                          device_id INTEGER NOT NULL REFERENCES devices(id) ON DELETE CASCADE,
                          started_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
                          ended_at TIMESTAMP WITH TIME ZONE,
                          is_current BOOLEAN DEFAULT FALSE
);

-- Посты
CREATE TABLE posts (
                       id SERIAL PRIMARY KEY,
                       title VARCHAR(255) NOT NULL,
                       content TEXT NOT NULL,
                       author_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
                       created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
                       updated_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW()
);

-- Комментарии
CREATE TABLE comments (
                          id SERIAL PRIMARY KEY,
                          content TEXT NOT NULL,
                          post_id INTEGER NOT NULL REFERENCES posts(id) ON DELETE CASCADE,
                          author_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
                          created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
                          updated_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW()
);

-- Лайки
CREATE TABLE likes (
                       id SERIAL PRIMARY KEY,
                       post_id INTEGER NOT NULL REFERENCES posts(id) ON DELETE CASCADE,
                       user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
                       created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
                       UNIQUE(post_id, user_id)  -- Один лайк на пост от пользователя
);

-- Чаты
CREATE TABLE chats (
                       id SERIAL PRIMARY KEY,
                       user1_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
                       user2_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
                       created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
                       UNIQUE(user1_id, user2_id),  -- Уникальный чат между двумя пользователями
                       CHECK (user1_id < user2_id)  -- Предотвращение дублирования чатов (1-2 и 2-1)
);
-- Сообщения
                           CREATE TABLE messages (
                           id SERIAL PRIMARY KEY,
                           chat_id INTEGER NOT NULL REFERENCES chats(id) ON DELETE CASCADE,
                           sender_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
                           receiver_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
                           content TEXT NOT NULL,
                           status VARCHAR(20) NOT NULL DEFAULT 'sent' CHECK (status IN ('sent', 'delivered', 'read')),
                           created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW()
                           );

-- Методы восстановления
CREATE TABLE recovery_methods (
                                  id SERIAL PRIMARY KEY,
                                  user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
                                  method_type VARCHAR(20) NOT NULL CHECK (method_type IN ('email', 'phone', 'totp')),
                                  value VARCHAR(255) NOT NULL,  -- email/phone number
                                  is_primary BOOLEAN NOT NULL DEFAULT FALSE,
                                  verified_at TIMESTAMP WITH TIME ZONE,
                                  created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW()
);

-- Запросы восстановления
CREATE TABLE recovery_requests (
                                   id SERIAL PRIMARY KEY,
                                   user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
                                   token VARCHAR(255) NOT NULL,
                                   new_device_id INTEGER REFERENCES devices(id) ON DELETE SET NULL,
                                   status VARCHAR(20) NOT NULL DEFAULT 'pending' CHECK (status IN ('pending', 'completed', 'expired')),
                                   created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
                                   expires_at TIMESTAMP WITH TIME ZONE NOT NULL
);

-- Аудит
CREATE TABLE audit_logs (
                            id SERIAL PRIMARY KEY,
                            user_id INTEGER REFERENCES users(id) ON DELETE SET NULL,
                            action VARCHAR(50) NOT NULL,
                            entity_type VARCHAR(50) NOT NULL,
                            entity_id INTEGER,
                            ip_address VARCHAR(45) NOT NULL,
                            user_agent TEXT NOT NULL,
                            metadata JSONB,
                            status VARCHAR(20) NOT NULL CHECK (status IN ('success', 'failed')),
                            created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW()
);

-- Индексы для улучшения производительности
CREATE INDEX idx_sessions_user_id ON sessions(user_id);
CREATE INDEX idx_sessions_device_id ON sessions(device_id);
CREATE INDEX idx_posts_author_id ON posts(author_id);
CREATE INDEX idx_comments_post_id ON comments(post_id);
CREATE INDEX idx_comments_author_id ON comments(author_id);
CREATE INDEX idx_likes_post_id ON likes(post_id);
CREATE INDEX idx_likes_user_id ON likes(user_id);
CREATE INDEX idx_messages_chat_id ON messages(chat_id);
CREATE INDEX idx_messages_sender_id ON messages(sender_id);
CREATE INDEX idx_messages_receiver_id ON messages(receiver_id);
CREATE INDEX idx_recovery_requests_user_id ON recovery_requests(user_id);
CREATE INDEX idx_recovery_requests_token ON recovery_requests(token);
CREATE INDEX idx_audit_logs_user_id ON audit_logs(user_id);
CREATE INDEX idx_audit_logs_created_at ON audit_logs(created_at);