import { QueryCtx, MutationCtx } from "../_generated/server";
import type { Id, Doc } from "../_generated/dataModel";

/**
 * Recalculate product averageRating and reviewCount from approved reviews.
 * Call after review approve/delete.
 */
export async function recalculateProductRating(
  ctx: MutationCtx,
  productId: Id<"products">,
) {
  const approved = await ctx.db
    .query("reviews")
    .withIndex("by_product_approved", (q) =>
      q.eq("productId", productId).eq("isApproved", true),
    )
    .collect();

  const count = approved.length;
  const averageRating =
    count > 0
      ? approved.reduce((sum, r) => sum + r.rating, 0) / count
      : undefined;
  const reviewCount = count > 0 ? count : undefined;

  await ctx.db.patch(productId, {
    averageRating,
    reviewCount,
    updatedAt: Date.now(),
  });
}

export async function getProductWithRelations(
  ctx: QueryCtx,
  productId: Id<"products">,
) {
  const product = await ctx.db.get(productId);
  if (!product) return null;

  const [imagesRaw, variants, category] = await Promise.all([
    ctx.db
      .query("productImages")
      .withIndex("by_product", (q) => q.eq("productId", productId))
      .collect(),
    ctx.db
      .query("productVariants")
      .withIndex("by_product_and_active", (q) =>
        q.eq("productId", productId).eq("isActive", true),
      )
      .collect(),
    ctx.db.get(product.categoryId),
  ]);
  const images = imagesRaw.sort((a, b) => a.position - b.position);

  return { ...product, images, variants, category };
}

export async function enrichProducts(
  ctx: QueryCtx,
  products: Doc<"products">[],
) {
  return Promise.all(
    products.map(async (product) => {
      const [imagesRaw, variants] = await Promise.all([
        ctx.db
          .query("productImages")
          .withIndex("by_product", (q) => q.eq("productId", product._id))
          .collect(),
        ctx.db
          .query("productVariants")
          .withIndex("by_product_and_active", (q) =>
            q.eq("productId", product._id).eq("isActive", true),
          )
          .collect(),
      ]);
      const images = imagesRaw.sort((a, b) => a.position - b.position);
      return { ...product, images, variants };
    }),
  );
}
