/*
 * @Author: wrh
 * @Date: 2025-04-08 14:23:04
 * @LastEditors: wrh
 * @LastEditTime: 2026-03-11 10:29:17
 */
import request from '@/utils/request'
import { getToken } from '@/utils/auth'

// 查询cmc聊天记录详细
export function getAnswer(question) {
  return request({
    url: '/llm/session/answer',
    method: 'get',
    params: question
  })
}

// 查询cmc聊天记录详细
export function getAnswerWithDocument(question) {
  return request({
    url: '/llm/session/answerWithDocument',
    method: 'get',
    params: question
  })
}

function parseSseEvents(buffer) {
  // SSE 事件以空行分隔：\n\n（兼容 \r\n）
  const events = []
  const normalized = buffer.replace(/\r\n/g, '\n')
  const parts = normalized.split('\n\n')
  // 最后一段可能是不完整事件，留给下次拼接
  const rest = parts.pop() ?? ''

  for (const part of parts) {
    if (!part.trim()) continue
    const lines = part.split('\n')
    const dataLines = []
    for (const line of lines) {
      if (line.startsWith('data:')) {
        dataLines.push(line.slice(5).trimStart())
      }
    }
    const data = dataLines.join('\n')
    if (data !== '') events.push(data)
  }

  return { events, rest }
}

function normalizeSseData(data) {
  if (data == null) return ''
  let s = String(data)
  // 有些后端会把 payload 自己也带上 "data:"，这里做兼容剥离
  // 例如：data:data: xxx  ->  xxx
  while (s.startsWith('data:')) {
    s = s.slice(5)
    if (s.startsWith(' ')) s = s.slice(1)
  }
  return s
}

function stripToolCallStream(text, state) {
  if (!text) return ''
  const s = String(text)
  let i = 0
  let out = ''
  while (i < s.length) {
    if (!state.inToolCall) {
      const start = s.indexOf('<tool_call>', i)
      if (start === -1) {
        out += s.slice(i)
        break
      }
      out += s.slice(i, start)
      state.inToolCall = true
      i = start + '<tool_call>'.length
    } else {
      const end = s.indexOf('</tool_call>', i)
      if (end === -1) {
        // 剩余都在 tool_call 内，丢弃
        return out
      }
      state.inToolCall = false
      i = end + '</tool_call>'.length
    }
  }
  return out
}

function streamFetchSse(url, onMessage, onError, onComplete) {
  const controller = new AbortController()
  const toolCallState = { inToolCall: false }
  fetch(url, {
    method: 'GET',
    headers: {
      'Authorization': 'Bearer ' + getToken(),
      'Accept': 'text/event-stream',
      'Cache-Control': 'no-cache'
    },
    signal: controller.signal
  })
    .then(async (response) => {
      if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`)
      if (!response.body) throw new Error('ReadableStream not supported')

      const reader = response.body.getReader()
      const decoder = new TextDecoder('utf-8')
      let buffer = ''

      while (true) {
        const { done, value } = await reader.read()
        if (done) break

        buffer += decoder.decode(value, { stream: true })
        const parsed = parseSseEvents(buffer)
        buffer = parsed.rest

        for (const data of parsed.events) {
          const normalized = normalizeSseData(data)
          if (normalized === '[DONE]') {
            onComplete()
            controller.abort()
            return
          }
          const visible = stripToolCallStream(normalized, toolCallState)
          if (visible !== '') onMessage(visible)
        }
      }

      // 兜底：流结束但没收到 [DONE]
      if (buffer.trim()) {
        const parsed = parseSseEvents(buffer + '\n\n')
        for (const data of parsed.events) {
          const normalized = normalizeSseData(data)
          if (normalized !== '' && normalized !== '[DONE]') {
            const visible = stripToolCallStream(normalized, toolCallState)
            if (visible !== '') onMessage(visible)
          }
        }
      }
      onComplete()
    })
    .catch((error) => {
      if (error.name === 'AbortError') return
      console.error('流式请求错误:', error)
      onError(error)
    })

  return controller
}

// 流式回答API（SSE）
export function getAnswerStream(params, onMessage, onError, onComplete) {
  const baseURL = process.env.VUE_APP_BASE_API
  const url = `${baseURL}/llm/session/answer?topicId=${params.topicId}&question=${encodeURIComponent(params.question)}`
  return streamFetchSse(url, onMessage, onError, onComplete)
}

// 流式回答API（带文档）- 简化版
export function getAnswerWithDocumentStream(params, onMessage, onError, onComplete) {
  const baseURL = process.env.VUE_APP_BASE_API
  const url = `${baseURL}/llm/session/answerWithDocument?topicId=${params.topicId}&chatId=${params.chatId}&question=${encodeURIComponent(params.question)}`
  return streamFetchSse(url, onMessage, onError, onComplete)
}