import Cors from 'micro-cors'
import { NextResponse } from 'next/server'

import Stripe from 'stripe'
import { headers } from 'next/headers'
import { prisma } from '@/lib/prisma' // Adjust the path as needed

const cors = Cors({
  allowMethods: ['POST', 'HEAD'],
})

const stripe = new Stripe(process.env.STRIPE_SECRET_KEY as string)

export async function POST(req) {
  if (req.method !== 'POST') {
    // res.status(500).json({ message: 'Bad request' })
    NextResponse.json({ message: 'Bad request', status: 500 })

    return
  }

  let event

  // const rawBody = req.text() // Use 'buffer' from 'micro' to get the raw body
  // const rawBody = await buffer(req) // Use 'buffer' from 'micro' to get the raw body
  // const textBody = rawBody.toString()
  // const sig = headers().get('Stripe-Signature') as string

  // const sig = req.headers['stripe-signature']

  const rawBody = await req.text()

  try {
    event = stripe.webhooks.constructEvent(
      rawBody,
      headers().get('Stripe-Signature') as string,
      process.env.STRIPE_WEBHOOK_KEY as string
    )
  } catch (err) {
    console.error(err.message)
    // res.status(400).send(`Webhook Error: ${err.message}`)
    NextResponse.json({ message: `Webhook Error: ${err.message}`, status: 400 })

    return
  }

  const eventType = event.type
  const stripeAccountData = event.data.object

  switch (eventType) {
    case 'checkout.session.completed':
      const session = event.data.object // The checkout session object
      console.log({ session })
      // Assuming the PaymentIntent is linked to the session and has metadata
      const paymentIntentId = session.payment_intent

      const paymentIntent = await stripe.paymentIntents.retrieve(
        paymentIntentId
      )
      console.log({ paymentIntent })

      const appointmentKey = paymentIntent.metadata.appointmentKey

      console.log('metadata', paymentIntent.metadata.appointmentKey)

      // Update the appointment in the database
      if (appointmentKey) {
        try {
          await prisma.appointment.update({
            where: {
              appointmentKey: appointmentKey, // Assuming 'key' is the field you use to identify appointments
            },
            data: {
              paymentStatus: 'authorized',
              paymentIntentId,
              sessionId: session.id,
              authorizedDate: new Date().toISOString(),
            },
          })

          console.log('Appointment payment status updated successfully')
        } catch (error) {
          console.error('Error updating appointment payment status:', error)
        }
      }

      break

    case 'account.updated':
      console.log('Account updated:', stripeAccountData)
      try {
        const email = stripeAccountData.email
        if (email) {
          // Find the expert associated with the email
          const expert = await prisma.expert.findFirst({
            where: {
              User: {
                email: email,
              },
            },
            include: {
              StripeAccount: true, // Assuming this relation is correctly set up
            },
          })

          const parsedStripeAccountData = JSON.parse(
            JSON.stringify(stripeAccountData)
          )

          if (expert && expert.stripeAccountId) {
            await prisma.stripeAccount.update({
              where: {
                expertId: expert.id,
              },
              data: {
                stripeData: parsedStripeAccountData, // Assuming this is JSON-compatible
              },
            })
          } else {
            console.log('Expert or StripeAccount not found for email:', email)
          }
        }
      } catch (err) {
        console.error('Failed to handle account.updated event:', err)
        // Adjust according to your error handling strategy
        return
      }
      break

    default:
      console.log('Unhandled event type:', eventType)
  }

  return NextResponse.json({ message: 'successfully received', status: 200 })
}
