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

type Params = { params: Promise<{ id: string }> }

export const GET = safeHandler(async (_req: Request, { params }: Params) => {
  await requireAuth()
  const { id } = await params

  const invoice = await prisma.invoice.findUnique({
    where: { id },
    include: {
      items: { orderBy: { sortOrder: 'asc' } },
      booking: {
        select: { bookingNo: true, query: { select: { leadName: true } } },
      },
      createdBy: {
        select: { name: true, email: true },
      },
    },
  })
  if (!invoice) throw new AuthError('Invoice not found', 404)

  return NextResponse.json(invoice)
})

export const PUT = safeHandler(async (req: Request, { params }: Params) => {
  await requireAuth()
  const { id } = await params
  const data = await req.json()

  // Check invoice exists and is in DRAFT status
  const existing = await prisma.invoice.findUnique({ where: { id } })
  if (!existing) throw new AuthError('Invoice not found', 404)
  if (existing.status !== 'DRAFT') {
    throw new AuthError('Only DRAFT invoices can be updated', 400)
  }

  // Prepare items if provided
  const items = data.items
    ? (data.items as any[]).map((item: any, index: number) => {
        const quantity = parseInt(item.quantity) || 1
        const unitPrice = parseFloat(item.unitPrice) || 0
        const totalPrice = quantity * unitPrice
        return {
          description: item.description,
          hsnCode: item.hsnCode || null,
          quantity,
          unitPrice,
          totalPrice,
          sortOrder: item.sortOrder ?? index,
        }
      })
    : null

  // Recalculate totals if items are provided
  let totals: any = {}
  if (items) {
    const subtotal = items.reduce((sum: number, item: any) => sum + item.totalPrice, 0)
    const cgstRate = parseFloat(data.cgstRate) ?? Number(existing.cgstRate)
    const sgstRate = parseFloat(data.sgstRate) ?? Number(existing.sgstRate)
    const igstRate = parseFloat(data.igstRate) ?? Number(existing.igstRate)
    const cgstAmount = subtotal * cgstRate / 100
    const sgstAmount = subtotal * sgstRate / 100
    const igstAmount = subtotal * igstRate / 100
    const totalTax = cgstAmount + sgstAmount + igstAmount
    const totalAmount = subtotal + totalTax
    totals = { subtotal, cgstRate, cgstAmount, sgstRate, sgstAmount, igstRate, igstAmount, totalTax, totalAmount }
  }

  const invoice = await prisma.$transaction(async (tx) => {
    // Delete existing items and re-create if items provided
    if (items) {
      await tx.invoiceItem.deleteMany({ where: { invoiceId: id } })
    }

    const updated = await tx.invoice.update({
      where: { id },
      data: {
        type: data.type ?? undefined,
        issueDate: data.issueDate ? new Date(data.issueDate) : undefined,
        dueDate: data.dueDate !== undefined ? (data.dueDate ? new Date(data.dueDate) : null) : undefined,
        clientName: data.clientName ?? undefined,
        clientEmail: data.clientEmail !== undefined ? (data.clientEmail || null) : undefined,
        clientPhone: data.clientPhone !== undefined ? (data.clientPhone || null) : undefined,
        clientGstNumber: data.clientGstNumber !== undefined ? (data.clientGstNumber || null) : undefined,
        clientPanNumber: data.clientPanNumber !== undefined ? (data.clientPanNumber || null) : undefined,
        clientAddress: data.clientAddress !== undefined ? (data.clientAddress || null) : undefined,
        currency: data.currency ?? undefined,
        notes: data.notes !== undefined ? (data.notes || null) : undefined,
        termsConditions: data.termsConditions !== undefined ? (data.termsConditions || null) : undefined,
        ...totals,
        ...(items
          ? {
              items: {
                create: items,
              },
            }
          : {}),
      },
      include: {
        items: { orderBy: { sortOrder: 'asc' } },
        booking: {
          select: { bookingNo: true, query: { select: { leadName: true } } },
        },
      },
    })

    return updated
  })

  return NextResponse.json(invoice)
})

export const DELETE = safeHandler(async (_req: Request, { params }: Params) => {
  await requireAuth()
  const { id } = await params

  const invoice = await prisma.invoice.findUnique({ where: { id } })
  if (!invoice) throw new AuthError('Invoice not found', 404)
  if (invoice.status !== 'DRAFT') {
    throw new AuthError('Only DRAFT invoices can be deleted', 400)
  }

  await prisma.$transaction(async (tx) => {
    await tx.invoiceItem.deleteMany({ where: { invoiceId: id } })
    await tx.invoice.delete({ where: { id } })
  })

  return NextResponse.json({ message: 'Deleted' })
})
