import { makeAutoObservable, runInAction } from "mobx"
import {
  getOnlineInfo,
  startChat,
  deleteMessage,
  interruptChat,
  uploadFile,
} from "@/server/ai"
import { EModalType } from "@/server/type"
import { XStream } from "@ant-design/x"
import { uid } from "uid"
import { BubbleListRef } from "@ant-design/x/es/bubble/BubbleList"
import { createRef } from "react"

interface IBotInfo {
  name: string
  description: string
  suggestedQuestions: string[]
}
class NewChatStore {
  botInfo: IBotInfo | null = null
  conversationID = ""
  isLoading = false
  messageList: any[] = []
  chatId = ""
  controller: AbortController | null = null
  uploading = false
  fileArr: any[] = []
  containerRef = createRef<BubbleListRef>()
  userId = ""
  constructor() {
    makeAutoObservable(this) // 自动将字段和方法转为响应式
  }

  getBotInfo = async () => {
    const res = await getOnlineInfo(EModalType.GENERATE_REPLY)
    runInAction(() => {
      if (res.code === 10000) {
        this.userId = uid(32)
        document.title = res.data.bot.name
        this.botInfo = {
          ...res.data.bot,
          suggestedQuestions:
            res.data.bot.onboarding_info.suggested_questions || [],
        }
      }
    })
  }

  streamingChat = (query: string) => {
    if (this.isLoading) {
      return
    }
    runInAction(() => {
      this.messageList.unshift({
        id: uid(32),
        role: "user",
        content: query,
        file_url: this.fileArr,
      })
      this.messageList.unshift({
        id: uid(32),
        role: "assistant",
        content: "",
        loading: true,
        is_answer: 1,
      })
    })
    this.creatChat(query)
  }
  // 创建一个辅助函数来更新消息内容
  updateMessageContent = (content: string) => {
    runInAction(() => {
      this.messageList[0] = {
        ...this.messageList[0],
        content: content,
        loading: false,
      }
    })
  }

  creatChat = async (query: string, id?: string) => {
    this.controller = new AbortController()
    const fileIds = this.fileArr.map((item) => item.id)
    try {
      runInAction(() => {
        this.isLoading = true
        this.fileArr = []
      })
      const historyMessages = this.messageList
        .filter((val) => val.content !== "")
        .map((item) => {
          return {
            role: item.role,
            content: item.content,
            fileIds:
              item.file_url && item.file_url.length
                ? item.file_url.map((item: any) => item.id)
                : [],
          }
        })
      const response = await startChat(
        {
          conversationId: this.conversationID,
          content: query,
          fileIds,
          id,
          modelEnum: EModalType.GENERATE_REPLY,
          historyMessages,
          userId: this.userId,
        },
        this.controller.signal
      )
      let currentContent = ""
      let chatId = ""
      for await (const part of XStream({
        readableStream: response,
      })) {
        if (this.controller?.signal.aborted) {
          // Check if aborted during iteration
          break
        }
        if (typeof part === "string") {
          continue
        }
        // 去除事件名称前后的空格
        const eventName = part.event?.trim() || ""
        if (
          eventName === "conversation.chat.created" ||
          eventName === "conversation.message.delta" ||
          eventName === "conversation.message.completed"
        ) {
          part.data = JSON.parse(part.data)
        }
        console.log("🔄 SSE Event received:", `"${part.event}"`, "->", `"${eventName}"`, part.data)
        runInAction(() => {
          if (eventName === "conversation.chat.created") {
            this.conversationID = part.data.conversation_id
          } else if (eventName === "conversation.message.delta") {
            currentContent += part.data.content
            chatId = part.data.chat_id
            this.updateMessageContent(currentContent)
            if (chatId && this.chatId !== chatId) {
              this.chatId = chatId
            }
          }
          if (
            eventName === "conversation.chat.failed" ||
            eventName === "error"
          ) {
            if (this.messageList[0].role === "assistant") {
              // 如果内容为空，添加错误消息
              if (!this.messageList[0].content) {
                this.messageList[0].content = "抱歉，请求出错了，请重试。"
              }
              this.messageList[0] = {
                ...this.messageList[0],
                loading: false,
              }
            }
          }
        })
      }
    } catch (error) {
      if ((error as Error).name === "CanceledError") {
        runInAction(() => {
          if (this.messageList[0].role === "assistant") {
            // 如果内容为空，添加错误消息
            if (!this.messageList[0].content) {
              this.messageList[0].content = "会话已中断。"
            }
            this.messageList[0] = {
              ...this.messageList[0],
              loading: false,
            }
          }
        })
      } else {
        console.error("Error during chat stream:", error)
        // 在错误情况下更新UI状态
        runInAction(() => {
          if (this.messageList[0].role === "assistant") {
            // 如果内容为空，添加错误消息
            if (!this.messageList[0].content) {
              this.messageList[0].content = "抱歉，请求出错了，请重试。"
            }
            this.messageList[0] = {
              ...this.messageList[0],
              loading: false,
            }
          }
        })
      }
    } finally {
      this.complateChat()
      this.controller = null
    }
  }

  abortChat = async () => {
    await interruptChat({
      conversationId: this.conversationID,
      chatId: this.chatId,
      modelEnum: EModalType.GENERATE_REPLY,
    })
    this.controller?.abort()
    this.complateChat()
  }

  complateChat = () => {
    runInAction(() => {
      this.isLoading = false
      if (this.messageList[0] && this.messageList[0].is_answer) {
        this.messageList[0] = {
          ...this.messageList[0],
          is_answer: 0,
        }
      }
    })
  }

  deleteMessage = async (id: string) => {
    const res = await deleteMessage(id)
    if (res.code === 10000) {
      runInAction(() => {
        if (this.messageList.length > 0) {
          this.messageList = this.messageList.filter((item) => item.id !== id)
        }
      })
    }
  }

  reGenerate = () => {
    const content = this.messageList[1]?.content
    const chatId = this.chatId || this.messageList[0]?.chat_id
    this.messageList[0] = {
      id: uid(32),
      role: "assistant",
      content: "",
      loading: true,
      is_answer: 1,
    }
    this.creatChat(content, chatId)
  }

  getBase64(img: any, callback: any) {
    const reader = new FileReader()
    reader.addEventListener("load", () => callback(reader.result))
    reader.readAsDataURL(img)
  }

  onRemoveFile = (fileId: string) => {
    const fileList = this.fileArr.filter((file: any) => file.id !== fileId)
    this.fileArr = fileList
  }

  handleUploadFile = async (file?: any) => {
    if (!file) {
      this.fileArr = []
      return
    }
    const formData = new FormData()
    formData.append("file", file)
    formData.append("modelEnum", EModalType.GENERATE_REPLY)
    this.uploading = true
    const res = await uploadFile(formData)
    runInAction(() => {
      if (res.code === 10000) {
        this.getBase64(file, (url: any) => {
          runInAction(() => {
            this.fileArr.push({
              id: res.data,
              name: file.name,
              path: url,
            })
          })
        })
      }
      this.uploading = false
    })
  }

  scrollToBottom = () => {
    requestAnimationFrame(() => {
      this.containerRef.current?.scrollTo({
        offset: this.containerRef.current?.nativeElement.scrollHeight + 100,
        block: "nearest",
        behavior: "smooth",
      })
    })
  }
}
export default new NewChatStore()
