-- 010: Channel Kinds — text, voice, stage, forum, announcement
--
-- ALTER:
--   channel        — add channel_kind + voice/forum/stage fields
--   message_thread — add forum post fields (title, tags, pinned, locked)
--
-- New tables:
--   forum_tag, voice_participant, stage,
--   message_poll, message_poll_option, message_poll_vote

-- ============================================================
-- 1. ALTER channel — add channel_kind + voice/forum/stage fields
-- ============================================================

ALTER TABLE channel ADD COLUMN IF NOT EXISTS channel_kind TEXT NOT NULL DEFAULT 'text';
ALTER TABLE channel ADD COLUMN IF NOT EXISTS position INTEGER NULL;
ALTER TABLE channel ADD COLUMN IF NOT EXISTS nsfw BOOLEAN NOT NULL DEFAULT FALSE;

-- Voice / Stage specific
ALTER TABLE channel ADD COLUMN IF NOT EXISTS bitrate INTEGER NULL;
ALTER TABLE channel ADD COLUMN IF NOT EXISTS user_limit INTEGER NULL;
ALTER TABLE channel ADD COLUMN IF NOT EXISTS rtc_region TEXT NULL;

-- Forum specific
ALTER TABLE channel ADD COLUMN IF NOT EXISTS default_auto_archive_duration INTEGER NULL;
ALTER TABLE channel ADD COLUMN IF NOT EXISTS default_reaction_emoji TEXT NULL;
ALTER TABLE channel ADD COLUMN IF NOT EXISTS default_sort_order TEXT NULL;
ALTER TABLE channel ADD COLUMN IF NOT EXISTS default_forum_layout TEXT NULL;
ALTER TABLE channel ADD COLUMN IF NOT EXISTS require_tag BOOLEAN NULL;
ALTER TABLE channel ADD COLUMN IF NOT EXISTS available_tags JSONB NULL;
ALTER TABLE channel ADD COLUMN IF NOT EXISTS default_thread_rate_limit INTEGER NULL;

-- General
ALTER TABLE channel ADD COLUMN IF NOT EXISTS rate_limit_per_user INTEGER NULL;
ALTER TABLE channel ADD COLUMN IF NOT EXISTS parent_channel_id UUID NULL REFERENCES channel(id) ON DELETE SET NULL;

CREATE INDEX IF NOT EXISTS idx_channel_channel_kind ON channel (channel_kind);
CREATE INDEX IF NOT EXISTS idx_channel_parent_channel_id ON channel (parent_channel_id);

-- ============================================================
-- 2. ALTER message_thread — add forum post fields
-- ============================================================

ALTER TABLE message_thread ADD COLUMN IF NOT EXISTS title TEXT NULL;
ALTER TABLE message_thread ADD COLUMN IF NOT EXISTS tags TEXT[] NOT NULL DEFAULT '{}';
ALTER TABLE message_thread ADD COLUMN IF NOT EXISTS pinned BOOLEAN NOT NULL DEFAULT FALSE;
ALTER TABLE message_thread ADD COLUMN IF NOT EXISTS locked BOOLEAN NOT NULL DEFAULT FALSE;
ALTER TABLE message_thread ADD COLUMN IF NOT EXISTS rate_limit_per_user INTEGER NULL;
ALTER TABLE message_thread ADD COLUMN IF NOT EXISTS auto_archive_at TIMESTAMPTZ NULL;

CREATE INDEX IF NOT EXISTS idx_message_thread_pinned ON message_thread (pinned) WHERE pinned;

-- ============================================================
-- 3. Forum Tags
-- ============================================================

-- models/channels/forum_tags.rs  →  forum_tag
CREATE TABLE IF NOT EXISTS forum_tag (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    channel_id UUID NOT NULL REFERENCES channel(id) ON DELETE CASCADE,
    name TEXT NOT NULL,
    emoji_id TEXT NULL,
    emoji_name TEXT NULL,
    moderated BOOLEAN NOT NULL,
    position INTEGER NOT NULL,
    created_by UUID NOT NULL REFERENCES "user"(id) ON DELETE CASCADE,
    created_at TIMESTAMPTZ NOT NULL,
    updated_at TIMESTAMPTZ NOT NULL,
    CONSTRAINT uq_forum_tag_channel_name UNIQUE (channel_id, name)
);
CREATE INDEX IF NOT EXISTS idx_forum_tag_channel_id ON forum_tag (channel_id);

-- ============================================================
-- 4. Voice Participants
-- ============================================================

-- models/channels/voice_participants.rs  →  voice_participant
CREATE TABLE IF NOT EXISTS voice_participant (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    channel_id UUID NOT NULL REFERENCES channel(id) ON DELETE CASCADE,
    user_id UUID NOT NULL REFERENCES "user"(id) ON DELETE CASCADE,
    session_id TEXT NULL,
    deafened BOOLEAN NOT NULL,
    muted BOOLEAN NOT NULL,
    self_deafened BOOLEAN NOT NULL,
    self_muted BOOLEAN NOT NULL,
    self_video BOOLEAN NOT NULL,
    streaming BOOLEAN NOT NULL,
    speaking BOOLEAN NOT NULL,
    joined_at TIMESTAMPTZ NOT NULL,
    left_at TIMESTAMPTZ NULL
);
CREATE INDEX IF NOT EXISTS idx_voice_participant_channel_id ON voice_participant (channel_id);
CREATE INDEX IF NOT EXISTS idx_voice_participant_user_id ON voice_participant (user_id);
CREATE INDEX IF NOT EXISTS idx_voice_participant_channel_user ON voice_participant (channel_id, user_id);

