import { NextRequest, NextResponse } from "next/server";
import { requireAdmin } from "@/lib/api-auth";
import { db, tierDefinitions, auditLogs, eq } from "@epicure/db";
import { randomUUID } from "crypto";
import { UNLIMITED } from "@/lib/tiers";

interface RouteContext {
  params: Promise<{ tier: string }>;
}

const NUMERIC_FIELDS = ["maxRecipes", "aiCallsPerMonth", "storageMb", "maxPublicRecipes"] as const;
type NumericField = (typeof NUMERIC_FIELDS)[number];

const STRIPE_FIELDS = ["stripeProductId", "stripePriceIdMonthly", "stripePriceIdYearly"] as const;
type StripeField = (typeof STRIPE_FIELDS)[number];

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

  const { tier } = await params;
  if (tier !== "free" && tier !== "pro" && tier !== "family") {
    return NextResponse.json({ error: "Invalid tier" }, { status: 400 });
  }

  const body = (await req.json()) as Partial<Record<NumericField, number>> & Partial<Record<StripeField, string | null>>;
  const updateData: Partial<Record<NumericField, number>> & Partial<Record<StripeField, string | null>> = {};

  for (const field of NUMERIC_FIELDS) {
    const value = body[field];
    if (value === undefined) continue;
    if (!Number.isInteger(value) || (value < 0 && value !== UNLIMITED)) {
      return NextResponse.json({ error: `Invalid value for ${field}` }, { status: 400 });
    }
    updateData[field] = value;
  }

  for (const field of STRIPE_FIELDS) {
    const value = body[field];
    if (value === undefined) continue;
    if (value !== null && typeof value !== "string") {
      return NextResponse.json({ error: `Invalid value for ${field}` }, { status: 400 });
    }
    updateData[field] = value?.trim() || null;
  }

  const [updated] = await db
    .update(tierDefinitions)
    .set(updateData)
    .where(eq(tierDefinitions.tier, tier))
    .returning();

  if (!updated) {
    return NextResponse.json({ error: "Tier not found" }, { status: 404 });
  }

  await db.insert(auditLogs).values({
    id: randomUUID(),
    userId: session!.user.id,
    action: "admin.tier.update",
    targetType: "tier_definition",
    targetId: tier,
    metadata: JSON.stringify(updateData),
    createdAt: new Date(),
  });

  return NextResponse.json({ tierDefinition: updated });
}
