import { NextResponse } from "next/server";
import { auth } from "@/lib/auth";
import { db } from "@/lib/db";
import { stripe } from "@/lib/stripe";
import { logger } from "@/lib/logger";

/** Allowed one-time purchase amounts in cents: $10, $100, $1000 */
const ALLOWED_AMOUNTS_CENTS = [1000, 10000, 100000] as const;

function isAllowedAmount(cents: number): cents is (typeof ALLOWED_AMOUNTS_CENTS)[number] {
  return ALLOWED_AMOUNTS_CENTS.includes(cents as (typeof ALLOWED_AMOUNTS_CENTS)[number]);
}

/**
 * POST /api/marketplace/credits/purchase
 *
 * Body: { amount_cents: 1000 | 10000 | 100000 }
 * Creates a Stripe Checkout session for one-time payment; on success (webhook or return URL)
 * the user's marketplaceCreditsCents is increased. Returns { url } to redirect the client.
 */
export async function POST(request: Request) {
  const session = await auth();
  if (!session?.user?.id) {
    return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
  }

  let amountCents: number;
  try {
    const body = (await request.json()) as { amount_cents?: number };
    amountCents = Number(body.amount_cents);
    if (!Number.isInteger(amountCents) || !isAllowedAmount(amountCents)) {
      return NextResponse.json(
        {
          error: "amount_cents must be one of 1000, 10000, 100000 ($10, $100, $1000)",
        },
        { status: 400 },
      );
    }
  } catch {
    return NextResponse.json(
      { error: "Invalid JSON body; require { amount_cents: 1000 | 10000 | 100000 }" },
      { status: 400 },
    );
  }

  const user = await db.user.findUnique({
    where: { id: session.user.id },
    select: { id: true, email: true, stripeCustomerId: true },
  });
  if (!user) {
    return NextResponse.json({ error: "User not found" }, { status: 404 });
  }

  if (!stripe) {
    return NextResponse.json(
      { error: "Stripe is not configured. Set STRIPE_SECRET_KEY." },
      { status: 503 },
    );
  }

  let stripeCustomerId = user.stripeCustomerId;
  if (!stripeCustomerId) {
    const customer = await stripe.customers.create({
      email: user.email,
      metadata: { userId: user.id },
    });
    stripeCustomerId = customer.id;
    await db.user.update({
      where: { id: user.id },
      data: { stripeCustomerId },
    });
  }

  const baseUrl = process.env.NEXT_PUBLIC_APP_URL || "http://localhost:3000";
  try {
    const checkoutSession = await stripe.checkout.sessions.create({
      customer: stripeCustomerId,
      mode: "payment",
      payment_method_types: ["card"],
      line_items: [
        {
          price_data: {
            currency: "usd",
            unit_amount: amountCents,
            product_data: {
              name: "LLMHosts Marketplace Credits",
              description: `$${(amountCents / 100).toFixed(2)} prepaid credits for marketplace usage`,
            },
          },
          quantity: 1,
        },
      ],
      success_url: `${baseUrl}/dashboard/devices?credits=success`,
      cancel_url: `${baseUrl}/dashboard/devices?credits=cancelled`,
      metadata: {
        userId: user.id,
        type: "marketplace_credits",
        amount_cents: String(amountCents),
      },
    });

    return NextResponse.json({ url: checkoutSession.url });
  } catch (err) {
    logger.error(
      { err, action: "marketplace_credits_purchase", userId: user.id, amountCents },
      "Failed to create credits checkout session",
    );
    return NextResponse.json(
      { error: "Failed to create checkout session" },
      { status: 500 },
    );
  }
}
