import { NextRequest, NextResponse } from 'next/server'
import { stripe, PRICE_TO_PLAN } from '@/lib/stripe'
import { prisma } from '@/lib/prisma'
import { headers } from 'next/headers'

export async function POST(req: NextRequest) {
  const body = await req.text()
  const headersList = await headers()
  const sig = headersList.get('stripe-signature')

  if (!sig) {
    return NextResponse.json({ error: 'No signature' }, { status: 400 })
  }

  let event

  try {
    event = stripe.webhooks.constructEvent(
      body,
      sig,
      process.env.STRIPE_WEBHOOK_SECRET!
    )
  } catch (err: any) {
    console.error('Webhook signature verification failed:', err.message)
    return NextResponse.json({ error: `Webhook Error: ${err.message}` }, { status: 400 })
  }

  try {
    switch (event.type) {
      case 'checkout.session.completed': {
        const session = event.data.object as any
        const userId = session.metadata?.userId
        const subscriptionId = session.subscription as string
        const customerId = session.customer as string

        if (!userId || !subscriptionId) {
          console.error('Missing userId or subscriptionId in checkout session')
          break
        }

        // Get subscription to find the price
        const subscription = await stripe.subscriptions.retrieve(subscriptionId)
        const priceId = subscription.items.data[0]?.price?.id

        if (!priceId) {
          console.error('No price ID found in subscription')
          break
        }

        const planMapping = PRICE_TO_PLAN[priceId]
        if (!planMapping) {
          console.error('Unknown price ID:', priceId)
          break
        }

        // Update user
        await prisma.user.update({
          where: { id: userId },
          data: {
            plan: planMapping.plan,
            credits: planMapping.credits,
            stripeCustomerId: customerId,
            stripeSubscriptionId: subscriptionId,
            stripePriceId: priceId,
          },
        })

        // Create subscription record
        await prisma.subscription.create({
          data: {
            userId,
            plan: planMapping.plan,
            status: 'ACTIVE',
            stripeId: subscriptionId,
          },
        })

        console.log(`✅ User ${userId} upgraded to ${planMapping.plan} with ${planMapping.credits} credits`)
        break
      }

      case 'customer.subscription.updated': {
        const subscription = event.data.object as any
        const userId = subscription.metadata?.userId

        if (!userId) {
          console.log('No userId in subscription metadata, skipping')
          break
        }

        const priceId = subscription.items.data[0]?.price?.id
        if (priceId) {
          const planMapping = PRICE_TO_PLAN[priceId]
          if (planMapping) {
            await prisma.user.update({
              where: { id: userId },
              data: {
                plan: planMapping.plan,
                credits: planMapping.credits,
                stripePriceId: priceId,
              },
            })
            console.log(`📝 User ${userId} subscription updated to ${planMapping.plan}`)
          }
        }

        // Update subscription status
        if (subscription.status === 'active') {
          await prisma.subscription.updateMany({
            where: { stripeId: subscription.id },
            data: { status: 'ACTIVE' },
          })
        } else if (subscription.status === 'canceled' || subscription.status === 'unpaid') {
          await prisma.subscription.updateMany({
            where: { stripeId: subscription.id },
            data: { status: 'CANCELLED' },
          })
        }
        break
      }

      case 'customer.subscription.deleted': {
        const subscription = event.data.object as any
        const userId = subscription.metadata?.userId

        if (userId) {
          await prisma.user.update({
            where: { id: userId },
            data: {
              plan: 'FREE',
              credits: 5,
              stripeSubscriptionId: null,
              stripePriceId: null,
            },
          })

          await prisma.subscription.updateMany({
            where: { stripeId: subscription.id },
            data: { status: 'CANCELLED' },
          })

          console.log(`❌ User ${userId} downgraded to FREE`)
        }
        break
      }

      case 'invoice.payment_succeeded': {
        const invoice = event.data.object as any
        // On renewal, refresh credits
        const subscriptionId = invoice.subscription as string
        if (subscriptionId && invoice.billing_reason === 'subscription_cycle') {
          const sub = await stripe.subscriptions.retrieve(subscriptionId)
          const userId = sub.metadata?.userId
          const priceId = sub.items.data[0]?.price?.id

          if (userId && priceId) {
            const planMapping = PRICE_TO_PLAN[priceId]
            if (planMapping) {
              await prisma.user.update({
                where: { id: userId },
                data: { credits: planMapping.credits },
              })
              console.log(`💰 Renewed credits for user ${userId}: ${planMapping.credits}`)
            }
          }
        }
        break
      }

      default:
        console.log(`Unhandled event: ${event.type}`)
    }
  } catch (err: any) {
    console.error('Error processing webhook:', err)
    // Still return 200 to prevent Stripe retries for processing errors
  }

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