import { NextResponse } from 'next/server'
import { prisma } from '@/lib/prisma'
import { safeHandler, requireAuth, AuthError } from '@/lib/auth'
import { buildQuoteSnapshot, computeChangeSummary } from '@/lib/quote-diff'
import { logAudit } from '@/lib/audit'

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

  const quote = await prisma.quote.findUnique({
    where: { id },
    include: {
      items: { orderBy: { sortOrder: 'asc' } },
      query: { select: { queryNo: true, leadName: true, stage: true } },
    },
  })
  if (!quote) throw new AuthError('Quote not found', 404)

  return NextResponse.json(quote)
})

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

  const existing = await prisma.quote.findUnique({
    where: { id },
    include: { items: { orderBy: { sortOrder: 'asc' } } },
  })
  if (!existing) throw new AuthError('Quote not found', 404)

  // Calculate item totals
  const items = (data.items || []).map((item: any, index: number) => {
    const quantity = parseInt(item.quantity) || 1
    const unitCost = parseFloat(item.unitCost) || 0
    const totalCost = quantity * unitCost
    return {
      serviceType: item.serviceType,
      description: item.description || '',
      dayNumber: item.dayNumber ? parseInt(item.dayNumber) : null,
      quantity,
      unitCost,
      totalCost,
      sortOrder: item.sortOrder ?? index,
    }
  })

  // Calculate quote totals
  const subtotal = items.reduce((sum: number, item: any) => sum + item.totalCost, 0)
  const markupPercent = parseFloat(data.markupPercent) || 0
  const taxPercent = parseFloat(data.taxPercent) || 0
  const markup = subtotal * markupPercent / 100
  const taxAmount = (subtotal + markup) * taxPercent / 100
  const totalAmount = subtotal + markup + taxAmount

  // Build snapshot of current state and compute change summary
  const snapshot = buildQuoteSnapshot(existing, existing.items)
  const changeSummary = computeChangeSummary(snapshot, data.items || [], data)

  // Atomically create revision, delete old items, and update quote
  const quote = await prisma.$transaction(async (tx) => {
    await tx.quoteRevision.create({
      data: {
        quoteId: id,
        revisionNumber: existing.version,
        changeType: 'UPDATED',
        changeSummary,
        snapshotData: JSON.stringify(snapshot),
        changedById: userId,
      },
    })

    await tx.quoteItem.deleteMany({ where: { quoteId: id } })

    return tx.quote.update({
      where: { id },
      data: {
        validUntil: data.validUntil !== undefined ? (data.validUntil ? new Date(data.validUntil) : null) : undefined,
        notes: data.notes !== undefined ? (data.notes || null) : undefined,
        termsConditions: data.termsConditions !== undefined ? (data.termsConditions || null) : undefined,
        currency: data.currency || undefined,
        markupPercent,
        taxPercent,
        subtotal,
        markup,
        taxAmount,
        totalAmount,
        version: existing.version + 1,
        items: {
          create: items,
        },
      },
      include: {
        items: { orderBy: { sortOrder: 'asc' } },
        query: { select: { queryNo: true, leadName: true, stage: true } },
      },
    })
  })

  await logAudit({
    action: 'UPDATE',
    module: 'QUOTES',
    entity: 'Quote',
    entityId: quote.id,
    description: `Updated quote ${quote.quoteNo} (v${quote.version}): ${changeSummary}`,
    req,
  })

  return NextResponse.json(quote)
})

export const DELETE = safeHandler(async (req: Request, { params }: { params: Promise<{ id: string }> }) => {
  const { userId } = await requireAuth()
  const { id } = await params

  const quote = await prisma.quote.findUnique({
    where: { id },
    include: { items: { orderBy: { sortOrder: 'asc' } } },
  })
  if (!quote) throw new AuthError('Quote not found', 404)
  if (quote.isSelected) throw new AuthError('Cannot delete a selected quote', 400)

  // Create final revision before deletion
  const snapshot = buildQuoteSnapshot(quote, quote.items)
  await prisma.quoteRevision.create({
    data: {
      quoteId: id,
      revisionNumber: quote.version + 1,
      changeType: 'DELETED',
      changeSummary: 'Quote deleted',
      snapshotData: JSON.stringify(snapshot),
      changedById: userId,
    },
  })

  await prisma.quote.delete({ where: { id } })

  await logAudit({
    action: 'DELETE',
    module: 'QUOTES',
    entity: 'Quote',
    entityId: id,
    description: `Deleted quote ${quote.quoteNo}`,
    req,
  })

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