import { NextRequest, NextResponse } from "next/server";
import { z } from "zod";
import { db, recipes, eq, and, or } from "@epicure/db";
import { requireSessionOrApiKey } from "@/lib/api-auth";
import { applyRateLimit } from "@/lib/rate-limit";
import { getDefaultProviderWithKey } from "@/lib/ai/resolve-user-key";
import { withAiQuota, resolveAiConfigOrError } from "@/lib/ai/ai-error";
import { scaleRecipe } from "@/lib/ai/features/scale-recipe";

const Schema = z.object({
  recipeId: z.string(),
  targetServings: z.number().int().min(1).max(100),
});

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

  const limited = await applyRateLimit(`rl:ai:scale:${session!.user.id}`, 20, 60);
  if (limited) return limited;

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

  const { recipeId, targetServings } = parsed.data;

  const recipe = await db.query.recipes.findFirst({
    where: and(
      eq(recipes.id, recipeId),
      or(
        eq(recipes.authorId, session!.user.id),
        eq(recipes.visibility, "public")
      )
    ),
    with: { ingredients: true },
  });

  if (!recipe) {
    return NextResponse.json({ error: "Not found" }, { status: 404 });
  }

  const configResult = await resolveAiConfigOrError(() => getDefaultProviderWithKey(session!.user.id, "text"));
  if (!configResult.ok) return configResult.response;
  const aiConfig = configResult.data;

  const result = await withAiQuota(session!.user.id, session!.user.tier as "free" | "pro" | "family", () =>
    scaleRecipe(
      {
        title: recipe.title,
        baseServings: recipe.baseServings,
        ingredients: recipe.ingredients,
      },
      targetServings,
      recipe.baseServings,
      aiConfig,
      (session!.user as { locale?: string }).locale ?? "en"
    ), { skipQuota: aiConfig.isByok }
  );
  if (!result.ok) return result.response;

  return NextResponse.json({ ingredients: result.data });
}
