package api

import (
	"context"
	"errors"
	"net/http"

	"github.com/go-chi/chi/v5"
	"github.com/jackc/pgx/v5"
	"github.com/jackc/pgx/v5/pgtype"

	"git.fabledsword.com/bvandeusen/minstrel/internal/apierror"
)

// resolveByID parses paramKey as a UUID, fetches the row via fetch, and
// returns the row. On invalid UUID, returns BadRequest. On pgx.ErrNoRows,
// returns NotFound with code "<notFoundCode>_not_found". On other fetch
// errors, returns Internal (caller is responsible for logging if needed).
//
// Generic over T because dbq getters return concrete dbq row types.
func resolveByID[T any](
	r *http.Request,
	paramKey string,
	fetch func(context.Context, pgtype.UUID) (T, error),
	notFoundCode string,
) (T, *apierror.Error) {
	var zero T
	raw := chi.URLParam(r, paramKey)
	id, ok := parseUUID(raw)
	if !ok {
		return zero, apierror.BadRequest("bad_request", "invalid "+paramKey+" id")
	}
	row, err := fetch(r.Context(), id)
	if err != nil {
		if errors.Is(err, pgx.ErrNoRows) {
			return zero, apierror.NotFound(notFoundCode)
		}
		return zero, apierror.Internal(err)
	}
	return row, nil
}
