package recommendation

import (
	"sort"
	"time"

	"git.fabledsword.com/bvandeusen/minstrel/internal/db/dbq"
)

// Candidate pairs a track with the inputs needed to score it.
type Candidate struct {
	Track  dbq.Track
	Inputs ScoringInputs
}

// Shuffle scores each candidate, sorts descending by score, and returns
// the top `limit` candidates. limit <= 0 returns nil; nil input returns
// nil. Pure — no IO, no global state beyond the rng callback.
func Shuffle(
	candidates []Candidate,
	weights ScoringWeights,
	now time.Time,
	rng func() float64,
	limit int,
) []Candidate {
	if len(candidates) == 0 || limit <= 0 {
		return nil
	}
	scored := make([]struct {
		c     Candidate
		score float64
	}, len(candidates))
	for i, c := range candidates {
		scored[i].c = c
		scored[i].score = Score(c.Inputs, weights, now, rng)
	}
	sort.Slice(scored, func(i, j int) bool {
		return scored[i].score > scored[j].score
	})
	if limit > len(scored) {
		limit = len(scored)
	}
	out := make([]Candidate, limit)
	for i := 0; i < limit; i++ {
		out[i] = scored[i].c
	}
	return out
}
