import { describe, expect, it, vi } from 'vitest'
import { missionControlApi } from './missionControl'

class FakeEventSource {
  static instances: FakeEventSource[] = []

  onmessage: ((event: MessageEvent<string>) => void) | null = null
  onerror: (() => void) | null = null
  listeners = new Map<string, Set<(event: MessageEvent<string>) => void>>()

  constructor(public readonly url: string) {
    FakeEventSource.instances.push(this)
  }

  addEventListener(event: string, handler: (event: MessageEvent<string>) => void) {
    const existing = this.listeners.get(event) || new Set()
    existing.add(handler)
    this.listeners.set(event, existing)
  }

  removeEventListener(event: string, handler: (event: MessageEvent<string>) => void) {
    this.listeners.get(event)?.delete(handler)
  }

  close() {}

  emit(event: string, data: unknown) {
    const payload = { data: JSON.stringify(data) } as MessageEvent<string>
    for (const handler of this.listeners.get(event) || []) {
      handler(payload)
    }
  }
}

describe('missionControlApi.subscribeBridgeStatus', () => {
  it('subscribes to the named mission-control SSE event', () => {
    const originalWindow = globalThis.window
    const fakeWindow = {
      EventSource: FakeEventSource as unknown as typeof EventSource,
      location: {
        origin: 'https://explorer.example.org',
      },
    } as Window & typeof globalThis
    // @ts-expect-error test shim
    globalThis.window = fakeWindow

    const onStatus = vi.fn()
    const unsubscribe = missionControlApi.subscribeBridgeStatus(onStatus)
    const instance = FakeEventSource.instances.at(-1)

    expect(instance).toBeTruthy()

    instance?.emit('mission-control', { data: { status: 'operational' } })

    expect(onStatus).toHaveBeenCalledWith({ data: { status: 'operational' } })

    unsubscribe()
    globalThis.window = originalWindow
  })
})
