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

interface AIMessage {
  id: string
  role: string
  content: string
}

interface AIRequestOptions {
  onUpdate?: (content: string, message?: AIMessage) => void
  isReplace?: boolean
}

interface AIRequestData {
  model?: string
  prompt?: string
  messages?: AIMessage[]
}

export function useAI() {
  const messages = ref<AIMessage[]>([])
  const isLoading = ref(false)

  function post(data: AIRequestData, options: AIRequestOptions = {}) {
    const { onUpdate, isReplace = true } = options
    const { model = 'qwen-long', prompt, messages: messagesData, ...rest } = data
    const params = { model, messages: messagesData || [{ role: 'user', content: prompt }], ...rest }
    isLoading.value = true

    return new Promise((resolve, reject) => {
      let content = ''
      fetchEventSource('/api/lab/v1/experiment/qwen/chat', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(params),
        async onopen(response) {
          if (response.ok) {
            return
          } else {
            isLoading.value = false
            reject(response)
          }
        },
        onmessage(res) {
          console.log(res.data)
          if (res.data === '[DONE]') {
            isLoading.value = false
            resolve(content)
            return
          }
          try {
            const message = JSON.parse(res.data)
            const id = message.id
            const messageIndex = messages.value.findIndex((session) => session.id === id)
            content += message?.choices[0]?.delta.content || ''
            content = content.replace(/<think>[\s\S]*?<\/think>/g, '')
            if (isReplace) {
              content = content.replaceAll('\n', '<br/>')
            }
            if (messageIndex === -1) {
              messages.value.push({ id, role: 'assistant', content })
            } else {
              messages.value[messageIndex].content = content
            }
            if (onUpdate) {
              onUpdate(content, messages.value.at(-1))
            }
          } catch (error) {
            console.log(error)
          }
        },
        onerror(err) {
          isLoading.value = false
          reject(err)
        },
      })
    })
  }

  return { messages, post, isLoading }
}
