import { NextResponse } from 'next/server'
import { prisma } from '@/lib/prisma'
import { safeHandler, requireAuth, AuthError } from '@/lib/auth'

export const GET = safeHandler(async (req: Request) => {
  await requireAuth()
  const { searchParams } = new URL(req.url)
  const search = searchParams.get('search') || ''

  const bookings = await prisma.booking.findMany({
    where: search ? {
      bookingNo: { contains: search, mode: 'insensitive' },
    } : undefined,
    include: {
      query: {
        select: { leadName: true, queryNo: true },
      },
    },
    orderBy: { createdAt: 'desc' },
  })

  return NextResponse.json(bookings)
})

export const POST = safeHandler(async (req: Request) => {
  const { userId } = await requireAuth()
  const data = await req.json()

  if (!data.queryId) {
    throw new AuthError('Query is required', 400)
  }
  if (!data.startDate || !data.endDate) {
    throw new AuthError('Start date and end date are required', 400)
  }

  // Check the query exists and doesn't already have a booking
  const query = await prisma.query.findUnique({
    where: { id: data.queryId },
    include: { booking: true },
  })
  if (!query) throw new AuthError('Query not found', 404)
  if (query.booking) throw new AuthError('This query already has a booking', 409)

  // Find or create number series for bookings
  let series = await prisma.numberSeries.findFirst({ where: { module: 'BOOKING', docType: 'BOOKING' } })
  if (!series) {
    series = await prisma.numberSeries.create({
      data: { prefix: 'BKG', module: 'BOOKING', docType: 'BOOKING', nextNumber: 1, format: '{PREFIX}-{YEAR}-{NUM:4}' }
    })
  }
  const year = new Date().getFullYear()
  const bookingNo = `${series.prefix}-${year}-${String(series.nextNumber).padStart(4, '0')}`

  // Calculate totalAmount from selected quote if any
  let totalAmount = 0
  const selectedQuote = await prisma.quote.findFirst({
    where: { queryId: data.queryId, isSelected: true },
  })
  if (selectedQuote) {
    totalAmount = Number(selectedQuote.totalAmount)
  }

  // Create booking and update query stage in a transaction
  const booking = await prisma.$transaction(async (tx) => {
    const newBooking = await tx.booking.create({
      data: {
        bookingNo,
        queryId: data.queryId,
        startDate: new Date(data.startDate),
        endDate: new Date(data.endDate),
        totalAmount,
        currency: data.currency || 'USD',
        notes: data.notes || null,
        createdById: userId,
      },
    })

    // Update query stage to CONFIRMED
    await tx.query.update({
      where: { id: data.queryId },
      data: { stage: 'CONFIRMED' },
    })

    // Increment the number series
    await tx.numberSeries.update({
      where: { id: series!.id },
      data: { nextNumber: { increment: 1 } },
    })

    return newBooking
  })

  return NextResponse.json(booking, { status: 201 })
})
