import { NextRequest, NextResponse } from "next/server";
import { z } from "zod";
import { prisma } from "@/lib/prisma";
import { getStripeClient } from "@/lib/stripe";
import { getAvailableSlots } from "@/lib/availability";

const checkoutSchema = z.object({
  serviceId: z.string().min(1),
  date: z.string().regex(/^\d{4}-\d{2}-\d{2}$/),
  startTime: z.string().regex(/^\d{2}:\d{2}$/),
  customerName: z.string().min(1).max(200),
  customerEmail: z.email(),
  customerPhone: z.string().min(1).max(50),
  notes: z.string().max(2000).optional(),
});

export async function POST(request: NextRequest) {
  const body = await request.json().catch(() => null);
  const parsed = checkoutSchema.safeParse(body);
  if (!parsed.success) {
    return NextResponse.json({ error: "Invalid booking details" }, { status: 400 });
  }
  const { serviceId, date, startTime, customerName, customerEmail, customerPhone, notes } =
    parsed.data;

  const service = await prisma.service.findUnique({ where: { id: serviceId } });
  if (!service || !service.active) {
    return NextResponse.json({ error: "Service not found" }, { status: 404 });
  }

  const availableSlots = await getAvailableSlots(date, service.durationMinutes);
  if (!availableSlots.includes(startTime)) {
    return NextResponse.json(
      { error: "That time slot is no longer available. Please pick another." },
      { status: 409 }
    );
  }

  let stripe;
  try {
    stripe = await getStripeClient();
  } catch {
    return NextResponse.json(
      { error: "Online payment is not set up yet. Please contact the salon directly." },
      { status: 503 }
    );
  }

  const booking = await prisma.booking.create({
    data: {
      serviceId,
      date,
      startTime,
      customerName,
      customerEmail,
      customerPhone,
      notes,
      status: "pending",
    },
  });

  const origin = request.nextUrl.origin;

  try {
    const session = await stripe.checkout.sessions.create({
      mode: "payment",
      customer_email: customerEmail,
      line_items: [
        {
          quantity: 1,
          price_data: {
            currency: "usd",
            unit_amount: service.priceCents,
            product_data: {
              name: service.name,
              description: `${date} at ${startTime}`,
            },
          },
        },
      ],
      success_url: `${origin}/book/success?session_id={CHECKOUT_SESSION_ID}`,
      cancel_url: `${origin}/book/cancel`,
      metadata: { bookingId: booking.id },
    });

    await prisma.booking.update({
      where: { id: booking.id },
      data: { stripeSessionId: session.id },
    });

    return NextResponse.json({ url: session.url });
  } catch (err) {
    await prisma.booking.delete({ where: { id: booking.id } });
    console.error("[checkout] Stripe session creation failed", err);
    return NextResponse.json({ error: "Could not start checkout. Please try again." }, { status: 502 });
  }
}
