-- name: UpsertQuarantine :one
-- Insert a new quarantine row, or update reason/notes if the user has
-- already flagged this track.
INSERT INTO lidarr_quarantine (user_id, track_id, reason, notes)
VALUES ($1, $2, $3, $4)
ON CONFLICT (user_id, track_id) DO UPDATE SET
    reason     = EXCLUDED.reason,
    notes      = EXCLUDED.notes,
    created_at = now()
RETURNING user_id, track_id, reason, notes, created_at;

-- name: DeleteQuarantine :one
-- Removes the caller's row. Returns the deleted row so the handler can
-- distinguish "no row existed" (zero rows -> ErrNoRows) from success.
DELETE FROM lidarr_quarantine
 WHERE user_id = $1 AND track_id = $2
 RETURNING user_id, track_id, reason, notes, created_at;

-- name: ListQuarantineForUser :many
-- Caller's own quarantines plus just the joined fields the SPA's
-- /library/hidden actually renders. Embedding the full tracks/albums/artists
-- structs would drag ~28 columns of file_path / sort_* / mbid / etc. that
-- the row card never uses.
SELECT
    sqlc.embed(q),
    t.id          AS track_id_join,
    t.title       AS track_title,
    t.duration_ms AS track_duration_ms,
    al.id         AS album_id,
    al.title      AS album_title,
    al.cover_art_path AS album_cover_art_path,
    ar.id         AS artist_id,
    ar.name       AS artist_name
FROM lidarr_quarantine q
JOIN tracks  t  ON t.id  = q.track_id
JOIN albums  al ON al.id = t.album_id
JOIN artists ar ON ar.id = t.artist_id
WHERE q.user_id = $1
ORDER BY q.created_at DESC;

-- name: ListAdminQuarantineQueue :many
-- Aggregated admin queue. One row per track. The handler post-processes
-- the rows it gets from this query plus a per-track ListQuarantineReports
-- call to materialize reason_counts and the per-user reports list.
SELECT
    t.id              AS track_id,
    t.title           AS track_title,
    ar.name           AS artist_name,
    al.title          AS album_title,
    al.id             AS album_id,
    al.mbid           AS lidarr_album_mbid,
    count(q.user_id)::int             AS report_count,
    max(q.created_at)::timestamptz    AS latest_at
FROM lidarr_quarantine q
JOIN tracks  t  ON t.id  = q.track_id
JOIN albums  al ON al.id = t.album_id
JOIN artists ar ON ar.id = t.artist_id
GROUP BY t.id, ar.name, al.title, al.id, al.mbid
ORDER BY max(q.created_at) DESC;

-- name: ListQuarantineReportsForTrack :many
-- Per-user reports for a single track. Returned by ListAdminQuarantineQueue
-- post-processing and exposed expandable in the SPA admin queue rows.
SELECT
    q.user_id,
    u.username,
    q.reason,
    q.notes,
    q.created_at
FROM lidarr_quarantine q
JOIN users u ON u.id = q.user_id
WHERE q.track_id = $1
ORDER BY q.created_at DESC;

-- name: DeleteQuarantineForTrack :exec
-- Clears all per-user rows for a given track. Used by Resolve and the
-- two delete actions. Caller writes the audit row separately before
-- this fires (so we can capture the affected_users count).
DELETE FROM lidarr_quarantine WHERE track_id = $1;

-- name: CountQuarantineForTrack :one
-- Reads affected_users for the audit row before the delete fires.
SELECT count(*)::int FROM lidarr_quarantine WHERE track_id = $1;

-- name: WriteQuarantineAction :one
-- Audit row for an admin destructive action.
INSERT INTO lidarr_quarantine_actions (
    track_id, track_title, artist_name, album_title,
    action, admin_id, lidarr_album_mbid, affected_users
) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
RETURNING *;

-- name: ListQuarantineActions :many
SELECT * FROM lidarr_quarantine_actions
ORDER BY created_at DESC
LIMIT $1;
