-- Step 1: Create room_access table (private room explicit access grants)
CREATE TABLE IF NOT EXISTS room_access (
    room UUID NOT NULL,
    "user" UUID NOT NULL,
    granted_by UUID NOT NULL,
    granted_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    PRIMARY KEY (room, "user")
);

CREATE INDEX IF NOT EXISTS idx_room_access_user ON room_access ("user");

-- Step 2: Create room_user_state table (per-user per-room state)
CREATE TABLE IF NOT EXISTS room_user_state (
    room UUID NOT NULL,
    "user" UUID NOT NULL,
    last_read_seq BIGINT,
    do_not_disturb BOOLEAN NOT NULL DEFAULT FALSE,
    dnd_start_hour SMALLINT,
    dnd_end_hour SMALLINT,
    joined_at TIMESTAMPTZ,
    PRIMARY KEY (room, "user")
);

CREATE INDEX IF NOT EXISTS idx_room_user_state_user ON room_user_state ("user");

-- Step 3: Migrate data from room_member to room_access and room_user_state

-- For private rooms (public=false), migrate member rows → room_access
INSERT INTO room_access (room, "user", granted_by, granted_at)
SELECT rm.room, rm."user", rm."user", COALESCE(rm.joined_at, NOW())
FROM room_member rm
JOIN room r ON r.id = rm.room
WHERE r.public = false;

-- Migrate all room_member rows → room_user_state (state is always useful)
INSERT INTO room_user_state (room, "user", last_read_seq, do_not_disturb, dnd_start_hour, dnd_end_hour, joined_at)
SELECT rm.room, rm."user", rm.last_read_seq, rm.do_not_disturb, rm.dnd_start_hour, rm.dnd_end_hour, rm.joined_at
FROM room_member rm
ON CONFLICT (room, "user") DO NOTHING;

-- Step 4: Drop room_member table
DROP TABLE IF EXISTS room_member;

-- Step 5: Convert sender_type enum values in room_message
-- Old values: member, admin, owner, guest → new value: user
-- AI/system/tool/webhook stay the same (webhook is new)
UPDATE room_message SET sender_type = 'user'
WHERE sender_type IN ('member', 'admin', 'owner', 'guest');