// Code generated by sqlc. DO NOT EDIT.
// versions:
//   sqlc v1.31.1
// source: covers.sql

package dbq

import (
	"context"

	"github.com/jackc/pgx/v5/pgtype"
)

const clearAlbumCover = `-- name: ClearAlbumCover :exec
UPDATE albums
   SET cover_art_path   = NULL,
       cover_art_source = NULL
 WHERE id = $1
`

// Used by the admin retry endpoint to wipe state before re-running the
// enricher. Sets both fields to NULL.
func (q *Queries) ClearAlbumCover(ctx context.Context, id pgtype.UUID) error {
	_, err := q.db.Exec(ctx, clearAlbumCover, id)
	return err
}

const clearAlbumCoverNone = `-- name: ClearAlbumCoverNone :exec
UPDATE albums
   SET cover_art_source = NULL
 WHERE id = $1 AND cover_art_source = 'none'
`

// M7 #380: when MBID backfill heals an album, clear its 'none' cover_art_source
// back to NULL so the enricher's next batch retries the MBCAA fetch.
// Idempotent — only updates rows currently stamped 'none'.
func (q *Queries) ClearAlbumCoverNone(ctx context.Context, id pgtype.UUID) error {
	_, err := q.db.Exec(ctx, clearAlbumCoverNone, id)
	return err
}

const countAlbumCoverSources = `-- name: CountAlbumCoverSources :one
SELECT
    COUNT(*) FILTER (WHERE cover_art_source IS NULL)     ::bigint AS untried,
    COUNT(*) FILTER (WHERE cover_art_source = 'sidecar') ::bigint AS sidecar,
    COUNT(*) FILTER (WHERE cover_art_source = 'embedded')::bigint AS embedded,
    COUNT(*) FILTER (WHERE cover_art_source = 'mbcaa')   ::bigint AS mbcaa,
    COUNT(*) FILTER (WHERE cover_art_source = 'none')    ::bigint AS none
  FROM albums
`

type CountAlbumCoverSourcesRow struct {
	Untried  int64
	Sidecar  int64
	Embedded int64
	Mbcaa    int64
	None     int64
}

// Diagnostic for the admin overview: counts by source, including NULL.
// Returns one row with named tallies.
func (q *Queries) CountAlbumCoverSources(ctx context.Context) (CountAlbumCoverSourcesRow, error) {
	row := q.db.QueryRow(ctx, countAlbumCoverSources)
	var i CountAlbumCoverSourcesRow
	err := row.Scan(
		&i.Untried,
		&i.Sidecar,
		&i.Embedded,
		&i.Mbcaa,
		&i.None,
	)
	return i, err
}

const getAlbumWithFirstTrackPath = `-- name: GetAlbumWithFirstTrackPath :one
SELECT a.id, a.mbid, a.title, a.cover_art_path, a.cover_art_source,
       ar.name AS artist_name,
       t.file_path AS track_file_path
  FROM albums a
  JOIN artists ar ON ar.id = a.artist_id
  LEFT JOIN tracks t ON t.album_id = a.id
 WHERE a.id = $1
 ORDER BY t.disc_number NULLS LAST, t.track_number NULLS LAST, t.id
 LIMIT 1
`

type GetAlbumWithFirstTrackPathRow struct {
	ID             pgtype.UUID
	Mbid           *string
	Title          string
	CoverArtPath   *string
	CoverArtSource *string
	ArtistName     string
	TrackFilePath  *string
}

// Returns the album row, the artist's name (used by name-based art
// providers like Deezer/Last.fm), and one of its track file paths
// (used to derive the album directory for sidecar writes). Pick
// lowest position track for determinism.
func (q *Queries) GetAlbumWithFirstTrackPath(ctx context.Context, id pgtype.UUID) (GetAlbumWithFirstTrackPathRow, error) {
	row := q.db.QueryRow(ctx, getAlbumWithFirstTrackPath, id)
	var i GetAlbumWithFirstTrackPathRow
	err := row.Scan(
		&i.ID,
		&i.Mbid,
		&i.Title,
		&i.CoverArtPath,
		&i.CoverArtSource,
		&i.ArtistName,
		&i.TrackFilePath,
	)
	return i, err
}

const listAlbumsMissingCover = `-- name: ListAlbumsMissingCover :many

SELECT a.id
  FROM albums a
 WHERE a.cover_art_source IS NULL
    OR (a.cover_art_source = 'none' AND a.cover_art_sources_version != $1)
 ORDER BY a.created_at
 LIMIT $2
`

type ListAlbumsMissingCoverParams struct {
	CoverArtSourcesVersion int32
	Limit                  int32
}

// M7 #353: album cover enrichment queries.
// M7 cover-sources: returns rows the enricher should attempt. Eligible:
// cover_art_source IS NULL (never tried), OR cover_art_source = 'none'
// AND cover_art_sources_version != current (settled under an older
// source set; recheck against the current chain). LIMIT supplied by
// caller for batching.
func (q *Queries) ListAlbumsMissingCover(ctx context.Context, arg ListAlbumsMissingCoverParams) ([]pgtype.UUID, error) {
	rows, err := q.db.Query(ctx, listAlbumsMissingCover, arg.CoverArtSourcesVersion, arg.Limit)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []pgtype.UUID
	for rows.Next() {
		var id pgtype.UUID
		if err := rows.Scan(&id); err != nil {
			return nil, err
		}
		items = append(items, id)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const listAlbumsRetryMissing = `-- name: ListAlbumsRetryMissing :many
SELECT a.id, a.mbid, a.title, a.artist_id
  FROM albums a
 WHERE a.cover_art_source IS NULL OR a.cover_art_source = 'none'
 ORDER BY a.created_at ASC
 LIMIT $1
`

type ListAlbumsRetryMissingRow struct {
	ID       pgtype.UUID
	Mbid     *string
	Title    string
	ArtistID pgtype.UUID
}

// Bulk-retry candidates: NULL (never tried) plus 'none' (tried, failed).
// Used by the admin "refetch missing covers" endpoint. LIMIT supplied.
func (q *Queries) ListAlbumsRetryMissing(ctx context.Context, limit int32) ([]ListAlbumsRetryMissingRow, error) {
	rows, err := q.db.Query(ctx, listAlbumsRetryMissing, limit)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []ListAlbumsRetryMissingRow
	for rows.Next() {
		var i ListAlbumsRetryMissingRow
		if err := rows.Scan(
			&i.ID,
			&i.Mbid,
			&i.Title,
			&i.ArtistID,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const setAlbumCover = `-- name: SetAlbumCover :exec
UPDATE albums
   SET cover_art_path   = NULLIF($2::text, ''),
       cover_art_source = $3
 WHERE id = $1
`

type SetAlbumCoverParams struct {
	ID             pgtype.UUID
	Column2        string
	CoverArtSource *string
}

// Persist enrichment result. Pass cover_art_path = ” to clear (turns into NULL).
func (q *Queries) SetAlbumCover(ctx context.Context, arg SetAlbumCoverParams) error {
	_, err := q.db.Exec(ctx, setAlbumCover, arg.ID, arg.Column2, arg.CoverArtSource)
	return err
}
