-- Устанавливаем таймзону для сессии, чтобы все timestamp были в UTC
SET TIMEZONE = 'UTC';

-- Таблица пользователей. Основная сущность, хранящая данные для входа.
CREATE TABLE users (
    id SERIAL PRIMARY KEY,
    uuid UUID NOT NULL UNIQUE,
    username VARCHAR(16) NOT NULL UNIQUE,
    email VARCHAR(255) NOT NULL UNIQUE,
    password_hash VARCHAR(60) NOT NULL, -- bcrypt хеши имеют длину 60 символов
    role VARCHAR(20) NOT NULL DEFAULT 'user', -- 'user' или 'admin'
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-- Индекс для быстрого поиска по имени пользователя (хотя UNIQUE уже создает индекс)
CREATE INDEX idx_users_username ON users(username);

-- Таблица профилей. Связана с пользователями и хранит игровые данные (скины, плащи).
CREATE TABLE profiles (
    id SERIAL PRIMARY KEY,
    user_id INTEGER NOT NULL UNIQUE,
    skin_hash VARCHAR(40), -- SHA1 хеш скина (40 символов)
    cape_hash VARCHAR(40), -- SHA1 хеш плаща (40 символов)
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),

    CONSTRAINT fk_user
        FOREIGN KEY(user_id)
        REFERENCES users(id)
        ON DELETE CASCADE -- Если пользователь удален, его профиль тоже удаляется
);

-- Таблица для хранения активных access-токенов (Yggdrasil)
CREATE TABLE access_tokens (
    id SERIAL PRIMARY KEY,
    user_id INTEGER NOT NULL,
    access_token VARCHAR(36) NOT NULL UNIQUE, -- UUIDv4
    client_token VARCHAR(255) NOT NULL,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),

    CONSTRAINT fk_user
        FOREIGN KEY(user_id)
        REFERENCES users(id)
        ON DELETE CASCADE
);

-- Таблица игровых серверов, которые отображаются в мониторинге
CREATE TABLE game_servers (
    id SERIAL PRIMARY KEY,
    name VARCHAR(100) NOT NULL,
    address VARCHAR(255) NOT NULL UNIQUE, -- Например, "mc.example.com:25565"
    is_enabled BOOLEAN NOT NULL DEFAULT TRUE,
    -- Данные, получаемые поллером
    status_json TEXT, -- Полный JSON-ответ от сервера Minecraft
    last_polled_at TIMESTAMPTZ,
    -- Данные, которые мы будем извлекать из JSON для удобства
    motd TEXT,
    player_count INTEGER,
    max_players INTEGER,
    version_name VARCHAR(100),
    ping_backend_server INTEGER -- Пинг от бэкенда до игрового сервера в мс
);

-- Таблица модпаков (сборок)
CREATE TABLE modpacks (
    id SERIAL PRIMARY KEY,
    name VARCHAR(100) NOT NULL UNIQUE, -- Уникальное имя, например, "TechnoMagic"
    display_name VARCHAR(255) NOT NULL, -- Человекочитаемое имя, "TechnoMagic SkyBlock"
    minecraft_version VARCHAR(50) NOT NULL,
    is_active BOOLEAN NOT NULL DEFAULT FALSE,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-- Таблица файлов, принадлежащих модпакам.
-- Хранит метаданные о каждом файле в модпаке.
CREATE TABLE modpack_files (
    id BIGSERIAL PRIMARY KEY,
    modpack_id INTEGER NOT NULL,
    -- Относительный путь файла в клиенте, например, "mods/industrial-craft.jar"
    relative_path TEXT NOT NULL,
    file_hash VARCHAR(40) NOT NULL, -- SHA1 хеш файла
    file_size BIGINT NOT NULL,
    -- URL для скачивания (если файл импортирован с CurseForge/Modrinth)
    download_url TEXT,

    CONSTRAINT fk_modpack
        FOREIGN KEY(modpack_id)
        REFERENCES modpacks(id)
        ON DELETE CASCADE,

    -- Уникальный ключ, чтобы в одном модпаке не было двух файлов с одинаковым путем
    UNIQUE (modpack_id, relative_path)
);

-- Индекс для быстрого поиска файлов по хешу
CREATE INDEX idx_modpack_files_hash ON modpack_files(file_hash);

-- Функция для автоматического обновления поля updated_at
CREATE OR REPLACE FUNCTION trigger_set_timestamp()
RETURNS TRIGGER AS $$
BEGIN
  NEW.updated_at = NOW();
  RETURN NEW;
END;
$$ LANGUAGE plpgsql;

-- Триггеры для таблиц users и profiles
CREATE TRIGGER set_timestamp
BEFORE UPDATE ON users
FOR EACH ROW
EXECUTE FUNCTION trigger_set_timestamp();

CREATE TRIGGER set_timestamp
BEFORE UPDATE ON profiles
FOR EACH ROW
EXECUTE FUNCTION trigger_set_timestamp();

-- Сообщение об успешном завершении миграции
\echo 'Initial schema migration applied successfully.'
