import { userStore } from '@/stores'
import { fetchEventSource } from '@microsoft/fetch-event-source'
import obj from './obj'
import qs from 'qs'
import sass from './sass'

export type SseConfig = {
  method: 'GET' | 'POST'
  url: string
  onMessage: (message: string) => void
  data?: any
  controller?: AbortController | null
  onOpen?: (response: Response) => void
  onError?: (error: any) => void
  onClose?: () => void
}

export const request = async (config: SseConfig) => {
  const { method, onMessage, data, controller, onOpen, onError, onClose } = config
  let { url } = config

  const user = userStore()
  // 过滤掉 null 和 undefined
  obj.clearNullProps(data)

  // 请求体
  let body = null
  const headers: any = {}
  if (method === 'POST') {
    headers['Content-Type'] = 'application/json'
    if (data) {
      body = JSON.stringify(data)
    }
  } else if (data) {
    let join = '?'
    if (url.indexOf(join) !== -1) {
      // 已经有参数了
      join = '&'
    }
    url = `${url}${join}${qs.stringify(data)}`
  }

  await fetchEventSource(url, {
    method,
    headers: {
      Authorization: user.token,
      'X-Tenant-Id': sass.platform.tenantId,
      ...headers,
    },
    signal: controller?.signal,
    body,
    onopen(response) {
      // 连接成功时触发
      if (response.ok) {
        onOpen && onOpen(response)
        return Promise.resolve()
      } else {
        controller?.abort()
        throw new Error('连接失败')
      }
    },
    onmessage(event) {
      // 接收服务器发送的每条事件
      onMessage(event.data)
    },
    onclose() {
      onClose && onClose()
    },
    onerror(err) {
      onError && onError(err)
      controller?.abort()
    },
  })
}

export const post = async (config: SseConfig) => {
  return await request({
    ...config,
    method: 'POST',
  })
}

export const get = async (config: SseConfig) => {
  return await request({
    ...config,
    method: 'GET',
  })
}
