-- Chat Switchboard — 005 Channels & Conversations (SQLite)
-- Consolidated v0.28.0

CREATE TABLE IF NOT EXISTS folders (
    id          TEXT PRIMARY KEY,
    user_id     TEXT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
    name        TEXT NOT NULL,
    parent_id   TEXT REFERENCES folders(id) ON DELETE CASCADE,
    sort_order  INTEGER DEFAULT 0,
    created_at  TEXT DEFAULT (datetime('now')),
    updated_at  TEXT DEFAULT (datetime('now')),
    UNIQUE(user_id, name, parent_id)
);

CREATE INDEX IF NOT EXISTS idx_folders_user ON folders(user_id);
CREATE INDEX IF NOT EXISTS idx_folders_parent ON folders(parent_id);

CREATE TABLE IF NOT EXISTS channels (
    id              TEXT PRIMARY KEY,
    user_id         TEXT REFERENCES users(id) ON DELETE CASCADE,
    title           TEXT NOT NULL,
    description     TEXT,
    type            TEXT DEFAULT 'direct'
                    CHECK (type IN ('direct', 'dm', 'group', 'channel', 'workflow', 'service')),
    model           TEXT,
    system_prompt   TEXT,
    provider_config_id TEXT REFERENCES provider_configs(id) ON DELETE SET NULL,
    is_archived     INTEGER DEFAULT 0,
    is_pinned       INTEGER DEFAULT 0,
    folder_id       TEXT REFERENCES folders(id) ON DELETE SET NULL,
    folder          TEXT,
    team_id         TEXT REFERENCES teams(id) ON DELETE SET NULL,
    settings        TEXT DEFAULT '{}',
    tags            TEXT DEFAULT '[]',
    ai_mode         TEXT NOT NULL DEFAULT 'auto',
    topic           TEXT,
    allow_anonymous INTEGER NOT NULL DEFAULT 0,
    workflow_id      TEXT,
    workflow_version INTEGER,
    current_stage    INTEGER DEFAULT 0,
    stage_data       TEXT DEFAULT '{}',
    workflow_status  TEXT DEFAULT 'active'
                     CHECK (workflow_status IN ('active', 'completed', 'stale', 'cancelled')),
    last_activity_at TEXT DEFAULT (datetime('now')),
    stage_entered_at TEXT,
    kb_auto_inject  INTEGER NOT NULL DEFAULT 0,
    project_id      TEXT,
    workspace_id    TEXT,
    purge_after     TEXT,
    created_at      TEXT DEFAULT (datetime('now')),
    updated_at      TEXT DEFAULT (datetime('now'))
);

CREATE INDEX IF NOT EXISTS idx_channels_user ON channels(user_id);
CREATE INDEX IF NOT EXISTS idx_channels_updated ON channels(updated_at);
CREATE INDEX IF NOT EXISTS idx_channels_type ON channels(type);
CREATE INDEX IF NOT EXISTS idx_channels_team ON channels(team_id);
CREATE INDEX IF NOT EXISTS idx_channels_folder ON channels(folder_id);
CREATE INDEX IF NOT EXISTS idx_channels_project ON channels(project_id);
CREATE INDEX IF NOT EXISTS idx_channels_workspace ON channels(workspace_id);
CREATE INDEX IF NOT EXISTS idx_channels_workflow ON channels(workflow_id);

CREATE TABLE IF NOT EXISTS messages (
    id              TEXT PRIMARY KEY,
    channel_id      TEXT NOT NULL REFERENCES channels(id) ON DELETE CASCADE,
    role            TEXT NOT NULL CHECK (role IN ('user', 'assistant', 'system', 'tool')),
    content         TEXT NOT NULL,
    model           TEXT,
    tokens_used     INTEGER,
    tool_calls      TEXT,
    metadata        TEXT DEFAULT '{}',
    parent_id       TEXT REFERENCES messages(id) ON DELETE SET NULL,
    sibling_index   INTEGER DEFAULT 0,
    participant_type TEXT DEFAULT 'user',
    participant_id  TEXT,
    provider_config_id TEXT REFERENCES provider_configs(id) ON DELETE SET NULL,
    deleted_at      TEXT,
    created_at      TEXT DEFAULT (datetime('now'))
);

CREATE INDEX IF NOT EXISTS idx_messages_channel ON messages(channel_id, created_at);
CREATE INDEX IF NOT EXISTS idx_messages_parent ON messages(parent_id);

