-- Meldingsboks: Universell diskusjonsprimitiv
-- Erstatter separate tabeller for kanban-kort, kalenderhendelser, faktoider og notater.
-- Alle disse blir meldingsbokser (messages) med view-config-tabeller.
-- Se docs/features/meldingsboks.md for full spec.
--
-- Avhenger av: 0001, 0002, 0003, 0004

BEGIN;

-- ============================================================
-- 1. ALTER messages-tabellen
-- ============================================================

-- channel_id nullable (notater, standalone-bokser trenger ikke channel)
ALTER TABLE messages ALTER COLUMN channel_id DROP NOT NULL;

-- Nye kolonner
ALTER TABLE messages ADD COLUMN title TEXT;
ALTER TABLE messages ADD COLUMN pinned BOOLEAN NOT NULL DEFAULT false;
ALTER TABLE messages ADD COLUMN visibility TEXT NOT NULL DEFAULT 'workspace';
ALTER TABLE messages ADD COLUMN updated_at TIMESTAMPTZ NOT NULL DEFAULT now();

-- Indeks for reply_to (tråd-oppslag)
CREATE INDEX IF NOT EXISTS idx_messages_reply ON messages(reply_to) WHERE reply_to IS NOT NULL;

-- updated_at trigger
CREATE TRIGGER trg_messages_updated_at BEFORE UPDATE ON messages
    FOR EACH ROW EXECUTE FUNCTION set_updated_at();

-- ============================================================
-- 2. View-config-tabeller
-- ============================================================

-- Kanban: view-metadata for meldingsbokser som vises som kort
CREATE TABLE kanban_card_view (
    message_id  UUID PRIMARY KEY REFERENCES messages(id) ON DELETE CASCADE,
    column_id   UUID NOT NULL REFERENCES kanban_columns(id) ON DELETE CASCADE,
    position    REAL NOT NULL DEFAULT 0,
    color       TEXT,
    assignee_id TEXT REFERENCES users(authentik_id) ON DELETE SET NULL
);

CREATE INDEX idx_kanban_card_view_column ON kanban_card_view(column_id, position);

-- Kalender: view-metadata for meldingsbokser som vises som hendelser
CREATE TABLE calendar_event_view (
    message_id  UUID PRIMARY KEY REFERENCES messages(id) ON DELETE CASCADE,
    calendar_id UUID NOT NULL REFERENCES calendars(id) ON DELETE CASCADE,
    starts_at   TIMESTAMPTZ NOT NULL,
    ends_at     TIMESTAMPTZ,
    all_day     BOOLEAN NOT NULL DEFAULT false,
    color       TEXT
);

CREATE INDEX idx_calendar_event_view_calendar ON calendar_event_view(calendar_id, starts_at);

-- ============================================================
-- 3. Migrer kanban_cards → messages + kanban_card_view
-- ============================================================

-- Oppdater node_type til 'melding'
UPDATE nodes SET node_type = 'melding'
WHERE id IN (SELECT id FROM kanban_cards);

-- Opprett meldingsbokser fra kanban-kort
INSERT INTO messages (id, channel_id, author_id, message_type, title, body, created_at, updated_at)
SELECT
    kc.id,
    NULL,
    kc.created_by,
    'text',
    kc.title,
    COALESCE(kc.description, ''),
    kc.created_at,
    kc.updated_at
FROM kanban_cards kc;

-- Opprett kanban view-config
INSERT INTO kanban_card_view (message_id, column_id, position, assignee_id)
SELECT
    kc.id,
    kc.column_id,
    kc.position,
    kc.assignee_id
FROM kanban_cards kc;

-- ============================================================
-- 4. Migrer calendar_events → messages + calendar_event_view
-- ============================================================

UPDATE nodes SET node_type = 'melding'
WHERE id IN (SELECT id FROM calendar_events);

INSERT INTO messages (id, channel_id, author_id, message_type, title, body, created_at, updated_at)
SELECT
    ce.id,
    NULL,
    ce.created_by,
    'text',
    ce.title,
    COALESCE(ce.description, ''),
    ce.created_at,
    ce.created_at
FROM calendar_events ce;

INSERT INTO calendar_event_view (message_id, calendar_id, starts_at, ends_at, all_day, color)
SELECT
    ce.id,
    ce.calendar_id,
    ce.starts_at,
    ce.ends_at,
    ce.all_day,
    ce.color
FROM calendar_events ce;

-- ============================================================
-- 5. Reaksjoner (erstatter message_votes og factoid_votes)
-- ============================================================

