-- ==========================================
-- Chat Switchboard — 007 Notes & Links
-- ==========================================
-- Notes with full-text search, wikilink graph edges.
-- ICD §6 (Notes)
-- ==========================================

-- =========================================
-- NOTES
-- =========================================

CREATE TABLE IF NOT EXISTS notes (
    id                  UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    user_id             UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
    title               VARCHAR(500) NOT NULL,
    content             TEXT DEFAULT '',
    folder_path         TEXT DEFAULT '/',
    tags                TEXT[] DEFAULT '{}',
    metadata            JSONB DEFAULT '{}',
    source_channel_id   UUID REFERENCES channels(id) ON DELETE SET NULL,
    source_message_id   UUID,
    team_id             UUID REFERENCES teams(id) ON DELETE SET NULL,
    search_vector       TSVECTOR,
    embedding           VECTOR(3072),
    created_at          TIMESTAMPTZ DEFAULT NOW(),
    updated_at          TIMESTAMPTZ DEFAULT NOW()
);

CREATE INDEX IF NOT EXISTS idx_notes_user ON notes(user_id);
CREATE INDEX IF NOT EXISTS idx_notes_search ON notes USING GIN(search_vector);
CREATE INDEX IF NOT EXISTS idx_notes_folder ON notes(user_id, folder_path);
CREATE INDEX IF NOT EXISTS idx_notes_tags ON notes USING GIN(tags);
CREATE INDEX IF NOT EXISTS idx_notes_updated ON notes(user_id, updated_at DESC);
CREATE INDEX IF NOT EXISTS idx_notes_team ON notes(team_id) WHERE team_id IS NOT NULL;
CREATE INDEX IF NOT EXISTS idx_notes_source_msg ON notes(source_message_id)
    WHERE source_message_id IS NOT NULL;

CREATE OR REPLACE FUNCTION notes_search_update_fn()
RETURNS TRIGGER AS $$
BEGIN
    NEW.search_vector :=
        setweight(to_tsvector('pg_catalog.english', COALESCE(NEW.title, '')), 'A') ||
        setweight(to_tsvector('pg_catalog.english', COALESCE(NEW.content, '')), 'B');
    NEW.updated_at := NOW();
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

DROP TRIGGER IF EXISTS notes_search_update ON notes;
CREATE TRIGGER notes_search_update
    BEFORE INSERT OR UPDATE OF title, content ON notes
    FOR EACH ROW EXECUTE FUNCTION notes_search_update_fn();


-- =========================================
-- NOTE LINKS (v0.17.3 — wikilink graph)
-- =========================================

CREATE TABLE IF NOT EXISTS note_links (
    source_note_id  UUID NOT NULL REFERENCES notes(id) ON DELETE CASCADE,
    target_note_id  UUID REFERENCES notes(id) ON DELETE CASCADE,
    target_title    TEXT NOT NULL,
    display_text    TEXT,
    is_transclusion BOOLEAN NOT NULL DEFAULT FALSE,
    created_at      TIMESTAMPTZ DEFAULT now(),
    PRIMARY KEY (source_note_id, target_title)
);

CREATE INDEX IF NOT EXISTS idx_note_links_target ON note_links(target_note_id)
    WHERE target_note_id IS NOT NULL;

COMMENT ON TABLE note_links IS 'Directed links between notes, extracted from [[wikilink]] syntax on save';
COMMENT ON COLUMN note_links.target_note_id IS 'NULL for unresolved links (target note does not exist yet)';
COMMENT ON COLUMN note_links.target_title IS 'Raw [[title]] text — preserved for re-resolution after renames';
COMMENT ON COLUMN note_links.is_transclusion IS 'true for ![[embed]] syntax, false for regular [[link]]';
