-- 091_messaging_redesign.sql
-- Unified conversation model: replaces separate private_messages + message_group
-- Conversations (1:1 and group), messages, reactions, pins

BEGIN;

-- Unified conversations (1:1 or group)
CREATE TABLE conversations (
    id SERIAL PRIMARY KEY,
    name VARCHAR(255),
    is_group BOOLEAN NOT NULL DEFAULT FALSE,
    owner_id INTEGER REFERENCES users(id) ON DELETE SET NULL,
    created_at TIMESTAMP NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMP NOT NULL DEFAULT NOW(),
    last_message_id INTEGER  -- FK added below after conv_messages exists
);

CREATE INDEX idx_conversations_owner ON conversations(owner_id);
CREATE INDEX idx_conversations_updated ON conversations(updated_at DESC);

-- Conversation membership
CREATE TABLE conversation_members (
    conversation_id INTEGER NOT NULL REFERENCES conversations(id) ON DELETE CASCADE,
    user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
    role VARCHAR(20) NOT NULL DEFAULT 'member',
    last_read_at TIMESTAMP,
    is_muted BOOLEAN NOT NULL DEFAULT FALSE,
    is_archived BOOLEAN NOT NULL DEFAULT FALSE,
    joined_at TIMESTAMP NOT NULL DEFAULT NOW(),
    added_by_id INTEGER REFERENCES users(id) ON DELETE SET NULL,
    PRIMARY KEY (conversation_id, user_id)
);

CREATE INDEX idx_conversation_members_user ON conversation_members(user_id);

-- Messages within a conversation
CREATE TABLE conv_messages (
    id SERIAL PRIMARY KEY,
    conversation_id INTEGER NOT NULL REFERENCES conversations(id) ON DELETE CASCADE,
    sender_id INTEGER REFERENCES users(id) ON DELETE SET NULL,
    content TEXT NOT NULL,
    reply_to_id INTEGER REFERENCES conv_messages(id) ON DELETE SET NULL,
    edited_at TIMESTAMP,
    is_deleted BOOLEAN NOT NULL DEFAULT FALSE,
    link_preview JSONB,
    created_at TIMESTAMP NOT NULL DEFAULT NOW()
);

CREATE INDEX idx_conv_messages_conversation ON conv_messages(conversation_id);
CREATE INDEX idx_conv_messages_created ON conv_messages(created_at);
CREATE INDEX idx_conv_messages_conversation_created ON conv_messages(conversation_id, created_at);

-- Now add the deferred FK from conversations.last_message_id -> conv_messages.id
ALTER TABLE conversations
    ADD CONSTRAINT fk_conversations_last_message
    FOREIGN KEY (last_message_id) REFERENCES conv_messages(id) ON DELETE SET NULL;

-- Emoji reactions on messages
CREATE TABLE message_reactions (
    id SERIAL PRIMARY KEY,
    message_id INTEGER NOT NULL REFERENCES conv_messages(id) ON DELETE CASCADE,
    user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
    emoji VARCHAR(10) NOT NULL,
    created_at TIMESTAMP NOT NULL DEFAULT NOW(),
    CONSTRAINT uq_message_reaction UNIQUE (message_id, user_id, emoji)
);

CREATE INDEX idx_message_reactions_message ON message_reactions(message_id);

-- Pinned messages
CREATE TABLE message_pins (
    id SERIAL PRIMARY KEY,
    conversation_id INTEGER NOT NULL REFERENCES conversations(id) ON DELETE CASCADE,
    message_id INTEGER NOT NULL REFERENCES conv_messages(id) ON DELETE CASCADE,
    pinned_by_id INTEGER REFERENCES users(id) ON DELETE SET NULL,
    created_at TIMESTAMP NOT NULL DEFAULT NOW()
);

CREATE INDEX idx_message_pins_conversation ON message_pins(conversation_id);

-- Extend message_attachments to support conv_messages
ALTER TABLE message_attachments ADD COLUMN conv_message_id INTEGER REFERENCES conv_messages(id) ON DELETE CASCADE;
CREATE INDEX idx_message_attachments_conv ON message_attachments(conv_message_id) WHERE conv_message_id IS NOT NULL;

-- Grants
GRANT ALL ON TABLE conversations TO nordabiz_app;
GRANT ALL ON TABLE conversation_members TO nordabiz_app;
GRANT ALL ON TABLE conv_messages TO nordabiz_app;
GRANT ALL ON TABLE message_reactions TO nordabiz_app;
GRANT ALL ON TABLE message_pins TO nordabiz_app;
GRANT USAGE, SELECT ON SEQUENCE conversations_id_seq TO nordabiz_app;
GRANT USAGE, SELECT ON SEQUENCE conv_messages_id_seq TO nordabiz_app;
GRANT USAGE, SELECT ON SEQUENCE message_reactions_id_seq TO nordabiz_app;
GRANT USAGE, SELECT ON SEQUENCE message_pins_id_seq TO nordabiz_app;

COMMIT;