CREATE TABLE message_reactions (
    message_id UUID NOT NULL REFERENCES messages(id) ON DELETE CASCADE,
    user_id    TEXT NOT NULL REFERENCES users(authentik_id) ON DELETE CASCADE,
    reaction   TEXT NOT NULL,
    created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
    PRIMARY KEY (message_id, user_id, reaction)
);

-- Migrer eksisterende message_votes til reactions
INSERT INTO message_reactions (message_id, user_id, reaction, created_at)
SELECT
    mv.message_id,
    mv.user_id,
    CASE WHEN mv.vote = 1 THEN 'upvote' ELSE 'downvote' END,
    mv.created_at
FROM message_votes mv;

-- ============================================================
-- 6. Migrer factoids → messages
-- ============================================================

UPDATE nodes SET node_type = 'melding'
WHERE id IN (SELECT id FROM factoids);

INSERT INTO messages (id, channel_id, author_id, message_type, body, created_at, updated_at)
SELECT
    f.id,
    NULL,
    f.created_by,
    'factoid',
    f.body,
    f.created_at,
    f.created_at
FROM factoids f;

-- Flytt factoid_votes til reactions
INSERT INTO message_reactions (message_id, user_id, reaction, created_at)
SELECT
    fv.factoid_id,
    fv.user_id,
    CASE WHEN fv.vote = 1 THEN 'upvote' ELSE 'downvote' END,
    fv.created_at
FROM factoid_votes fv
ON CONFLICT (message_id, user_id, reaction) DO NOTHING;

-- ============================================================
-- 7. Migrer notes → messages
-- ============================================================

UPDATE nodes SET node_type = 'melding'
WHERE id IN (SELECT id FROM notes);

INSERT INTO messages (id, channel_id, author_id, message_type, title, body, created_at, updated_at)
SELECT
    n.id,
    NULL,
    n.created_by,
    'text',
    n.title,
    COALESCE(n.content, ''),
    n.created_at,
    n.updated_at
FROM notes n;

-- ============================================================
-- 8. Drop gamle tabeller
-- ============================================================

-- Triggers først
DROP TRIGGER IF EXISTS trg_kanban_cards_updated_at ON kanban_cards;
DROP TRIGGER IF EXISTS trg_calendar_events_updated_at ON calendar_events;
DROP TRIGGER IF EXISTS trg_notes_updated_at ON notes;

-- Tabeller (rekkefølge: FK-avhengigheter)
DROP TABLE factoid_votes;
DROP TABLE factoids;
DROP TABLE message_votes;
DROP TABLE kanban_cards;
DROP TABLE calendar_events;
DROP TABLE notes;

-- ============================================================
-- RLS: Ikke nødvendig på messages/view-config-tabeller.
-- Workspace-isolasjon arves via FK til nodes (samme mønster
-- som episodes, segments, entities).
-- ============================================================

COMMIT;

-- ============================================================
-- 9. Entities (erstatter actors + topics)
-- ============================================================
-- Alt som kan nevnes med # er en entitet: personer, organisasjoner,
-- steder, temaer, konsepter. Én tabell, én autocomplete.
--
-- ALTER TYPE ADD VALUE kan ikke kjøres i en transaksjon (PG < 16),
-- derfor utenfor BEGIN/COMMIT-blokken.

ALTER TYPE node_type ADD VALUE IF NOT EXISTS 'entitet';

BEGIN;

CREATE TABLE entities (
    id         UUID PRIMARY KEY REFERENCES nodes(id) ON DELETE CASCADE,
    name       TEXT NOT NULL,
    type       TEXT NOT NULL,          -- 'person', 'organisasjon', 'sted', 'tema', 'konsept'
    aliases    TEXT[] DEFAULT '{}',    -- Forkortelser, kallenavn: {'JGS', 'Støre'}
    avatar_url TEXT
);

CREATE INDEX idx_entities_name ON entities(name);
CREATE INDEX idx_entities_aliases ON entities USING GIN(aliases);

-- Migrer actors → entities
INSERT INTO entities (id, name, type)
SELECT id, name, COALESCE(type, 'person')
FROM actors;

UPDATE nodes SET node_type = 'entitet'
WHERE id IN (SELECT id FROM actors);

-- Migrer topics → entities
INSERT INTO entities (id, name, type)
SELECT id, name, 'tema'
FROM topics;

UPDATE nodes SET node_type = 'entitet'
WHERE id IN (SELECT id FROM topics);

DROP TABLE actors;
DROP TABLE topics;

-- ============================================================
-- RLS: Ikke nødvendig på messages/view-config/entities.
-- Workspace-isolasjon arves via FK til nodes (samme mønster
-- som episodes, segments).
-- ============================================================

COMMIT;