CREATE TABLE IF NOT EXISTS channel_participants (
    id              TEXT PRIMARY KEY,
    channel_id      TEXT NOT NULL REFERENCES channels(id) ON DELETE CASCADE,
    participant_type TEXT NOT NULL DEFAULT 'user'
                    CHECK (participant_type IN ('user', 'persona', 'session')),
    participant_id  TEXT NOT NULL,
    role            TEXT NOT NULL DEFAULT 'member'
                    CHECK (role IN ('owner', 'member', 'observer')),
    display_name    TEXT,
    avatar_url      TEXT,
    joined_at       TEXT DEFAULT (datetime('now')),
    last_read_at    TEXT DEFAULT (datetime('now')),
    last_read_message_id TEXT,
    UNIQUE(channel_id, participant_type, participant_id)
);

CREATE INDEX IF NOT EXISTS idx_channel_participants_channel ON channel_participants(channel_id);
CREATE INDEX IF NOT EXISTS idx_channel_participants_ref ON channel_participants(participant_type, participant_id);

CREATE TABLE IF NOT EXISTS channel_models (
    id              TEXT PRIMARY KEY,
    channel_id      TEXT NOT NULL REFERENCES channels(id) ON DELETE CASCADE,
    model_id        TEXT NOT NULL,
    provider_config_id TEXT REFERENCES provider_configs(id) ON DELETE SET NULL,
    persona_id      TEXT REFERENCES personas(id) ON DELETE SET NULL,
    display_name    TEXT,
    system_prompt   TEXT,
    settings        TEXT DEFAULT '{}',
    is_default      INTEGER DEFAULT 0,
    added_at        TEXT DEFAULT (datetime('now'))
);

CREATE UNIQUE INDEX IF NOT EXISTS idx_channel_models_raw
    ON channel_models(channel_id, model_id, provider_config_id) WHERE persona_id IS NULL;
CREATE UNIQUE INDEX IF NOT EXISTS idx_channel_models_persona
    ON channel_models(channel_id, persona_id) WHERE persona_id IS NOT NULL;
CREATE INDEX IF NOT EXISTS idx_channel_models_channel ON channel_models(channel_id);

CREATE TABLE IF NOT EXISTS channel_cursors (
    id              TEXT PRIMARY KEY,
    channel_id      TEXT NOT NULL REFERENCES channels(id) ON DELETE CASCADE,
    user_id         TEXT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
    active_leaf_id  TEXT REFERENCES messages(id) ON DELETE SET NULL,
    updated_at      TEXT DEFAULT (datetime('now')),
    UNIQUE(channel_id, user_id)
);

CREATE INDEX IF NOT EXISTS idx_channel_cursors_channel ON channel_cursors(channel_id);
CREATE INDEX IF NOT EXISTS idx_channel_cursors_user ON channel_cursors(user_id);

CREATE TABLE IF NOT EXISTS user_model_settings (
    id          TEXT PRIMARY KEY,
    user_id     TEXT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
    model_id    TEXT NOT NULL,
    provider_config_id TEXT NOT NULL REFERENCES provider_configs(id) ON DELETE CASCADE,
    hidden      INTEGER DEFAULT 0,
    preferred_temperature REAL,
    preferred_max_tokens  INTEGER,
    sort_order  INTEGER DEFAULT 0,
    created_at  TEXT DEFAULT (datetime('now')),
    updated_at  TEXT DEFAULT (datetime('now')),
    UNIQUE(user_id, model_id, provider_config_id)
);

CREATE INDEX IF NOT EXISTS idx_user_model_settings_user ON user_model_settings(user_id);

CREATE TABLE IF NOT EXISTS session_participants (
    id            TEXT PRIMARY KEY,
    session_token TEXT NOT NULL UNIQUE,
    channel_id    TEXT NOT NULL REFERENCES channels(id) ON DELETE CASCADE,
    display_name  TEXT NOT NULL DEFAULT 'Visitor',
    fingerprint   TEXT,
    created_at    TEXT NOT NULL DEFAULT (datetime('now'))
);

CREATE INDEX IF NOT EXISTS idx_session_participants_channel ON session_participants(channel_id);
CREATE INDEX IF NOT EXISTS idx_session_participants_token ON session_participants(session_token);
