import { NextRequest } from 'next/server'
import { auth } from '@/lib/auth'
import { prisma } from '@/lib/prisma'
import { OrderStatus } from '@prisma/client'

// Polling interval in milliseconds - faster = smoother logs
const POLL_INTERVAL_MS = 500

/**
 * GET /api/v1/admin/orders/[id]/logs/stream
 * Stream provisioning logs via Server-Sent Events
 *
 * Optimized for low-latency log streaming:
 * - 500ms polling interval for near-real-time updates
 * - Only sends status updates when changed
 * - Batches multiple logs per event for efficiency
 */
export async function GET(
  request: NextRequest,
  { params }: { params: Promise<{ id: string }> }
) {
  try {
    const session = await auth()

    if (!session || session.user.userType !== 'staff') {
      return new Response('Unauthorized', { status: 401 })
    }

    const { id: orderId } = await params

    // Verify order exists
    const order = await prisma.order.findUnique({
      where: { id: orderId },
      select: { id: true, status: true },
    })

    if (!order) {
      return new Response('Order not found', { status: 404 })
    }

    // Create SSE response
    const encoder = new TextEncoder()
    let lastLogId: string | null = null
    let lastStatus: OrderStatus = order.status
    let isActive = true

    const stream = new ReadableStream({
      async start(controller) {
        // Send initial connection message
        controller.enqueue(
          encoder.encode(`event: connected\ndata: ${JSON.stringify({ orderId })}\n\n`)
        )

        // Send initial status
        controller.enqueue(
          encoder.encode(`event: status\ndata: ${JSON.stringify({ status: order.status })}\n\n`)
        )

        // Poll for new logs
        const poll = async () => {
          if (!isActive) return

          try {
            // Fetch new logs and current status in parallel for speed
            const [newLogs, currentOrder] = await Promise.all([
              prisma.provisioningLog.findMany({
                where: {
                  orderId,
                  ...(lastLogId ? { id: { gt: lastLogId } } : {}),
                },
                orderBy: { timestamp: 'asc' },
                take: 100, // Increased batch size
              }),
              prisma.order.findUnique({
                where: { id: orderId },
                select: { status: true },
              }),
            ])

            if (!currentOrder) {
              controller.enqueue(
                encoder.encode(`event: error\ndata: ${JSON.stringify({ error: 'Order not found' })}\n\n`)
              )
              controller.close()
              return
            }

            // Send logs immediately as they arrive
            if (newLogs.length > 0) {
              lastLogId = newLogs[newLogs.length - 1].id

              // Send each log individually for smooth streaming
              for (const log of newLogs) {
                controller.enqueue(
                  encoder.encode(`event: log\ndata: ${JSON.stringify({
                    id: log.id,
                    level: log.level,
                    step: log.step,
                    message: log.message,
                    timestamp: log.timestamp.toISOString(),
                  })}\n\n`)
                )
              }
            }

            // Only send status update if changed
            if (currentOrder.status !== lastStatus) {
              lastStatus = currentOrder.status
              controller.enqueue(
                encoder.encode(`event: status\ndata: ${JSON.stringify({ status: currentOrder.status })}\n\n`)
              )
            }

            // Check if provisioning is complete
            const terminalStatuses: OrderStatus[] = [
              OrderStatus.FULFILLED,
              OrderStatus.EMAIL_CONFIGURED,
              OrderStatus.FAILED,
            ]

            if (terminalStatuses.includes(currentOrder.status)) {
              controller.enqueue(
                encoder.encode(`event: complete\ndata: ${JSON.stringify({
                  status: currentOrder.status,
                  success: currentOrder.status !== OrderStatus.FAILED
                })}\n\n`)
              )
              controller.close()
              return
            }

            // Continue polling with fast interval
            setTimeout(poll, POLL_INTERVAL_MS)
          } catch (err) {
            console.error('SSE polling error:', err)
            controller.enqueue(
              encoder.encode(`event: error\ndata: ${JSON.stringify({ error: 'Polling error' })}\n\n`)
            )
            controller.close()
          }
        }

        // Start polling immediately
        poll()
      },
      cancel() {
        isActive = false
      },
    })

    return new Response(stream, {
      headers: {
        'Content-Type': 'text/event-stream',
        'Cache-Control': 'no-cache, no-transform',
        'Connection': 'keep-alive',
        'X-Accel-Buffering': 'no', // Disable nginx buffering
      },
    })
  } catch (error) {
    console.error('Error setting up SSE stream:', error)
    return new Response('Internal Server Error', { status: 500 })
  }
}
