-- Claude Finder Database Schema
-- Stores indexed conversation data with tree structure

-- Enable WAL mode for better concurrent access (prevents corruption)
PRAGMA journal_mode=WAL;
PRAGMA synchronous=NORMAL;

CREATE TABLE IF NOT EXISTS messages (
    -- Identity
    message_uuid TEXT PRIMARY KEY,
    session_id TEXT NOT NULL,

    -- Tree structure
    parent_uuid TEXT,  -- NULL for root messages
    is_sidechain BOOLEAN DEFAULT FALSE,
    depth INTEGER DEFAULT 0,  -- Distance from root

    -- Metadata
    timestamp TEXT NOT NULL,
    message_type TEXT NOT NULL CHECK(message_type IN ('user', 'assistant')),
    project_path TEXT,
    conversation_file TEXT,  -- Path to the JSONL file

    -- Content
    summary TEXT,  -- Generated by Haiku (1-2 sentences)
    full_content TEXT NOT NULL,

    -- Summarization tracking
    is_summarized BOOLEAN DEFAULT FALSE,
    is_tool_noise BOOLEAN DEFAULT FALSE,
    is_meta_conversation BOOLEAN DEFAULT FALSE,
    summary_method TEXT CHECK(summary_method IN ('truncation', 'ai_generated', 'too_short', NULL)),

    -- Indexing
    indexed_at TEXT DEFAULT CURRENT_TIMESTAMP,

    FOREIGN KEY (parent_uuid) REFERENCES messages(message_uuid)
);

-- Index for tree traversal
CREATE INDEX IF NOT EXISTS idx_parent_uuid ON messages(parent_uuid);
CREATE INDEX IF NOT EXISTS idx_session_id ON messages(session_id);
CREATE INDEX IF NOT EXISTS idx_timestamp ON messages(timestamp DESC);
CREATE INDEX IF NOT EXISTS idx_project_path ON messages(project_path);
CREATE INDEX IF NOT EXISTS idx_is_summarized ON messages(is_summarized);
CREATE INDEX IF NOT EXISTS idx_is_tool_noise ON messages(is_tool_noise);
CREATE INDEX IF NOT EXISTS idx_is_meta_conversation ON messages(is_meta_conversation);

-- Full-text search on summaries (lightweight)
CREATE VIRTUAL TABLE IF NOT EXISTS message_summaries_fts USING fts5(
    message_uuid UNINDEXED,
    summary,
    content='messages',
    content_rowid='rowid'
);

-- Triggers to keep FTS in sync
CREATE TRIGGER IF NOT EXISTS messages_ai AFTER INSERT ON messages BEGIN
    INSERT INTO message_summaries_fts(rowid, message_uuid, summary)
    VALUES (new.rowid, new.message_uuid, new.summary);
END;

CREATE TRIGGER IF NOT EXISTS messages_ad AFTER DELETE ON messages BEGIN
    DELETE FROM message_summaries_fts WHERE rowid = old.rowid;
END;

CREATE TRIGGER IF NOT EXISTS messages_au AFTER UPDATE ON messages BEGIN
    DELETE FROM message_summaries_fts WHERE rowid = old.rowid;
    INSERT INTO message_summaries_fts(rowid, message_uuid, summary)
    VALUES (new.rowid, new.message_uuid, new.summary);
END;

-- Conversation metadata (one per session)
CREATE TABLE IF NOT EXISTS conversations (
    session_id TEXT PRIMARY KEY,
    project_path TEXT,
    conversation_file TEXT,
    root_message_uuid TEXT,
    leaf_message_uuid TEXT,  -- From the summary line
    conversation_summary TEXT,  -- From the first line of JSONL
    first_message_at TEXT,
    last_message_at TEXT,
    message_count INTEGER DEFAULT 0,
    indexed_at TEXT DEFAULT CURRENT_TIMESTAMP,

    FOREIGN KEY (root_message_uuid) REFERENCES messages(message_uuid)
);

CREATE INDEX IF NOT EXISTS idx_conv_project ON conversations(project_path);
CREATE INDEX IF NOT EXISTS idx_conv_last_message ON conversations(last_message_at DESC);

-- Processing queue for new/updated files
CREATE TABLE IF NOT EXISTS index_queue (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    file_path TEXT UNIQUE NOT NULL,
    discovered_at TEXT DEFAULT CURRENT_TIMESTAMP,
    processed_at TEXT,
    status TEXT DEFAULT 'pending' CHECK(status IN ('pending', 'processing', 'completed', 'failed')),
    error_message TEXT
);

CREATE INDEX IF NOT EXISTS idx_queue_status ON index_queue(status);
