// Hero banner mix builder, shared by the movies/TV/music landing stores.
//
// The hero used to show the first N items of fixed pools (continue watching,
// recently played, latest), which made it identical on every visit. Instead we
// sample a couple of items at random from each pool — pools are ordered most
// personal first — and shuffle the rotation, so the banner is a fresh mix each
// time while still leading with something personal.
// TRACES: UR-034 | DR-038
import type { MediaItem } from "$lib/api/types";

/** Fisher-Yates shuffle; returns a new array, input is untouched. */
export function shuffle<T>(items: T[]): T[] {
  const result = [...items];
  for (let i = result.length - 1; i > 0; i--) {
    const j = Math.floor(Math.random() * (i + 1));
    [result[i], result[j]] = [result[j], result[i]];
  }
  return result;
}

/**
 * Build a varied hero rotation from ordered pools (most personal first).
 *
 * Takes up to `perPool` random items from each pool, de-duplicated by id and
 * filtered to items with usable artwork. The first pick from the first
 * non-empty pool leads the rotation (so a resumable/recent item greets the
 * user), the rest are shuffled. If that yields fewer than `count` items, the
 * remainder is backfilled from whatever is left across all pools.
 */
export function buildHeroMix(
  pools: MediaItem[][],
  hasArt: (item: MediaItem) => boolean,
  count = 6,
  perPool = 2
): MediaItem[] {
  const seen = new Set<string>();
  const usable = pools.map(pool =>
    pool.filter(item => {
      if (!hasArt(item) || seen.has(item.id)) return false;
      seen.add(item.id);
      return true;
    })
  );

  const picked = new Set<string>();
  const picks: MediaItem[] = [];
  for (const pool of usable) {
    for (const item of shuffle(pool).slice(0, perPool)) {
      picked.add(item.id);
      picks.push(item);
    }
  }

  if (picks.length === 0) return [];

  const [leader, ...rest] = picks;
  const leftovers = shuffle(usable.flat().filter(item => !picked.has(item.id)));
  return [leader, ...shuffle(rest), ...leftovers].slice(0, count);
}
