// What the library overview mosaic is made of, and in what order.
//
// Pure: takes the libraries, returns the tiles to draw. No DOM, no stores — so
// the ordering and the de-duplication rules below are unit-testable rather than
// buried in markup.
//
// Note what is NOT decided here: which favourites category a library belongs to.
// That is Jellyfin vocabulary and arrives on the library itself as
// `favoritesScope` (Rust: `SearchScope::for_collection_type`). This file only
// decides what to *call* it and where to put it.
//
// TRACES: UR-075, UR-067 | DR-174, DR-175 | UT-167

import type { Library } from "$lib/api/types";
import {
  FAVORITE_SCOPE_LABELS,
  asFavoritesScope,
  favoritesRouteUrl,
  type FavoritesScope,
} from "$lib/utils/favoritesView";

/** Artwork shapes, as the source images generally arrive. A measured image
 *  overrides these (see MosaicGrid); they are the shape assumed until then. */
const SQUARE = 1;
const WIDE = 16 / 9;

export type LibraryMosaicEntry = {
  /** Stable identity for the layout and for `{#each}` keying. */
  key: string;
  /** Assumed width / height until the artwork reports its own. */
  ratio: number;
  label: string;
} & (
  | { kind: "library"; library: Library }
  | { kind: "favorites"; scope: FavoritesScope; href: string }
);

/**
 * A music library's artwork is a square cover; everything else is a wide
 * backdrop. Presentation, not taxonomy: this is the shape of a picture, and it
 * is a starting guess that the decoded image is allowed to overrule.
 */
export function assumedLibraryRatio(lib: Library): number {
  return lib.collectionType === "music" ? SQUARE : WIDE;
}

/**
 * The mosaic's tiles, in order: the cross-library favourites entry first, then
 * each library followed by its own favourites tile.
 *
 * A category's favourites tile appears **once**, after the first library of that
 * category — two movie libraries ("Films", "Kids") share one favourites list, so
 * a tile each would be two tiles going to the same place.
 */
export function buildLibraryMosaic(libraries: Library[]): LibraryMosaicEntry[] {
  const entries: LibraryMosaicEntry[] = [
    {
      key: "favorites:all",
      kind: "favorites",
      scope: "all",
      href: favoritesRouteUrl("all"),
      ratio: WIDE,
      label: "Favourites",
    },
  ];

  const seenScopes = new Set<FavoritesScope>(["all"]);

  for (const lib of libraries) {
    const ratio = assumedLibraryRatio(lib);
    entries.push({ key: `library:${lib.id}`, kind: "library", library: lib, ratio, label: lib.name });

    const scope = asFavoritesScope(lib.favoritesScope);
    if (!scope || seenScopes.has(scope)) continue;
    seenScopes.add(scope);
    entries.push({
      key: `favorites:${scope}`,
      kind: "favorites",
      scope,
      href: favoritesRouteUrl(scope),
      ratio,
      label: `Favourite ${FAVORITE_SCOPE_LABELS[scope]}`,
    });
  }

  return entries;
}
