/*
 * @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
  })
}

/**
 * 解析SSE事件 - 优化版
 * 正确处理多行data和事件类型
 */
function parseSseEvents(buffer) {
  const events = []
  const lines = buffer.split(/\r?\n/)
  let currentEvent = null
  let currentData = []
  let remaining = []
  let i = 0
  
  for (; i < lines.length; i++) {
    const line = lines[i]
    
    // 空行表示事件结束
    if (line === '') {
      if (currentData.length > 0) {
        const data = currentData.join('\n')
        events.push({
          event: currentEvent || 'message',
          data: data
        })
        currentEvent = null
        currentData = []
      }
      continue
    }
    
    // 解析事件类型
    if (line.startsWith('event:')) {
      currentEvent = line.slice(6).trim()
      continue
    }
    
    // 解析数据行
    if (line.startsWith('data:')) {
      const dataValue = line.slice(5).trimStart()
      currentData.push(dataValue)
      continue
    }
  }
  
  // 保存剩余未完成的数据
  if (i < lines.length) {
    remaining = lines.slice(i).join('\n')
  } else if (currentData.length > 0) {
    // 如果最后没有空行，但数据已完整，也要保留
    remaining = lines.slice(i - currentData.length - (currentEvent ? 1 : 0)).join('\n')
  } else {
    remaining = ''
  }
  
  return { events, rest: remaining }
}

/**
 * 规范化SSE数据
 */
function normalizeSseData(data) {
  if (data == null) return ''
  let s = String(data)
  // 移除可能的 "data:" 前缀
  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
}

/**
 * 流式请求SSE - 优化版
 * @param {string} url - 请求URL
 * @param {Function} onMessage - 收到消息时的回调，接收解析后的JSON对象和事件类型
 * @param {Function} onError - 错误回调
 * @param {Function} onComplete - 完成回调
 * @returns {AbortController} 用于取消请求的控制器
 */
function streamFetchSse(url, onMessage, onError, onComplete) {
  const controller = new AbortController()

  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 })
        
        // 解析SSE事件
        const { events, rest } = parseSseEvents(buffer)
        buffer = rest

        for (const event of events) {
          const normalizedData = normalizeSseData(event.data)
          
          // 检查是否结束
          if (normalizedData === '[DONE]') {
            onComplete && onComplete()
            controller.abort()
            return
          }
          
          try {
            const jsonData = JSON.parse(normalizedData)
            // 根据事件名称分发，传递JSON对象和事件类型
            onMessage && onMessage(jsonData, event.event)
          } catch (e) {
            console.warn('解析JSON失败，作为普通文本处理:', normalizedData)
            onMessage && onMessage({ content: normalizedData }, event.event)
          }
        }
      }
      
      onComplete && onComplete()
    })
    .catch((error) => {
      if (error.name === 'AbortError') {
        console.log('请求已取消')
        return
      }
      console.error('流式请求错误:', error)
      onError && onError(error)
    })

  return controller
}

/**
 * 流式回答API（SSE）
 * @param {Object} params - 参数对象
 * @param {string} params.topicId - 话题ID
 * @param {string} params.question - 问题
 * @param {Function} onMessage - 收到消息时的回调，接收参数：(jsonData, eventType)
 *                              - jsonData: 解析后的JSON对象，包含content、tokenUsage等字段
 *                              - eventType: 事件类型（如'answer'、'error'、'completed'）
 * @param {Function} onError - 错误回调
 * @param {Function} onComplete - 完成回调
 * @returns {AbortController} 用于取消请求的控制器
 */
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（带文档）
 * @param {Object} params - 参数对象
 * @param {string} params.topicId - 话题ID
 * @param {string} params.chatId - 聊天ID
 * @param {string} params.question - 问题
 * @param {Function} onMessage - 收到消息时的回调，接收参数：(jsonData, eventType)
 *                              - jsonData: 解析后的JSON对象，包含content、tokenUsage等字段
 *                              - eventType: 事件类型（如'answer'、'error'、'completed'）
 * @param {Function} onError - 错误回调
 * @param {Function} onComplete - 完成回调
 * @returns {AbortController} 用于取消请求的控制器
 */
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)
}
