import { eq, inArray } from 'drizzle-orm';
import { db, wishlistItems, itemClaims, guests } from '@/lib/db';

type RawItem = typeof wishlistItems.$inferSelect;

export async function attachClaimsToItems(items: RawItem[]) {
  if (items.length === 0) return [];
  const itemIds = items.map((i) => i.id);
  const rows = await db
    .select({
      id: itemClaims.id,
      itemId: itemClaims.itemId,
      quantity: itemClaims.quantity,
      note: itemClaims.note,
      isPurchased: itemClaims.isPurchased,
      claimedAt: itemClaims.claimedAt,
      guestId: guests.id,
      guestName: guests.name,
    })
    .from(itemClaims)
    .innerJoin(guests, eq(itemClaims.guestId, guests.id))
    .where(inArray(itemClaims.itemId, itemIds));

  const byItem = new Map<string, ReturnType<typeof shapeClaim>[]>();
  for (const r of rows) {
    const arr = byItem.get(r.itemId) ?? [];
    arr.push(shapeClaim(r));
    byItem.set(r.itemId, arr);
  }

  return items.map((it) => {
    const claims = byItem.get(it.id) ?? [];
    const claimedQuantity = claims.reduce((s, c) => s + c.quantity, 0);
    return {
      ...it,
      claims,
      claimedQuantity,
      remainingQuantity: Math.max(0, it.quantity - claimedQuantity),
    };
  });
}

function shapeClaim(r: {
  id: string; quantity: number; note: string | null; isPurchased: boolean;
  claimedAt: Date; guestId: string; guestName: string;
}) {
  return {
    id: r.id,
    quantity: r.quantity,
    note: r.note,
    isPurchased: r.isPurchased,
    claimedAt: r.claimedAt,
    guest: { id: r.guestId, name: r.guestName },
  };
}
