import i18n from '@/locales'
import { fetchEventSource } from '@microsoft/fetch-event-source'
import { BASE_URLS } from '@/config/base-url'
import { useUserStore } from '@/store/modules/user'
import { useSystemLanguageStore } from '@/store/modules/system-language'
import { languageKeyTransform } from '@/utils/language-key-transform'

interface ResponseData {
  message: string
  reasoningContent: string
  function: {
    displayFormat: PluginDisplayFormatType
    name: string
    result: string
    arguments: string
  }
  knowledgeContentResult: KnowledgeContentResultItem[]
  dbChainResult: DBChainResultItem[]
}

const { t } = i18n.global

const ENV = import.meta.env.VITE_APP_ENV

const EVENT_SOURCE_BASE_URL = `${BASE_URLS[ENV || 'DEV']}`

export function fetchCustomEventSource(config: {
  path: string
  payload: any
  controller: AbortController
  onResponse: (_data: ResponseData) => void
  onRequestError: (err: any) => void
  onError?: (err: any) => void
  onFinally?: () => void
}) {
  const userStore = useUserStore()
  const systemLanguageStore = useSystemLanguageStore()
  let responseError = false

  fetchEventSource(`${EVENT_SOURCE_BASE_URL}${config.path}`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'X-Request-Token': userStore.token || '',
      'x-lang': languageKeyTransform(systemLanguageStore.currentLanguageInfo.key),
    },
    body: JSON.stringify(config.payload || {}),
    signal: config.controller?.signal,
    openWhenHidden: true,
    onmessage: (e) => {
      if (e.data === '[DONE]' && !responseError) {
        config.onFinally && config.onFinally()

        return
      }

      try {
        const data = JSON.parse(e.data)

        if (data.code === -10) {
          window.$message.info(t('common_module.expired_identity'))

          config.onError && config.onError(data)

          userStore.logout()
          return
        }

        if (data.code === -1) {
          responseError = true

          window.$message.error(data.message)
          config.controller?.abort()

          config.onFinally && config.onFinally()
          config.onError && config.onError(data)

          return
        }

        config.onResponse(data)
      } catch (err) {
        config.onRequestError(err)

        config.onFinally && config.onFinally()
      }
    },
    onclose: () => {},
    onerror: (err) => {
      config.onRequestError(err)
      window.$message.error(err.message || '操作失败请重试')
      config.onFinally && config.onFinally()

      throw err
    },
  })
}
