import { getCurrentUser } from '@/lib/auth/current-user'
import { env } from '@/lib/env'
import { buildLiveSnapshot } from '@/lib/services/live-snapshot'

export const dynamic = 'force-dynamic'
export const runtime = 'nodejs'

/**
 * Live grid stream (Server-Sent Events).
 *
 * SSE rather than WebSockets: the traffic is strictly server→client, it survives proxies
 * that mishandle upgrades, and the browser reconnects on its own. A WebSocket would add
 * a second protocol and a second failure mode for no gain here.
 *
 * The interval is cleared from the stream's `cancel` callback, so a viewer closing a tab
 * stops the work rather than leaving a timer recomputing snapshots forever.
 */
export async function GET(request: Request) {
  const user = await getCurrentUser()
  if (!user || !user.permissions.has('grid.read')) {
    return new Response(
      JSON.stringify({
        ok: false,
        error: { code: 'PERMISSION_DENIED', message: 'Not permitted.', messageAr: 'غير مصرح.' },
      }),
      { status: 403, headers: { 'Content-Type': 'application/json' } },
    )
  }

  const encoder = new TextEncoder()
  const tickMs = Math.max(1000, env.telemetryTickMs)

  const stream = new ReadableStream<Uint8Array>({
    async start(controller) {
      let closed = false

      const send = (event: string, data: unknown) => {
        if (closed) return
        try {
          controller.enqueue(encoder.encode(`event: ${event}\ndata: ${JSON.stringify(data)}\n\n`))
        } catch {
          closed = true
        }
      }

      const push = async () => {
        if (closed) return
        try {
          send('snapshot', await buildLiveSnapshot())
        } catch (error) {
          console.error('[stream] snapshot failed', error)
          send('stream-error', { message: 'snapshot_failed' })
        }
      }

      // Tell the browser how long to wait before reconnecting if the stream drops.
      controller.enqueue(encoder.encode(`retry: ${tickMs * 2}\n\n`))
      await push()

      const interval = setInterval(push, tickMs)

      const stop = () => {
        if (closed) return
        closed = true
        clearInterval(interval)
        try {
          controller.close()
        } catch {
          /* already closed */
        }
      }

      request.signal.addEventListener('abort', stop)
      ;(controller as unknown as { _nabdhStop?: () => void })._nabdhStop = stop
    },

    cancel() {
      // Reached when the consumer disconnects; the abort listener handles the rest.
    },
  })

  return new Response(stream, {
    headers: {
      'Content-Type': 'text/event-stream; charset=utf-8',
      'Cache-Control': 'no-cache, no-transform',
      Connection: 'keep-alive',
      // Proxies that buffer would defeat the point of a stream.
      'X-Accel-Buffering': 'no',
    },
  })
}
