-- Migration 002: Knowledge graph tables
-- Adds nodes, cells, facts, and graph edges to the unified database.

-- Nodes are entities in the knowledge graph.
-- A node is either a note or an artifact link.
CREATE TABLE IF NOT EXISTS nodes
(
    id        TEXT PRIMARY KEY,
    parent_id TEXT,                -- parent node ID (C2 wiki style hierarchy)
    name      TEXT NOT NULL,       -- human-readable name
    type      TEXT NOT NULL DEFAULT 'note', -- 'note' or 'artifact_link'
    created   TEXT NOT NULL,       -- ISO 8601 UTC
    modified  TEXT NOT NULL,       -- ISO 8601 UTC
    FOREIGN KEY (parent_id) REFERENCES nodes (id)
);
CREATE INDEX IF NOT EXISTS idx_nodes_parent ON nodes (parent_id);
CREATE INDEX IF NOT EXISTS idx_nodes_name ON nodes (name);

-- Many-to-many junction: nodes <-> tags.
CREATE TABLE IF NOT EXISTS node_tags
(
    node_id TEXT NOT NULL,
    tag_id  TEXT NOT NULL,
    FOREIGN KEY (node_id) REFERENCES nodes (id),
    FOREIGN KEY (tag_id) REFERENCES tags (id)
);

-- Many-to-many junction: nodes <-> categories.
CREATE TABLE IF NOT EXISTS node_categories
(
    node_id     TEXT NOT NULL,
    category_id TEXT NOT NULL,
    FOREIGN KEY (node_id) REFERENCES nodes (id),
    FOREIGN KEY (category_id) REFERENCES categories (id)
);

-- Cells are content units within a note.
-- Inspired by Quiver's cell-based structure.
CREATE TABLE IF NOT EXISTS cells
(
    id       TEXT PRIMARY KEY,
    node_id  TEXT NOT NULL,
    type     TEXT NOT NULL DEFAULT 'markdown', -- 'markdown', 'code', etc.
    contents BLOB,
    ordinal  INTEGER NOT NULL DEFAULT 0,       -- display order within the node
    created  TEXT NOT NULL,
    modified TEXT NOT NULL,
    FOREIGN KEY (node_id) REFERENCES nodes (id)
);
CREATE INDEX IF NOT EXISTS idx_cells_node ON cells (node_id);

-- Facts record EAV relationships with transactional history.
-- entity + attribute + transaction form the natural key.
CREATE TABLE IF NOT EXISTS facts
(
    id             TEXT PRIMARY KEY,
    entity_id      TEXT NOT NULL,       -- the subject (node or artifact UUID)
    entity_name    TEXT NOT NULL,       -- human-readable entity name
    attribute_id   TEXT NOT NULL,       -- attribute UUID
    attribute_name TEXT NOT NULL,       -- human-readable attribute name
    value_contents TEXT NOT NULL,
    value_type     TEXT NOT NULL,
    tx_timestamp   INTEGER NOT NULL,    -- Unix epoch of the transaction
    retraction     INTEGER NOT NULL DEFAULT 0 -- 1 = this fact is retracted
);
CREATE INDEX IF NOT EXISTS idx_facts_entity ON facts (entity_id);
CREATE INDEX IF NOT EXISTS idx_facts_attribute ON facts (attribute_id);

-- Graph edges link nodes to other nodes or artifacts.
CREATE TABLE IF NOT EXISTS edges
(
    id        TEXT PRIMARY KEY,
    source_id TEXT NOT NULL,       -- source node UUID
    target_id TEXT NOT NULL,       -- target node or artifact UUID
    relation  TEXT NOT NULL,       -- 'child', 'parent', 'related', 'artifact_link', etc.
    created   TEXT NOT NULL,
    FOREIGN KEY (source_id) REFERENCES nodes (id)
);
CREATE INDEX IF NOT EXISTS idx_edges_source ON edges (source_id);
CREATE INDEX IF NOT EXISTS idx_edges_target ON edges (target_id);

INSERT INTO schema_version (version, applied) VALUES (2, datetime('now'));
