import { useEffect, useRef, useState } from 'react'
import { api } from '../api/client.js'

// Subscribe to the public shard live-event SSE stream and keep a rolling buffer
// of the most recent events. The browser talks to our own /public/shard/stream
// route (plain HTTP EventSource) — never the sidecar's WebSocket — so the token
// stays server-side and it works through any reverse proxy.
//
// EventSource auto-reconnects on drop, so there is no manual retry loop here; a
// `connected` flag is exposed for a small live/offline indicator. `filter` (a
// Set of kinds, optional) limits which events are buffered. `max` caps the
// buffer length.
export function useShardFeed({ url, filter, max = 40 } = {}) {
  const [events, setEvents] = useState([])
  const [connected, setConnected] = useState(false)
  // Keep the latest filter in a ref so re-renders don't tear down the stream.
  const filterRef = useRef(filter)
  filterRef.current = filter
  const streamUrl = url || api.shardStreamUrl

  useEffect(() => {
    // EventSource isn't available during SSR / very old browsers — degrade to
    // "no live feed" rather than throwing.
    if (typeof window === 'undefined' || typeof window.EventSource === 'undefined') return undefined

    const es = new EventSource(streamUrl, { withCredentials: true })

    es.onopen = () => setConnected(true)
    es.onerror = () => setConnected(false) // EventSource will retry on its own

    es.onmessage = (msg) => {
      let event
      try {
        event = JSON.parse(msg.data)
      } catch {
        return
      }
      if (!event || !event.kind) return
      const f = filterRef.current
      if (f && !f.has(event.kind)) return
      setEvents((prev) => {
        // Tag with a stable-ish local id for React keys (events carry t but can
        // collide within a ms) and cap the buffer.
        const next = [{ ...event, _id: `${event.kind}-${event.t}-${prev.length}` }, ...prev]
        return next.slice(0, max)
      })
    }

    return () => es.close()
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [max, streamUrl])

  return { events, connected }
}
