import { NextRequest, NextResponse } from "next/server";
import { z } from "zod";
import { db, collections, collectionRecipes, eq, and, inArray } from "@epicure/db";
import { requireSessionOrApiKey } from "@/lib/api-auth";

type Params = { params: Promise<{ id: string }> };

const Schema = z.object({
  recipeIds: z.array(z.string()).min(1).max(500),
});

export async function PATCH(req: NextRequest, { params }: Params) {
  const { session, response } = await requireSessionOrApiKey(req);
  if (response) return response;
  const { id } = await params;

  const existing = await db.query.collections.findFirst({
    where: and(eq(collections.id, id), eq(collections.userId, session!.user.id)),
  });
  if (!existing) return NextResponse.json({ error: "Not found" }, { status: 404 });

  const body = await req.json() as unknown;
  const parsed = Schema.safeParse(body);
  if (!parsed.success) return NextResponse.json({ error: "Validation error", issues: parsed.error.issues }, { status: 400 });

  const current = await db.query.collectionRecipes.findMany({
    where: eq(collectionRecipes.collectionId, id),
    columns: { recipeId: true },
  });
  const currentIds = new Set(current.map((r) => r.recipeId));
  const requestedIds = parsed.data.recipeIds.filter((rid) => currentIds.has(rid));
  if (requestedIds.length === 0) return NextResponse.json({ error: "No matching recipes in this collection" }, { status: 400 });

  await db.transaction(async (tx) => {
    for (let i = 0; i < requestedIds.length; i++) {
      await tx
        .update(collectionRecipes)
        .set({ position: i })
        .where(and(eq(collectionRecipes.collectionId, id), inArray(collectionRecipes.recipeId, [requestedIds[i]!])));
    }
  });

  return NextResponse.json({ ok: true });
}
