-- SQL Script to initialize the Supabase PostgreSQL database
-- Copy and paste this into the Supabase SQL Editor (SQL Editor -> New Query)

-- 1. STREAMS TABLE
CREATE TABLE IF NOT EXISTS streams (
    id SERIAL PRIMARY KEY,
    start_time TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
    end_time TIMESTAMP WITH TIME ZONE,
    title TEXT,
    twitch_stream_id TEXT UNIQUE,
    category TEXT,
    backfill_status TEXT DEFAULT 'pending',
    twitch_vod_id TEXT
);

-- 2. MESSAGES TABLE
CREATE TABLE IF NOT EXISTS messages (
    id TEXT PRIMARY KEY, -- Twitch Message ID (UUID-like from tags)
    stream_id INTEGER REFERENCES streams(id) ON DELETE SET NULL,
    username TEXT NOT NULL,
    display_name TEXT,
    message TEXT NOT NULL,
    timestamp TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
    is_streamer BOOLEAN DEFAULT FALSE,
    is_mod BOOLEAN DEFAULT FALSE,
    is_sub BOOLEAN DEFAULT FALSE
);

-- Create indexes for fast querying and statistics aggregation
CREATE INDEX IF NOT EXISTS idx_messages_stream_id ON messages(stream_id);
CREATE INDEX IF NOT EXISTS idx_messages_username ON messages(username);
CREATE INDEX IF NOT EXISTS idx_messages_timestamp ON messages(timestamp);

-- 2.5 STREAM VIEWERS TABLE
CREATE TABLE IF NOT EXISTS stream_viewers (
    stream_id INTEGER REFERENCES streams(id) ON DELETE CASCADE,
    username TEXT NOT NULL,
    display_name TEXT,
    has_chatted BOOLEAN DEFAULT FALSE,
    is_mod BOOLEAN DEFAULT FALSE,
    is_sub BOOLEAN DEFAULT FALSE,
    first_seen TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
    PRIMARY KEY (stream_id, username)
);
CREATE INDEX IF NOT EXISTS idx_stream_viewers_stream_id ON stream_viewers(stream_id);

-- 2.6 CHAT USERS TABLE
CREATE TABLE IF NOT EXISTS chat_users (
    username TEXT PRIMARY KEY,
    display_name TEXT,
    is_mod BOOLEAN DEFAULT FALSE,
    is_sub BOOLEAN DEFAULT FALSE,
    is_vip BOOLEAN DEFAULT FALSE,
    last_seen TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);

-- 3. VOICE WORDS TABLE (transcribed spoken words from streamer)
CREATE TABLE IF NOT EXISTS voice_words (
    id SERIAL PRIMARY KEY,
    stream_id INTEGER REFERENCES streams(id) ON DELETE CASCADE,
    word TEXT NOT NULL,
    timestamp TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);

CREATE INDEX IF NOT EXISTS idx_voice_words_stream_id ON voice_words(stream_id);
CREATE INDEX IF NOT EXISTS idx_voice_words_word ON voice_words(word);

-- 4. MOD ACTIONS TABLE (from EventSub: bans, timeouts, message deletions)
CREATE TABLE IF NOT EXISTS mod_actions (
    id SERIAL PRIMARY KEY,
    stream_id INTEGER REFERENCES streams(id) ON DELETE SET NULL,
    action_type TEXT NOT NULL, -- 'ban', 'timeout', 'unban', 'delete'
    moderator TEXT NOT NULL, -- Moderator's username
    target_user TEXT, -- Banned/timed out user's username
    duration INTEGER, -- Timeout duration in seconds (NULL for bans/deletions)
    reason TEXT, -- Reason provided
    message_text TEXT, -- Text of deleted message (for 'delete' action)
    timestamp TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
    reaction_time REAL
);

CREATE INDEX IF NOT EXISTS idx_mod_actions_stream_id ON mod_actions(stream_id);
CREATE INDEX IF NOT EXISTS idx_mod_actions_timestamp ON mod_actions(timestamp);

-- 5. SETTINGS TABLE (for persistent oauth tokens, etc.)
CREATE TABLE IF NOT EXISTS settings (
    key TEXT PRIMARY KEY,
    value TEXT NOT NULL,
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);

-- A trigger to automatically update updated_at in settings table
CREATE OR REPLACE FUNCTION update_modified_column()
RETURNS TRIGGER AS $$
BEGIN
    NEW.updated_at = now();
    RETURN NEW;
END;
$$ language 'plpgsql';

CREATE OR REPLACE TRIGGER update_settings_modtime
    BEFORE UPDATE ON settings
    FOR EACH ROW
    EXECUTE FUNCTION update_modified_column();

-- =========================================================================
-- HELPER VIEWS FOR STATISTICS
-- =========================================================================

-- View for chatter statistics per stream
DROP VIEW IF EXISTS stream_chatter_stats;
CREATE VIEW stream_chatter_stats AS
SELECT 
    v.stream_id,
    v.username,
    u.display_name,
    u.is_mod,
    u.is_sub,
    u.is_vip,
    v.has_chatted,
    v.first_seen,
    (SELECT COUNT(*) FROM messages m WHERE m.stream_id = v.stream_id AND m.username = v.username) as message_count
FROM stream_viewers v
LEFT JOIN chat_users u ON v.username = u.username;

-- View for chatter statistics overall (all-time)
DROP VIEW IF EXISTS global_chatter_stats;
CREATE VIEW global_chatter_stats AS
SELECT 
    m.username,
    u.display_name,
    u.is_mod,
    u.is_sub,
    u.is_vip,
    count(*) as message_count
FROM messages m
LEFT JOIN chat_users u ON m.username = u.username
GROUP BY m.username, u.display_name, u.is_mod, u.is_sub, u.is_vip;

-- View for spoken word statistics per stream
CREATE OR REPLACE VIEW stream_voice_word_stats AS
SELECT 
    stream_id,
    word,
    count(*) as word_count
FROM voice_words
GROUP BY stream_id, word;

-- View for spoken word statistics overall (all-time)
CREATE OR REPLACE VIEW global_voice_word_stats AS
SELECT 
    word,
    count(*) as word_count
FROM voice_words
GROUP BY word;
