CREATE EXTENSION IF NOT EXISTS "pgcrypto";

CREATE TABLE IF NOT EXISTS users (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    username TEXT UNIQUE NOT NULL,
    client_salt TEXT NOT NULL,
    encrypted_master_key TEXT NOT NULL,
    hashed_auth_key TEXT NOT NULL,
    public_identity_key TEXT NOT NULL,
    public_signing_key TEXT NOT NULL,
    encrypted_private_keys TEXT NOT NULL, 
    is_admin BOOLEAN DEFAULT FALSE,
    created_at TIMESTAMPTZ DEFAULT NOW()
);

CREATE TABLE IF NOT EXISTS channels (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    name TEXT UNIQUE NOT NULL,
    type TEXT DEFAULT 'text' CHECK (type IN ('text', 'voice')),
    created_at TIMESTAMPTZ DEFAULT NOW()
);

CREATE TABLE IF NOT EXISTS roles (
    id SERIAL PRIMARY KEY,
    name TEXT NOT NULL,
    color TEXT DEFAULT '#99aab5',
    position INTEGER DEFAULT 0,
    permissions JSONB DEFAULT '{}',
    is_hoist BOOLEAN DEFAULT FALSE,
    created_at TIMESTAMPTZ DEFAULT NOW()
);

CREATE TABLE IF NOT EXISTS user_roles (
    user_id UUID REFERENCES users(id) ON DELETE CASCADE,
    role_id INTEGER REFERENCES roles(id) ON DELETE CASCADE,
    PRIMARY KEY (user_id, role_id)
);

CREATE TABLE IF NOT EXISTS channel_keys (
    channel_id UUID NOT NULL,
    user_id UUID NOT NULL,
    encrypted_key_bundle TEXT NOT NULL,
    key_version INTEGER DEFAULT 1,
    PRIMARY KEY (channel_id, user_id)
);

CREATE TABLE IF NOT EXISTS messages (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    channel_id UUID NOT NULL,
    sender_id UUID NOT NULL,
    ciphertext TEXT NOT NULL,
    nonce TEXT NOT NULL,
    signature TEXT NOT NULL,
    key_version INTEGER NOT NULL,
    created_at TIMESTAMPTZ DEFAULT NOW()
);

CREATE TABLE IF NOT EXISTS invites (
    code TEXT PRIMARY KEY,               -- e.g. "8f1a4c..." (The ID of the invite)
    encrypted_payload TEXT NOT NULL,     -- The AES-Encrypted Key Bundle (Server can't read this)
    created_by UUID REFERENCES users(id) ON DELETE CASCADE,
    max_uses INTEGER DEFAULT NULL,       -- NULL = Infinite
    uses INTEGER DEFAULT 0,
    expires_at TIMESTAMPTZ DEFAULT NULL,   -- NULL = Never
    key_version INTEGER NOT NULL,        -- Which key version is inside? (So we can invalidate leaks)
    created_at TIMESTAMPTZ DEFAULT NOW()
);
