import { NextResponse } from "next/server"; import { prisma } from "../../../../lib/prisma"; import { cookies } from "next/headers"; import { getServerSession } from "next-auth"; import { authOptions } from "../../../../lib/auth"; export async function POST(req: Request) { try { const body = await req.json(); const slug = body.slug as string; const productId = body.productId as string; const priceId = body.priceId as string; const name = body.name as string; const unitAmount = Number(body.unitAmount); const currency = body.currency as string; const quantity = Number(body.quantity) || 1; if ( !slug || !productId || !priceId || !name || !Number.isFinite(unitAmount) || !currency ) { return NextResponse.json( { error: "Missing required cart fields." }, { status: 400 } ); } const store = await prisma.store.findUnique({ where: { slug } }); if (!store) { return NextResponse.json({ error: "Store not found." }, { status: 404 }); } const session = await getServerSession(authOptions); const cookieStore = cookies(); let sessionId = cookieStore.get("sf_session")?.value; const createdNew = !sessionId; if (!sessionId) sessionId = crypto.randomUUID(); const sessionCart = await prisma.cart.findUnique({ where: { storeId_sessionId: { storeId: store.id, sessionId } }, }); let cart; if (session?.user?.email) { const user = await prisma.user.findUnique({ where: { email: session.user.email }, }); if (!user) { return NextResponse.json({ error: "User not found." }, { status: 404 }); } const userCart = await prisma.cart.findUnique({ where: { storeId_userId: { storeId: store.id, userId: user.id } }, }); if (!userCart) { if (sessionCart) { cart = await prisma.cart.update({ where: { id: sessionCart.id }, data: { userId: user.id }, }); } else { cart = await prisma.cart.create({ data: { storeId: store.id, userId: user.id, sessionId }, }); } } else if (sessionCart && sessionCart.id !== userCart.id) { const sessionItems = await prisma.cartItem.findMany({ where: { cartId: sessionCart.id }, }); for (const item of sessionItems) { const existing = await prisma.cartItem.findFirst({ where: { cartId: userCart.id, priceId: item.priceId }, }); if (existing) { await prisma.cartItem.update({ where: { id: existing.id }, data: { quantity: existing.quantity + item.quantity }, }); } else { await prisma.cartItem.create({ data: { cartId: userCart.id, productId: item.productId, priceId: item.priceId, name: item.name, unitAmount: item.unitAmount, currency: item.currency, quantity: item.quantity, }, }); } } await prisma.cart.delete({ where: { id: sessionCart.id } }); cart = await prisma.cart.update({ where: { id: userCart.id }, data: { sessionId }, }); } else if (userCart.sessionId !== sessionId) { cart = await prisma.cart.update({ where: { id: userCart.id }, data: { sessionId }, }); } else { cart = userCart; } } else { cart = sessionCart ?? (await prisma.cart.create({ data: { storeId: store.id, sessionId } })); } const existing = await prisma.cartItem.findFirst({ where: { cartId: cart.id, priceId }, }); const item = existing ? await prisma.cartItem.update({ where: { id: existing.id }, data: { quantity: existing.quantity + quantity }, }) : await prisma.cartItem.create({ data: { cartId: cart.id, productId, priceId, name, unitAmount, currency, quantity, }, }); const res = NextResponse.json({ item }); if (createdNew) { res.cookies.set("sf_session", sessionId, { httpOnly: true, sameSite: "lax", path: "/", }); } return res; } catch (err: any) { return NextResponse.json( { error: err?.message || "Failed to add to cart." }, { status: 500 } ); } }