import { db, recipePhotos, recipeBatchDishes, favorites, inArray, eq, and } from "@epicure/db";

export type CardExtras = {
  photos: { storageKey: string; isCover: boolean }[];
  dishCount: number;
  isFavorited: boolean;
};

/** Batches the photo/batch-dish/favorite lookups a recipe grid card needs, for
 * list endpoints whose main query selects individual recipe columns rather
 * than going through `db.query.recipes.findMany`'s relational loader. */
export async function attachCardExtras<T extends { id: string }>(
  recipeList: T[],
  viewerId?: string
): Promise<(T & CardExtras)[]> {
  const ids = recipeList.map((r) => r.id);
  if (ids.length === 0) return [];

  const [photoRows, dishRows, favoritedRows] = await Promise.all([
    db
      .select({ recipeId: recipePhotos.recipeId, storageKey: recipePhotos.storageKey, isCover: recipePhotos.isCover })
      .from(recipePhotos)
      .where(inArray(recipePhotos.recipeId, ids)),
    db
      .select({ recipeId: recipeBatchDishes.recipeId })
      .from(recipeBatchDishes)
      .where(inArray(recipeBatchDishes.recipeId, ids)),
    viewerId
      ? db
          .select({ recipeId: favorites.recipeId })
          .from(favorites)
          .where(and(eq(favorites.userId, viewerId), inArray(favorites.recipeId, ids)))
      : Promise.resolve([]),
  ]);

  const photosByRecipe = new Map<string, { storageKey: string; isCover: boolean }[]>();
  for (const p of photoRows) {
    const arr = photosByRecipe.get(p.recipeId) ?? [];
    arr.push({ storageKey: p.storageKey, isCover: p.isCover });
    photosByRecipe.set(p.recipeId, arr);
  }

  const dishCountByRecipe = new Map<string, number>();
  for (const d of dishRows) dishCountByRecipe.set(d.recipeId, (dishCountByRecipe.get(d.recipeId) ?? 0) + 1);

  const favoritedSet = new Set(favoritedRows.map((f) => f.recipeId));

  return recipeList.map((r) => ({
    ...r,
    photos: photosByRecipe.get(r.id) ?? [],
    dishCount: dishCountByRecipe.get(r.id) ?? 0,
    isFavorited: favoritedSet.has(r.id),
  }));
}
