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

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 = {}, transform?: (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]') {
        try {
          const data = JSON.parse(event.data)
          accumulatedData.push(data)
          onUpdate?.(transform ? transform(accumulatedData) : accumulatedData, event)
        } catch (error) {
          console.error(error)
        }
      }
    },

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

    onerror: (err) => {
      onError?.(err)
      message.error(err.message || '请求失败')
    },
  })
}
