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

package dbq

import (
	"context"

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

const approveLidarrRequest = `-- name: ApproveLidarrRequest :one
UPDATE lidarr_requests
   SET status                = 'approved',
       quality_profile_id    = $2,
       root_folder_path      = $3,
       decided_at            = now(),
       decided_by            = $4,
       updated_at            = now()
 WHERE id = $1 AND status = 'pending'
 RETURNING id, user_id, status, kind, lidarr_artist_mbid, lidarr_album_mbid, lidarr_track_mbid, artist_name, album_title, track_title, quality_profile_id, root_folder_path, decided_at, decided_by, notes, completed_at, matched_track_id, matched_album_id, matched_artist_id, requested_at, updated_at, lidarr_add_confirmed_at
`

type ApproveLidarrRequestParams struct {
	ID               pgtype.UUID
	QualityProfileID *int32
	RootFolderPath   *string
	DecidedBy        pgtype.UUID
}

func (q *Queries) ApproveLidarrRequest(ctx context.Context, arg ApproveLidarrRequestParams) (LidarrRequest, error) {
	row := q.db.QueryRow(ctx, approveLidarrRequest,
		arg.ID,
		arg.QualityProfileID,
		arg.RootFolderPath,
		arg.DecidedBy,
	)
	var i LidarrRequest
	err := row.Scan(
		&i.ID,
		&i.UserID,
		&i.Status,
		&i.Kind,
		&i.LidarrArtistMbid,
		&i.LidarrAlbumMbid,
		&i.LidarrTrackMbid,
		&i.ArtistName,
		&i.AlbumTitle,
		&i.TrackTitle,
		&i.QualityProfileID,
		&i.RootFolderPath,
		&i.DecidedAt,
		&i.DecidedBy,
		&i.Notes,
		&i.CompletedAt,
		&i.MatchedTrackID,
		&i.MatchedAlbumID,
		&i.MatchedArtistID,
		&i.RequestedAt,
		&i.UpdatedAt,
		&i.LidarrAddConfirmedAt,
	)
	return i, err
}

const cancelLidarrRequest = `-- name: CancelLidarrRequest :one
UPDATE lidarr_requests
   SET status     = 'rejected',
       notes      = 'cancelled by user',
       decided_at = now(),
       decided_by = $2,
       updated_at = now()
 WHERE id = $1 AND user_id = $2 AND status = 'pending'
 RETURNING id, user_id, status, kind, lidarr_artist_mbid, lidarr_album_mbid, lidarr_track_mbid, artist_name, album_title, track_title, quality_profile_id, root_folder_path, decided_at, decided_by, notes, completed_at, matched_track_id, matched_album_id, matched_artist_id, requested_at, updated_at, lidarr_add_confirmed_at
`

type CancelLidarrRequestParams struct {
	ID        pgtype.UUID
	DecidedBy pgtype.UUID
}

// $2 serves as both the ownership guard (user_id = $2) and the
// decided_by audit field. The generated parameter struct names it
// DecidedBy — callers must pass the cancelling user's UUID, and
// a wrong UUID will silently no-op (zero rows updated) rather than
// erroring at the SQL layer.
func (q *Queries) CancelLidarrRequest(ctx context.Context, arg CancelLidarrRequestParams) (LidarrRequest, error) {
	row := q.db.QueryRow(ctx, cancelLidarrRequest, arg.ID, arg.DecidedBy)
	var i LidarrRequest
	err := row.Scan(
		&i.ID,
		&i.UserID,
		&i.Status,
		&i.Kind,
		&i.LidarrArtistMbid,
		&i.LidarrAlbumMbid,
		&i.LidarrTrackMbid,
		&i.ArtistName,
		&i.AlbumTitle,
		&i.TrackTitle,
		&i.QualityProfileID,
		&i.RootFolderPath,
		&i.DecidedAt,
		&i.DecidedBy,
		&i.Notes,
		&i.CompletedAt,
		&i.MatchedTrackID,
		&i.MatchedAlbumID,
		&i.MatchedArtistID,
		&i.RequestedAt,
		&i.UpdatedAt,
		&i.LidarrAddConfirmedAt,
	)
	return i, err
}

const completeLidarrRequest = `-- name: CompleteLidarrRequest :one
UPDATE lidarr_requests
   SET status            = 'completed',
       matched_track_id  = $2,
       matched_album_id  = $3,
       matched_artist_id = $4,
       completed_at      = now(),
       updated_at        = now()
 WHERE id = $1 AND status = 'approved'
 RETURNING id, user_id, status, kind, lidarr_artist_mbid, lidarr_album_mbid, lidarr_track_mbid, artist_name, album_title, track_title, quality_profile_id, root_folder_path, decided_at, decided_by, notes, completed_at, matched_track_id, matched_album_id, matched_artist_id, requested_at, updated_at, lidarr_add_confirmed_at
`

type CompleteLidarrRequestParams struct {
	ID              pgtype.UUID
	MatchedTrackID  pgtype.UUID
	MatchedAlbumID  pgtype.UUID
	MatchedArtistID pgtype.UUID
}

// Reconciler transitions an approved request to completed when its
// target track/album/artist has appeared in the library. Callers
// should set ONLY the matched_*_id corresponding to the request's
// kind and pass pgtype.UUID{} (Valid: false) for the others —
// per-kind one-of-three is the contract, NULL for the others
// preserves auditability if the matched row is later evicted.
func (q *Queries) CompleteLidarrRequest(ctx context.Context, arg CompleteLidarrRequestParams) (LidarrRequest, error) {
	row := q.db.QueryRow(ctx, completeLidarrRequest,
		arg.ID,
		arg.MatchedTrackID,
		arg.MatchedAlbumID,
		arg.MatchedArtistID,
	)
	var i LidarrRequest
	err := row.Scan(
		&i.ID,
		&i.UserID,
		&i.Status,
		&i.Kind,
		&i.LidarrArtistMbid,
		&i.LidarrAlbumMbid,
		&i.LidarrTrackMbid,
		&i.ArtistName,
		&i.AlbumTitle,
		&i.TrackTitle,
		&i.QualityProfileID,
		&i.RootFolderPath,
		&i.DecidedAt,
		&i.DecidedBy,
		&i.Notes,
		&i.CompletedAt,
		&i.MatchedTrackID,
		&i.MatchedAlbumID,
		&i.MatchedArtistID,
		&i.RequestedAt,
		&i.UpdatedAt,
		&i.LidarrAddConfirmedAt,
	)
	return i, err
}

const createLidarrRequest = `-- name: CreateLidarrRequest :one
INSERT INTO lidarr_requests (
    user_id, kind,
    lidarr_artist_mbid, lidarr_album_mbid, lidarr_track_mbid,
    artist_name, album_title, track_title
) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
RETURNING id, user_id, status, kind, lidarr_artist_mbid, lidarr_album_mbid, lidarr_track_mbid, artist_name, album_title, track_title, quality_profile_id, root_folder_path, decided_at, decided_by, notes, completed_at, matched_track_id, matched_album_id, matched_artist_id, requested_at, updated_at, lidarr_add_confirmed_at
`

type CreateLidarrRequestParams struct {
	UserID           pgtype.UUID
	Kind             LidarrRequestKind
	LidarrArtistMbid string
	LidarrAlbumMbid  *string
	LidarrTrackMbid  *string
	ArtistName       string
	AlbumTitle       *string
	TrackTitle       *string
}

func (q *Queries) CreateLidarrRequest(ctx context.Context, arg CreateLidarrRequestParams) (LidarrRequest, error) {
	row := q.db.QueryRow(ctx, createLidarrRequest,
		arg.UserID,
		arg.Kind,
		arg.LidarrArtistMbid,
		arg.LidarrAlbumMbid,
		arg.LidarrTrackMbid,
		arg.ArtistName,
		arg.AlbumTitle,
		arg.TrackTitle,
	)
	var i LidarrRequest
	err := row.Scan(
		&i.ID,
		&i.UserID,
		&i.Status,
		&i.Kind,
		&i.LidarrArtistMbid,
		&i.LidarrAlbumMbid,
		&i.LidarrTrackMbid,
		&i.ArtistName,
		&i.AlbumTitle,
		&i.TrackTitle,
		&i.QualityProfileID,
		&i.RootFolderPath,
		&i.DecidedAt,
		&i.DecidedBy,
		&i.Notes,
		&i.CompletedAt,
		&i.MatchedTrackID,
		&i.MatchedAlbumID,
		&i.MatchedArtistID,
		&i.RequestedAt,
		&i.UpdatedAt,
		&i.LidarrAddConfirmedAt,
	)
	return i, err
}

const getLidarrRequestByID = `-- name: GetLidarrRequestByID :one
SELECT id, user_id, status, kind, lidarr_artist_mbid, lidarr_album_mbid, lidarr_track_mbid, artist_name, album_title, track_title, quality_profile_id, root_folder_path, decided_at, decided_by, notes, completed_at, matched_track_id, matched_album_id, matched_artist_id, requested_at, updated_at, lidarr_add_confirmed_at FROM lidarr_requests WHERE id = $1
`

func (q *Queries) GetLidarrRequestByID(ctx context.Context, id pgtype.UUID) (LidarrRequest, error) {
	row := q.db.QueryRow(ctx, getLidarrRequestByID, id)
	var i LidarrRequest
	err := row.Scan(
		&i.ID,
		&i.UserID,
		&i.Status,
		&i.Kind,
		&i.LidarrArtistMbid,
		&i.LidarrAlbumMbid,
		&i.LidarrTrackMbid,
		&i.ArtistName,
		&i.AlbumTitle,
		&i.TrackTitle,
		&i.QualityProfileID,
		&i.RootFolderPath,
		&i.DecidedAt,
		&i.DecidedBy,
		&i.Notes,
		&i.CompletedAt,
		&i.MatchedTrackID,
		&i.MatchedAlbumID,
		&i.MatchedArtistID,
		&i.RequestedAt,
		&i.UpdatedAt,
		&i.LidarrAddConfirmedAt,
	)
	return i, err
}

const getNonTerminalRequestForMBID = `-- name: GetNonTerminalRequestForMBID :one
SELECT id, user_id, status, kind, lidarr_artist_mbid, lidarr_album_mbid, lidarr_track_mbid, artist_name, album_title, track_title, quality_profile_id, root_folder_path, decided_at, decided_by, notes, completed_at, matched_track_id, matched_album_id, matched_artist_id, requested_at, updated_at, lidarr_add_confirmed_at FROM lidarr_requests
 WHERE status IN ('pending', 'approved', 'completed')
   AND ((kind = 'artist' AND lidarr_artist_mbid = $1)
     OR (kind = 'album'  AND lidarr_album_mbid  = $1)
     OR (kind = 'track'  AND lidarr_track_mbid  = $1))
 ORDER BY requested_at ASC
 LIMIT 1
`

// Returns the oldest non-terminal (pending/approved/completed) request
// whose own-kind MBID matches @mbid, or pgx.ErrNoRows when none. Create()
// uses this to dedupe: a re-request for something already in flight
// returns the existing row instead of inserting a duplicate. MBIDs are
// globally unique per entity type, so the cross-column OR cannot
// false-match (an artist MBID never collides with an album/track MBID).
func (q *Queries) GetNonTerminalRequestForMBID(ctx context.Context, mbid string) (LidarrRequest, error) {
	row := q.db.QueryRow(ctx, getNonTerminalRequestForMBID, mbid)
	var i LidarrRequest
	err := row.Scan(
		&i.ID,
		&i.UserID,
		&i.Status,
		&i.Kind,
		&i.LidarrArtistMbid,
		&i.LidarrAlbumMbid,
		&i.LidarrTrackMbid,
		&i.ArtistName,
		&i.AlbumTitle,
		&i.TrackTitle,
		&i.QualityProfileID,
		&i.RootFolderPath,
		&i.DecidedAt,
		&i.DecidedBy,
		&i.Notes,
		&i.CompletedAt,
		&i.MatchedTrackID,
		&i.MatchedAlbumID,
		&i.MatchedArtistID,
		&i.RequestedAt,
		&i.UpdatedAt,
		&i.LidarrAddConfirmedAt,
	)
	return i, err
}

const hasNonTerminalRequestForMBID = `-- name: HasNonTerminalRequestForMBID :one
SELECT EXISTS (
    SELECT 1 FROM lidarr_requests
    WHERE status IN ('pending', 'approved', 'completed')
      AND ((kind = 'artist' AND lidarr_artist_mbid = $1)
        OR (kind = 'album'  AND lidarr_album_mbid  = $1)
        OR (kind = 'track'  AND lidarr_track_mbid  = $1))
)
`

// Returns true if any user has a pending/approved/completed request
// whose MBID matches at the given level. Used to set the `requested`
// flag on /api/lidarr/search responses. Terminal-status (rejected,
// failed) rows do not count. The same MBID parameter is checked
// against artist/album/track columns based on kind.
func (q *Queries) HasNonTerminalRequestForMBID(ctx context.Context, mbid string) (bool, error) {
	row := q.db.QueryRow(ctx, hasNonTerminalRequestForMBID, mbid)
	var exists bool
	err := row.Scan(&exists)
	return exists, err
}

const listApprovedLidarrRequestsForReconcile = `-- name: ListApprovedLidarrRequestsForReconcile :many
SELECT id, user_id, status, kind, lidarr_artist_mbid, lidarr_album_mbid, lidarr_track_mbid, artist_name, album_title, track_title, quality_profile_id, root_folder_path, decided_at, decided_by, notes, completed_at, matched_track_id, matched_album_id, matched_artist_id, requested_at, updated_at, lidarr_add_confirmed_at FROM lidarr_requests
WHERE status = 'approved'
ORDER BY decided_at ASC
LIMIT $1
`

func (q *Queries) ListApprovedLidarrRequestsForReconcile(ctx context.Context, limit int32) ([]LidarrRequest, error) {
	rows, err := q.db.Query(ctx, listApprovedLidarrRequestsForReconcile, limit)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []LidarrRequest
	for rows.Next() {
		var i LidarrRequest
		if err := rows.Scan(
			&i.ID,
			&i.UserID,
			&i.Status,
			&i.Kind,
			&i.LidarrArtistMbid,
			&i.LidarrAlbumMbid,
			&i.LidarrTrackMbid,
			&i.ArtistName,
			&i.AlbumTitle,
			&i.TrackTitle,
			&i.QualityProfileID,
			&i.RootFolderPath,
			&i.DecidedAt,
			&i.DecidedBy,
			&i.Notes,
			&i.CompletedAt,
			&i.MatchedTrackID,
			&i.MatchedAlbumID,
			&i.MatchedArtistID,
			&i.RequestedAt,
			&i.UpdatedAt,
			&i.LidarrAddConfirmedAt,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const listLidarrRequestsByStatus = `-- name: ListLidarrRequestsByStatus :many
SELECT id, user_id, status, kind, lidarr_artist_mbid, lidarr_album_mbid, lidarr_track_mbid, artist_name, album_title, track_title, quality_profile_id, root_folder_path, decided_at, decided_by, notes, completed_at, matched_track_id, matched_album_id, matched_artist_id, requested_at, updated_at, lidarr_add_confirmed_at FROM lidarr_requests
WHERE status = $1
ORDER BY requested_at DESC
LIMIT $2
`

type ListLidarrRequestsByStatusParams struct {
	Status LidarrRequestStatus
	Limit  int32
}

func (q *Queries) ListLidarrRequestsByStatus(ctx context.Context, arg ListLidarrRequestsByStatusParams) ([]LidarrRequest, error) {
	rows, err := q.db.Query(ctx, listLidarrRequestsByStatus, arg.Status, arg.Limit)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []LidarrRequest
	for rows.Next() {
		var i LidarrRequest
		if err := rows.Scan(
			&i.ID,
			&i.UserID,
			&i.Status,
			&i.Kind,
			&i.LidarrArtistMbid,
			&i.LidarrAlbumMbid,
			&i.LidarrTrackMbid,
			&i.ArtistName,
			&i.AlbumTitle,
			&i.TrackTitle,
			&i.QualityProfileID,
			&i.RootFolderPath,
			&i.DecidedAt,
			&i.DecidedBy,
			&i.Notes,
			&i.CompletedAt,
			&i.MatchedTrackID,
			&i.MatchedAlbumID,
			&i.MatchedArtistID,
			&i.RequestedAt,
			&i.UpdatedAt,
			&i.LidarrAddConfirmedAt,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const listLidarrRequestsForUser = `-- name: ListLidarrRequestsForUser :many
SELECT id, user_id, status, kind, lidarr_artist_mbid, lidarr_album_mbid, lidarr_track_mbid, artist_name, album_title, track_title, quality_profile_id, root_folder_path, decided_at, decided_by, notes, completed_at, matched_track_id, matched_album_id, matched_artist_id, requested_at, updated_at, lidarr_add_confirmed_at FROM lidarr_requests
WHERE user_id = $1
ORDER BY requested_at DESC
LIMIT $2
`

type ListLidarrRequestsForUserParams struct {
	UserID pgtype.UUID
	Limit  int32
}

func (q *Queries) ListLidarrRequestsForUser(ctx context.Context, arg ListLidarrRequestsForUserParams) ([]LidarrRequest, error) {
	rows, err := q.db.Query(ctx, listLidarrRequestsForUser, arg.UserID, arg.Limit)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []LidarrRequest
	for rows.Next() {
		var i LidarrRequest
		if err := rows.Scan(
			&i.ID,
			&i.UserID,
			&i.Status,
			&i.Kind,
			&i.LidarrArtistMbid,
			&i.LidarrAlbumMbid,
			&i.LidarrTrackMbid,
			&i.ArtistName,
			&i.AlbumTitle,
			&i.TrackTitle,
			&i.QualityProfileID,
			&i.RootFolderPath,
			&i.DecidedAt,
			&i.DecidedBy,
			&i.Notes,
			&i.CompletedAt,
			&i.MatchedTrackID,
			&i.MatchedAlbumID,
			&i.MatchedArtistID,
			&i.RequestedAt,
			&i.UpdatedAt,
			&i.LidarrAddConfirmedAt,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const markLidarrRequestAddConfirmed = `-- name: MarkLidarrRequestAddConfirmed :exec
UPDATE lidarr_requests
   SET lidarr_add_confirmed_at = now(),
       updated_at              = now()
 WHERE id = $1
   AND status = 'approved'
   AND lidarr_add_confirmed_at IS NULL
`

// Idempotently records that Lidarr accepted the add for an approved
// request. The lidarr_add_confirmed_at IS NULL guard makes a redundant
// reconciler retry a no-op rather than bumping updated_at every tick.
func (q *Queries) MarkLidarrRequestAddConfirmed(ctx context.Context, id pgtype.UUID) error {
	_, err := q.db.Exec(ctx, markLidarrRequestAddConfirmed, id)
	return err
}

const rejectLidarrRequest = `-- name: RejectLidarrRequest :one
UPDATE lidarr_requests
   SET status     = 'rejected',
       notes      = $2,
       decided_at = now(),
       decided_by = $3,
       updated_at = now()
 WHERE id = $1 AND status = 'pending'
 RETURNING id, user_id, status, kind, lidarr_artist_mbid, lidarr_album_mbid, lidarr_track_mbid, artist_name, album_title, track_title, quality_profile_id, root_folder_path, decided_at, decided_by, notes, completed_at, matched_track_id, matched_album_id, matched_artist_id, requested_at, updated_at, lidarr_add_confirmed_at
`

type RejectLidarrRequestParams struct {
	ID        pgtype.UUID
	Notes     *string
	DecidedBy pgtype.UUID
}

func (q *Queries) RejectLidarrRequest(ctx context.Context, arg RejectLidarrRequestParams) (LidarrRequest, error) {
	row := q.db.QueryRow(ctx, rejectLidarrRequest, arg.ID, arg.Notes, arg.DecidedBy)
	var i LidarrRequest
	err := row.Scan(
		&i.ID,
		&i.UserID,
		&i.Status,
		&i.Kind,
		&i.LidarrArtistMbid,
		&i.LidarrAlbumMbid,
		&i.LidarrTrackMbid,
		&i.ArtistName,
		&i.AlbumTitle,
		&i.TrackTitle,
		&i.QualityProfileID,
		&i.RootFolderPath,
		&i.DecidedAt,
		&i.DecidedBy,
		&i.Notes,
		&i.CompletedAt,
		&i.MatchedTrackID,
		&i.MatchedAlbumID,
		&i.MatchedArtistID,
		&i.RequestedAt,
		&i.UpdatedAt,
		&i.LidarrAddConfirmedAt,
	)
	return i, err
}
