import { NextRequest, NextResponse } from "next/server"
import { stripe, isStripeEnabled } from "@/lib/stripe"
import { db } from "@/lib/db"
import type Stripe from "stripe"

export async function POST(req: NextRequest) {
  if (!isStripeEnabled || !stripe || !process.env.STRIPE_WEBHOOK_SECRET) {
    return NextResponse.json({ error: "Stripe non configuré" }, { status: 503 })
  }

  const body = await req.text()
  const sig = req.headers.get("stripe-signature")
  if (!sig) {
    return NextResponse.json({ error: "Signature manquante" }, { status: 400 })
  }

  let event: Stripe.Event
  try {
    event = stripe.webhooks.constructEvent(
      body,
      sig,
      process.env.STRIPE_WEBHOOK_SECRET!
    )
  } catch {
    return NextResponse.json({ error: "Webhook signature invalid" }, { status: 400 })
  }

  switch (event.type) {
    case "checkout.session.completed": {
      const session = event.data.object as Stripe.Checkout.Session

      const order = await db.order.findFirst({
        where: { stripeSessionId: session.id, status: "PENDING" },
        include: { items: { include: { product: true } } },
      })
      if (!order) break

      // Marque payée, décrémente le stock et numérote les pièces en édition
      // limitée (n° = position dans la file des exemplaires déjà vendus).
      await db.$transaction(async (tx) => {
        await tx.order.update({
          where: { id: order.id },
          data: {
            status: "PAID",
            shippingAddress: (session.customer_details?.address ?? {}) as object,
          },
        })

        for (const item of order.items) {
          await tx.product.update({
            where: { id: item.productId },
            data: { stock: { decrement: item.quantity } },
          })

          if (item.product.editionSize) {
            const sold = await tx.orderItem.count({
              where: { productId: item.productId, editionNumber: { not: null } },
            })
            await tx.orderItem.update({
              where: { id: item.id },
              data: { editionNumber: sold + 1 },
            })
          }
        }
      })
      break
    }

    case "checkout.session.expired": {
      const session = event.data.object as Stripe.Checkout.Session
      await db.order.updateMany({
        where: { stripeSessionId: session.id, status: "PENDING" },
        data: { status: "CANCELLED" },
      })
      break
    }
  }

  return NextResponse.json({ received: true })
}
