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";

export async function POST(request: Request) {
  try {
    const session = await auth();

    if (!session?.user?.id) {
      return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
    }

    const { plan, priceId: legacyPriceId, seats } = (await request.json()) as {
      plan?: string;
      priceId?: string;
      seats?: number;
    };

    // Resolve price ID from plan name (preferred) or accept legacy direct priceId
    const priceMap: Record<string, string | undefined> = {
      pro: process.env.STRIPE_PRO_PRICE_ID,
      team: process.env.STRIPE_TEAM_PRICE_ID,
      enterprise: process.env.STRIPE_ENTERPRISE_PRICE_ID,
    };

    const priceId = plan ? priceMap[plan] : legacyPriceId;

    if (!priceId) {
      return NextResponse.json(
        { error: plan ? `No price configured for plan: ${plan}` : "Plan is required" },
        { 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 },
      );
    }

    // Create or retrieve Stripe customer
    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 },
      });
    }

    // Determine quantity: team plans allow multi-seat checkout
    const isTeamPlan = plan === "team";
    const quantity = isTeamPlan ? Math.max(1, Math.min(seats ?? 1, 100)) : 1;

    // Create checkout session
    const lineItem: { price: string; quantity: number; adjustable_quantity?: { enabled: boolean; minimum: number; maximum: number } } = {
      price: priceId,
      quantity,
    };

    // Allow seat adjustment for team plans
    if (isTeamPlan) {
      lineItem.adjustable_quantity = { enabled: true, minimum: 1, maximum: 100 };
    }

    const appUrl = process.env.NEXT_PUBLIC_APP_URL || "http://localhost:3000";

    const checkoutSession = await stripe.checkout.sessions.create({
      customer: stripeCustomerId,
      mode: "subscription",
      payment_method_types: ["card", "link"],
      line_items: [lineItem],
      billing_address_collection: "auto",
      phone_number_collection: { enabled: false },
      tax_id_collection: { enabled: false },
      custom_text: {
        submit: {
          message: "No hidden fees. Cancel anytime from your dashboard.",
        },
      },
      success_url: `${appUrl}/dashboard?checkout=success&session_id={CHECKOUT_SESSION_ID}`,
      cancel_url: `${appUrl}/pricing?checkout=cancelled`,
      metadata: { userId: user.id },
    });

    return NextResponse.json({ url: checkoutSession.url });
  } catch (error) {
    logger.error({ err: error, action: 'stripe_checkout' }, 'Failed to create checkout session');
    return NextResponse.json(
      { error: "Failed to create checkout session" },
      { status: 500 },
    );
  }
}
