import type { Context } from 'hono'
import { streamSSE } from 'hono/streaming'
import { subscribeAction } from '../feed.ts'

export function handleFeed(c: Context): Response {
  return streamSSE(c, async (stream) => {
    await stream.writeSSE({
      event: 'hello',
      data: JSON.stringify({ ts: Date.now() }),
    })

    const queue: Array<{ event: string; data: string }> = []
    let resolveNext: (() => void) | null = null
    const wake = () => {
      const r = resolveNext
      resolveNext = null
      r?.()
    }

    const unsubscribe = subscribeAction((packet) => {
      queue.push({ event: 'action', data: JSON.stringify(packet) })
      wake()
    })

    // Keepalive — sends a ping every 30s so intermediaries / browser
    // EventSource consider the connection live.
    const pingTimer = setInterval(() => {
      queue.push({ event: 'ping', data: String(Date.now()) })
      wake()
    }, 30_000)

    try {
      while (!stream.aborted) {
        if (queue.length === 0) {
          await new Promise<void>((res) => {
            resolveNext = res
          })
        }
        const msg = queue.shift()
        if (msg) await stream.writeSSE(msg)
      }
    } finally {
      unsubscribe()
      clearInterval(pingTimer)
    }
  })
}
