import { NextRequest, NextResponse } from "next/server";
import { db, users, userAllergens, eq } from "@epicure/db";
import { requireSession } from "@/lib/api-auth";
import { z } from "zod";

const ALLERGEN_TAGS = ["peanuts", "treeNuts", "dairy", "eggs", "shellfish", "fish", "soy", "gluten"] as const;

const CompleteSchema = z.object({
  dietaryTags: z
    .object({
      vegan: z.boolean().optional(),
      vegetarian: z.boolean().optional(),
      glutenFree: z.boolean().optional(),
      dairyFree: z.boolean().optional(),
      nutFree: z.boolean().optional(),
      halal: z.boolean().optional(),
      kosher: z.boolean().optional(),
    })
    .optional(),
  allergens: z.array(z.enum(ALLERGEN_TAGS)).optional(),
});

export async function GET() {
  const { session, response } = await requireSession();
  if (response) return response;

  const [dbUser, allergenRows] = await Promise.all([
    db.query.users.findFirst({
      where: eq(users.id, session!.user.id),
      columns: { onboardingCompletedAt: true, dietaryTags: true },
    }),
    db.select().from(userAllergens).where(eq(userAllergens.userId, session!.user.id)),
  ]);

  return NextResponse.json({
    data: {
      completed: !!dbUser?.onboardingCompletedAt,
      dietaryTags: dbUser?.dietaryTags ?? {},
      allergens: allergenRows.map((r) => r.allergenTag),
    },
  });
}

// Marks onboarding done regardless of what (if anything) was filled in — a
// user can skip every step and this still fires so the wizard never shows
// again. dietaryTags/allergens are optional and only written if provided.
export async function POST(req: NextRequest) {
  const { session, response } = await requireSession();
  if (response) return response;

  const parsed = CompleteSchema.safeParse(await req.json().catch(() => ({})));
  if (!parsed.success) {
    return NextResponse.json({ error: parsed.error.flatten() }, { status: 400 });
  }

  const { dietaryTags, allergens } = parsed.data;
  const userId = session!.user.id;

  await db
    .update(users)
    .set({
      onboardingCompletedAt: new Date(),
      ...(dietaryTags ? { dietaryTags } : {}),
    })
    .where(eq(users.id, userId));

  if (allergens) {
    await db.delete(userAllergens).where(eq(userAllergens.userId, userId));
    if (allergens.length > 0) {
      await db.insert(userAllergens).values(allergens.map((allergenTag) => ({ userId, allergenTag })));
    }
  }

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