/** 服务端流式返回的数据 **/

// 解析的流式数据格式如下：

/** 
data: data:{"content":"我理解您可能对当前系统的功能范围有些疑问。","contentType":"text/plain","last":false,"payload":{},"role":"assistant"}



data: data:{"content":"让我明确说明一下：\n\n1. 根据系统设定，我确实无法协助完成代码生成相关的任务\n2.","contentType":"text/plain","last":false,"payload":{},"role":"assistant"}



data: data:{"content":" 我的专长领域是提供信息咨询、创意建议和问题解答等非编程类服务\n3. 如果您有任何其他非技术性问题，","contentType":"text/plain","last":false,"payload":{},"role":"assistant"}



data: data:{"content":"比如学习建议、写作指导或日常咨询，我很乐意为您提供帮助\n\n您是否有一些其他方面的问题需要讨论呢？我可以为您推荐更适合的解决方案。","contentType":"text/plain","last":false,"payload":{},"role":"assistant"}



data: data:{"content":"","contentType":"text/plain","last":true,"payload":{"usage":{"completion_tokens":101,"prompt_tokens":28,"total_tokens":129,"web_searched":false}},"role":"assistant"}

data:{"content":{"answer":{"payload":{},"text":"你好，我是饭饭，很高兴你能使用QA"},"qaId":"qa_9605"},"contentType":"aiseek/qa","last":true,"payload":{},"role":"assistant"}

data:{"content":{"audio": "", sentenceBegin: ""},"contentType":"aiseek/audio_chunk","last":true,"payload":{},"role":"assistant"}

// 仅是文本转音频流时的结构
data:{"audio": ""}





data: [DONE]

*/
export interface ICompleteCallback {
  content?: string;
  reasoningContent?: string;
  body?: null| (TJsonMessage & Record<string,any>)
  audio?: string
}

type TContentType = "text/plain" | "aiseek/qa" | 'application/json' | 'aiseek/audio_chunk' | 'aiseek/thinking'  |  'aiseek/function_call' | 'aiseek/multimodal'
type TJsonMessage = {contentType: TContentType, content: string | any, reasoningContent: string, audio?: string} 


export default class ChunkParser {
  private buffer: string; // 用于存储未完成的 JSON 字符串
  private complete: (data: ICompleteCallback) => void;
  constructor() {
    this.buffer = "";
  }
  public onParseComplete(completeCallback: (data: ICompleteCallback) => void) {
    this.complete = completeCallback;
  }
  
  // 解析接收到的 chunk
  public parseChunk(
      chunk: string, 
      onParsed: (json: ICompleteCallback) => void,
      onAudioParsed: (m: ICompleteCallback) => void
    ): void {
    // 将新接收到的 chunk 添加到 buffer
    this.buffer += chunk;

    // 按换行符分割字符串
    const lines = this.buffer.split("\n");
    let receivedJsonBody:any = {}
    let audio = '' // todo: audio 是否需要拼接保留？？
    let combinedContentText: string[] = []; // 用于合并 content 字段
    
    // 遍历每一行
    for (let i = 0; i < lines.length; i++) {
      const line = lines[i].trim(); // 去除前后空格
      // 如果行不为空
      if (line) {
        // 如果遇到 DONE，合并并调用 onParsed
        // 同时兼容 "data:[DONE]" 和 "data: [DONE]" 两种格式
        if (line.startsWith("data:")) {
          const dataPayload = line.substring(5).trim();
          if (dataPayload === "[DONE]") {
            if (combinedContentText.length > 0 || audio.length > 0) {
              onParsed({ content: combinedContentText.join("") , body: receivedJsonBody});
            }
            this.complete({ content: combinedContentText.join(""), body: receivedJsonBody });
            this.buffer = "";
            return;
          }
        }
        // 尝试解析为 json 对象
        try {
          // 处理 data: data: 前缀
          if (line.startsWith("data:")) {
            const jsonStr = line.substring(5).trim(); // 移除 "data:" 前缀并去除空格
            const json: TJsonMessage = JSON.parse(jsonStr);
            receivedJsonBody = json
            // console.log(11111, receivedJsonBody)
            // 文本回复
            if(json.contentType === "text/plain") {
              if (json.content) {
                combinedContentText.push(json.content as string); // 收集 content 字段
              }
            }
            // QA 回复
            else if(json.contentType === "aiseek/qa") {
              if (json.content.answer?.text) {
                combinedContentText.push(json.content.answer.text); // 收集 QA 的 answer 文本
              }
            }
            // 语音回复消息
            else if(json.contentType === "aiseek/audio_chunk"){
              if(json.content?.sentenceBegin?.length){
                combinedContentText.push(json.content.sentenceBegin); // 收集 sentenceBegin 文本
              }
              // 收集 audio base64 格式文本
              if(json.content.audio){
                audio += json.content.audio;
              }
              // 音频流单独处理回调
              // 由于 语音和文本长度是不同步的，只要有语音就要调用一次 onAudioParsed
              if (audio.length >= 0) {
                onAudioParsed({body: json  }); // 合并并输出
              }
            }
            else if(json.audio?.length){
              onAudioParsed(json); // 音频流 base64 片断
            }
          }
        } catch (error) {
          // 如果解析失败，说明当前行不是完整的 JSON（通常是最后一行）
          // 在返回前，先把已成功解析并累计的文本吐出去，避免丢失
          if (combinedContentText.length > 0) {
            onParsed({ content: combinedContentText.join(''),  body: receivedJsonBody  });
          }
          // 将当前行保留在 buffer 中，等待下一个 chunk
          this.buffer = lines.slice(i).join("\n");
          return; // 直接返回，等待下一个 chunk
        }
      }
    }

    // 如果当前 combinedContent有内容合并后 调用  onParsed 
    if (combinedContentText.length > 0) {
      onParsed({ content: combinedContentText.join(''),  body: receivedJsonBody  }); // 合并并输出
    }

    // 清空 buffer
    this.buffer = "";
  }
}
