import { fetchEventSource, FetchEventSourceInit, EventSourceMessage } from '@fortaine/fetch-event-source'

export interface SSEOptions extends Omit<FetchEventSourceInit, 'onopen' | 'onmessage' | 'onerror' | 'onclose'> {
  /**
   * 每次接收服务端消息时触发
   */
  onUpdate?: (data: any, event: EventSourceMessage) => void

  /**
   * SSE 正常结束时触发，包含所有已接收数据
   */
  onSuccess?: (data: any) => void

  /**
   * SSE 发生错误时触发
   */
  onError?: (error: any) => void
}

export async function sseRequest(
  url: string,
  options: SSEOptions = {},
  updateTransform?: (data: string) => any,
  successTransform?: (data: any[]) => any
) {
  const { onUpdate, onError, onSuccess, ...rest } = options

  const accumulatedData: string[] = []

  await fetchEventSource(url, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    async onopen(response) {
      if (response.ok) return
      else throw response
    },

    ...rest,

    onmessage: (event) => {
      if (event.data && event.data !== '[DONE]') {
        const data = updateTransform ? updateTransform(event.data) : event.data
        accumulatedData.push(data)
        onUpdate?.(data, event)
      }
    },

    onclose: () => {
      onSuccess?.(successTransform ? successTransform(accumulatedData) : accumulatedData)
    },

    onerror: (err) => {
      onError?.(err)
    },
  })
}
