import { useSseStream } from '@overdeck/deck-ui'
import { useQueryClient } from '@tanstack/react-query'
import { useRef } from 'react'
import { collectorEventsUrl } from '../../lib/collector-client'
import type { Delta, ItemsResponse, StateResponse } from '../../lib/collector-types'
import { mergeCollectorPanel } from '../../lib/collector-state'

/**
 * Bridges the collector's `/events` SSE stream into the React Query cache. Renders
 * nothing — a sibling to OverviewContent so both share the same QueryClient.
 */
export function CollectorRealtimeBridge() {
  const queryClient = useQueryClient()
  const wasConnected = useRef(false)

  useSseStream<Delta>({
    url: collectorEventsUrl(),
    onStatus: (status) => {
      // Deltas emitted during a gap are gone for good — reconnecting without a refetch
      // leaves whatever the cache held before the drop on screen, indefinitely.
      if (status === 'open' && wasConnected.current) {
        void queryClient.invalidateQueries({ queryKey: ['collector-state'] })
        void queryClient.invalidateQueries({ queryKey: ['collector-items'] })
      }
      if (status === 'open') wasConnected.current = true
    },
    onMessage: (delta) => {
      if (delta.type === 'item') {
        queryClient.setQueryData<ItemsResponse>(['collector-items'], (old) => {
          const items = (old?.items ?? []).filter((existing) => existing.id !== delta.item.id)
          items.push(delta.item)
          return { items }
        })
        return
      }
      if (delta.type === 'item-resolved') {
        queryClient.setQueryData<ItemsResponse>(['collector-items'], (old) =>
          old ? { items: old.items.filter((item) => item.id !== delta.id) } : old,
        )
        return
      }
      queryClient.setQueryData<StateResponse>(['collector-state'], (old) => {
        if (!old) return old
        return mergeCollectorPanel(old, delta.panel)
      })
    },
  })

  return null
}
