import chatApi, { Session } from '@/api/chat'
import { defineStore } from 'pinia'
import { getTimeText } from '@/utils'
import { XMessage } from '@/hooks'

const SERVER_URL = import.meta.env.VITE_SERVER_URL

let controller: AbortController | null = null

export const useChatStore = defineStore('chat', () => {
  // 故意在左右两边留空格
  const defaultSessionTitle = ' 新的会话 '
  // 发送状态
  const sending = ref(true)

  // 判断数组是否有内容，一定要用x.value.length
  const sessions = ref<Session[]>([]) // 会话列表
  const currentSession = ref<Session>({} as Session) // 当前会话

  /**
   * 获得会话列表
   */
  const getSessions = async () => {
    sending.value = true
    sessions.value = await chatApi.getSessionsApi()
    sending.value = false

    if (sessions.value.length) {
      setCurrentSession(sessions.value[0])
    } else {
      setCurrentSession({} as Session)
    }
  }

  /**
   * 设置当前对话
   */
  const setCurrentSession = (session: Session) => {
    if (sending.value) return
    if (currentSession.value.id === session.id && !session.messages?.length) {
      // id相同，且新数据的消息列表为空
      session.messages = currentSession.value.messages
    }
    currentSession.value = session
  }

  /**
   * 添加新的会话
   */
  const addNewSession = async () => {
    if (sessions.value.length && sessions.value[0].local) {
      XMessage.error('已经有新的会话')
      return
    }

    const time = getTimeText()
    currentSession.value = {
      id: time,
      title: defaultSessionTitle,
      updateTime: time,
      num: 0,
      local: true,
      messages: [],
    }
    sessions.value = [currentSession.value, ...sessions.value]
  }

  /**
   * 添加用户消息
   */
  const addUserMessage = (content: string) => {
    const time = getTimeText()
    currentSession.value.messages?.push({
      id: time,
      role: 'user',
      content,
      createTime: time,
    })
    currentSession.value.num = currentSession.value.messages?.length as number
    // 没有标题或是默认标题时，才设置标题
    const title = currentSession.value.title
    if (!title || title === defaultSessionTitle) {
      currentSession.value.title = content
    }
  }

  /**
   * 添加AI消息
   */
  const addAIMessage = () => {
    const time = getTimeText()
    currentSession.value.messages?.push({
      id: time,
      role: 'ai',
      content: '正在思考中...',
      createTime: time,
    })
    currentSession.value.num = currentSession.value.messages?.length as number
  }

  /** 发送消息给ai */
  const sendMessage = async (content: string) => {
    if (sending.value) return

    // 对不合理内容的过滤
    content = content.trim()
    if (!content) {
      XMessage.error('请输入有效的内容')
      return
    }

    // 停止上一次的发送
    stopMessage()
    // 用来禁止这一次的请求
    controller = new AbortController()

    // 正在发送中
    sending.value = true

    // 先在屏幕上显示消息
    addUserMessage(content)
    addAIMessage()

    await chatApi.postChats({
      url: `${SERVER_URL}/chats`,
      data: {
        content: content,
        sessionId: currentSession.value.local ? undefined : currentSession.value.id,
      },
      controller,
      onMessage: (reasoning, content) => {
        if (!currentSession.value.messages?.length) return
        // 更新消息
        const idx = currentSession.value.messages.length - 1
        currentSession.value.messages[idx].content = content.trim()
        currentSession.value.messages[idx].reasoning = reasoning.trim()
      },
      onOpen: response => {
        if (!currentSession.value.local) return
        // 只更新本地的新会话
        // 更新会话id
        currentSession.value.local = false
        currentSession.value.id = response.headers.get('sessionId') as string
      },
      onError: error => {
        XMessage.error(error)
      },
    })

    // 发送完成
    sending.value = false
    controller = null
  }

  const stopMessage = () => {
    controller?.abort()
    controller = null
    sending.value = false
  }

  const $reset = () => {
    sending.value = false
    sessions.value = []
    currentSession.value = {} as Session
  }

  // 切换对话
  watch(
    // 只监听赋值
    () => currentSession.value,
    async session => {
      if (!session) return
      // 新会话不需要请求消息列表
      if (session.local) return
      sending.value = true
      currentSession.value.messages = await chatApi.getMessagesApi(session.id)
      currentSession.value.num = currentSession.value.messages.length
      sending.value = false
    },
  )

  return {
    sending,
    sessions,
    currentSession,
    getSessions,
    addNewSession,
    setCurrentSession,
    sendMessage,
    stopMessage,
    $reset,
  }
})