-- ============================================================
-- 5. Stages
-- ============================================================

-- models/channels/stages.rs  →  stage
CREATE TABLE IF NOT EXISTS stage (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    channel_id UUID NOT NULL REFERENCES channel(id) ON DELETE CASCADE,
    topic TEXT NOT NULL,
    privacy_level TEXT NOT NULL,
    discoverable BOOLEAN NOT NULL,
    started_by UUID NOT NULL REFERENCES "user"(id) ON DELETE CASCADE,
    started_at TIMESTAMPTZ NOT NULL,
    ended_at TIMESTAMPTZ NULL,
    created_at TIMESTAMPTZ NOT NULL,
    updated_at TIMESTAMPTZ NOT NULL,
    CONSTRAINT uq_stage_active_channel UNIQUE (channel_id, ended_at)
);
CREATE INDEX IF NOT EXISTS idx_stage_channel_id ON stage (channel_id);
CREATE INDEX IF NOT EXISTS idx_stage_channel_active ON stage (channel_id) WHERE ended_at IS NULL;

-- ============================================================
-- 6. Message Polls
-- ============================================================

-- models/channels/message_polls.rs  →  message_poll
CREATE TABLE IF NOT EXISTS message_poll (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    message_id UUID NOT NULL REFERENCES message(id) ON DELETE CASCADE,
    channel_id UUID NOT NULL REFERENCES channel(id) ON DELETE CASCADE,
    question TEXT NOT NULL,
    description TEXT NULL,
    layout TEXT NOT NULL,
    allow_multiselect BOOLEAN NOT NULL,
    duration_hours INTEGER NULL,
    ends_at TIMESTAMPTZ NULL,
    total_votes BIGINT NOT NULL,
    metadata JSONB NULL,
    created_at TIMESTAMPTZ NOT NULL,
    updated_at TIMESTAMPTZ NOT NULL,
    CONSTRAINT uq_message_poll_message_id UNIQUE (message_id)
);
CREATE INDEX IF NOT EXISTS idx_message_poll_channel_id ON message_poll (channel_id);
CREATE INDEX IF NOT EXISTS idx_message_poll_ends_at ON message_poll (ends_at) WHERE ends_at IS NOT NULL;

-- ============================================================
-- 7. Message Poll Options
-- ============================================================

-- models/channels/message_poll_options.rs  →  message_poll_option
CREATE TABLE IF NOT EXISTS message_poll_option (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    poll_id UUID NOT NULL REFERENCES message_poll(id) ON DELETE CASCADE,
    position INTEGER NOT NULL,
    text TEXT NOT NULL,
    emoji_id TEXT NULL,
    emoji_name TEXT NULL,
    vote_count BIGINT NOT NULL,
    created_at TIMESTAMPTZ NOT NULL
);
CREATE INDEX IF NOT EXISTS idx_message_poll_option_poll_id ON message_poll_option (poll_id);

-- ============================================================
-- 8. Message Poll Votes
-- ============================================================

-- models/channels/message_poll_votes.rs  →  message_poll_vote
CREATE TABLE IF NOT EXISTS message_poll_vote (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    poll_id UUID NOT NULL REFERENCES message_poll(id) ON DELETE CASCADE,
    option_id UUID NOT NULL REFERENCES message_poll_option(id) ON DELETE CASCADE,
    user_id UUID NOT NULL REFERENCES "user"(id) ON DELETE CASCADE,
    voted_at TIMESTAMPTZ NOT NULL,
    CONSTRAINT uq_message_poll_vote_user_option UNIQUE (poll_id, option_id, user_id)
);
CREATE INDEX IF NOT EXISTS idx_message_poll_vote_poll_id ON message_poll_vote (poll_id);
CREATE INDEX IF NOT EXISTS idx_message_poll_vote_user_id ON message_poll_vote (user_id);
CREATE INDEX IF NOT EXISTS idx_message_poll_vote_option_id ON message_poll_vote (option_id);

-- ============================================================
-- 9. Triggers — auto-refresh updated_at
-- ============================================================

DROP TRIGGER IF EXISTS trg_forum_tag_updated_at ON forum_tag;
CREATE TRIGGER trg_forum_tag_updated_at BEFORE UPDATE ON forum_tag FOR EACH ROW EXECUTE FUNCTION set_updated_at();

DROP TRIGGER IF EXISTS trg_stage_updated_at ON stage;
CREATE TRIGGER trg_stage_updated_at BEFORE UPDATE ON stage FOR EACH ROW EXECUTE FUNCTION set_updated_at();

DROP TRIGGER IF EXISTS trg_message_poll_updated_at ON message_poll;
CREATE TRIGGER trg_message_poll_updated_at BEFORE UPDATE ON message_poll FOR EACH ROW EXECUTE FUNCTION set_updated_at();
