-- name: OpenDM :execrows
INSERT OR IGNORE INTO dm_open_state (user_id, channel_id) VALUES (?, ?);

-- name: CloseDM :exec
DELETE FROM dm_open_state WHERE user_id = ? AND channel_id = ?;

-- name: IsDMParticipant :one
SELECT user_id FROM dm_participants WHERE user_id = ? AND channel_id = ?;

-- name: GetDMParticipantIDs :many
SELECT user_id FROM dm_participants WHERE channel_id = ?;

-- name: CountDMParticipants :one
SELECT COUNT(*) FROM dm_participants WHERE channel_id = ?;

-- name: IsGroupDM :one
SELECT is_group FROM channels WHERE id = ? AND type = 'dm';

-- name: RemoveDMParticipant :exec
DELETE FROM dm_participants WHERE channel_id = ? AND user_id = ?;

-- name: SetDMChannelName :exec
UPDATE channels SET name = ? WHERE id = ? AND type = 'dm';

-- name: GetDMParticipants :many
SELECT
    u.id                                      AS id,
    u.username                                AS username,
    COALESCE(u.display_name, '')              AS display_name,
    COALESCE(u.avatar, '')                    AS avatar,
    u.status                                  AS status
FROM dm_participants dp
JOIN users u ON u.id = dp.user_id
WHERE dp.channel_id = ?
ORDER BY u.id ASC;

-- name: GetUserDMChannelIDs :many
SELECT channel_id FROM dm_open_state WHERE user_id = ?;

-- A DM row carries no recipient any more: dm_participants holds N users, so
-- "the other one" is only well defined for a two-person DM. The participant
-- set comes from GetDMParticipantsForUser below, one extra query for the whole
-- list rather than one per channel, and the Go layer stitches them together.
-- name: GetUserDMChannels :many
SELECT
    c.id                                          AS channel_id,
    c.name                                        AS name,
    c.is_group                                    AS is_group,
    lm.id                                         AS last_message_id,
    COALESCE(lm.content, '')                      AS last_message,
    COALESCE(lm.timestamp, '')                    AS last_message_at,
    (SELECT COUNT(*) FROM messages mu
      WHERE mu.channel_id = c.id AND mu.deleted = 0
        AND mu.id > COALESCE((SELECT rs.last_message_id FROM read_states rs
                               WHERE rs.channel_id = c.id AND rs.user_id = dos.user_id), 0)
    ) AS unread_count
FROM dm_open_state dos
JOIN channels c          ON c.id = dos.channel_id AND c.type = 'dm'
LEFT JOIN messages lm    ON lm.id = (
    SELECT MAX(id) FROM messages WHERE channel_id = c.id AND deleted = 0
)
WHERE dos.user_id = ?
ORDER BY COALESCE(lm.timestamp, dos.opened_at) DESC;

-- Every participant of every DM the user has open, in one pass. Includes the
-- user themselves so a caller can tell "group of three" from "group of three
-- others"; the Go layer filters when it needs the others.
-- name: GetDMParticipantsForUser :many
SELECT
    dp.channel_id                                 AS channel_id,
    u.id                                          AS id,
    u.username                                    AS username,
    COALESCE(u.display_name, '')                  AS display_name,
    COALESCE(u.avatar, '')                        AS avatar,
    u.status                                      AS status
FROM dm_open_state dos
JOIN dm_participants dp ON dp.channel_id = dos.channel_id
JOIN users u            ON u.id = dp.user_id
WHERE dos.user_id = ?
ORDER BY dp.channel_id ASC, u.id ASC;
