-- name: UpsertTrack :one
-- file_path is the canonical identity for library scan; mbid is secondary.
INSERT INTO tracks (
    title, album_id, artist_id, track_number, disc_number,
    duration_ms, file_path, file_size, file_format, bitrate, mbid, genre
) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)
ON CONFLICT (file_path) DO UPDATE SET
    title = EXCLUDED.title,
    album_id = EXCLUDED.album_id,
    artist_id = EXCLUDED.artist_id,
    track_number = EXCLUDED.track_number,
    disc_number = EXCLUDED.disc_number,
    duration_ms = EXCLUDED.duration_ms,
    file_size = EXCLUDED.file_size,
    file_format = EXCLUDED.file_format,
    bitrate = EXCLUDED.bitrate,
    mbid = EXCLUDED.mbid,
    genre = EXCLUDED.genre,
    updated_at = now()
RETURNING *;

-- name: GetTrackByID :one
SELECT * FROM tracks WHERE id = $1;

-- name: GetTrackByPath :one
SELECT * FROM tracks WHERE file_path = $1;

-- name: ListTracksByAlbum :many
SELECT * FROM tracks WHERE album_id = $1 ORDER BY disc_number NULLS LAST, track_number NULLS LAST;

-- name: CountTracksByAlbum :one
SELECT count(*) FROM tracks WHERE album_id = $1;

-- name: SearchTracks :many
SELECT * FROM tracks
WHERE title ILIKE '%' || $1 || '%'
ORDER BY title
LIMIT $2 OFFSET $3;

-- name: CountTracksMatching :one
SELECT COUNT(*) FROM tracks WHERE title ILIKE '%' || $1::text || '%';
