import { NextRequest, NextResponse } from "next/server"
import { stripe, isStripeEnabled } from "@/lib/stripe"
import { db } from "@/lib/db"
import { auth } from "@/lib/auth"
import { toStringArray } from "@/lib/json-array"
import { z } from "zod"

const itemSchema = z.object({
  id: z.string(),
  size: z.string(),
  quantity: z.number().int().positive().max(10),
})

const bodySchema = z.object({
  items: z.array(itemSchema).min(1).max(20),
})

export async function POST(req: NextRequest) {
  if (!isStripeEnabled || !stripe) {
    return NextResponse.json(
      { error: "Les paiements ne sont pas encore activés. Reviens très bientôt." },
      { status: 503 }
    )
  }

  const session = await auth()
  if (!session?.user) {
    return NextResponse.json({ error: "Non authentifié" }, { status: 401 })
  }

  const userId = session.user.id
  if (!userId) return NextResponse.json({ error: "Session invalide" }, { status: 401 })

  const body = await req.json()
  const parsed = bodySchema.safeParse(body)
  if (!parsed.success) {
    return NextResponse.json({ error: "Données invalides" }, { status: 400 })
  }

  const { items } = parsed.data

  // Prix et disponibilité vérifiés côté serveur — jamais depuis le client
  const products = await db.product.findMany({
    where: { id: { in: items.map((i) => i.id) }, active: true },
  })
  const productMap = new Map(products.map((p) => [p.id, p]))

  for (const item of items) {
    const product = productMap.get(item.id)
    if (!product) {
      return NextResponse.json({ error: "Produit introuvable" }, { status: 400 })
    }
    if (!toStringArray(product.sizes).includes(item.size)) {
      return NextResponse.json({ error: `Taille indisponible pour ${product.name}` }, { status: 400 })
    }
    if (product.stock < item.quantity) {
      return NextResponse.json({ error: `Stock insuffisant pour ${product.name}` }, { status: 409 })
    }
  }

  const appUrl = process.env.NEXT_PUBLIC_APP_URL

  const stripeSession = await stripe.checkout.sessions.create({
    payment_method_types: ["card"],
    mode: "payment",
    line_items: items.map((item) => {
      const product = productMap.get(item.id)!
      const images = toStringArray(product.images)
      return {
        price_data: {
          currency: "eur",
          product_data: {
            name: `${product.name} — ${item.size}`,
            images: images[0] ? [images[0]] : [],
          },
          unit_amount: product.price,
        },
        quantity: item.quantity,
      }
    }),
    success_url: `${appUrl}/checkout/success?session_id={CHECKOUT_SESSION_ID}`,
    cancel_url: `${appUrl}/cart`,
    customer_email: session.user.email!,
    metadata: { userId },
    shipping_address_collection: { allowed_countries: ["BE", "FR", "NL", "LU", "DE"] },
  })

  const total = items.reduce(
    (sum, i) => sum + productMap.get(i.id)!.price * i.quantity,
    0
  )
  await db.order.create({
    data: {
      userId,
      total,
      stripeSessionId: stripeSession.id,
      shippingAddress: {},
      items: {
        create: items.map((item) => ({
          productId: item.id,
          size: item.size,
          quantity: item.quantity,
          price: productMap.get(item.id)!.price,
        })),
      },
    },
  })

  return NextResponse.json({ url: stripeSession.url })
}
