/**
 * 用于处理Coze工作流流式响应的工具函数
 */

/**
 * 处理流式响应
 * @param {Object} response - 从Coze API返回的流式响应
 * @param {Function} onChunk - 处理每个数据块的回调函数
 * @param {Function} onComplete - 处理完成时的回调函数
 * @param {Function} onError - 处理错误的回调函数
 * @returns {Promise<void>}
 */
export const handleStreamResponse = async (response, onChunk, onComplete, onError) => {
  try {
    if (!response || !response.body) {
      throw new Error('无效的流式响应');
    }

    const reader = response.body.getReader();
    const decoder = new TextDecoder();
    let buffer = '';
    let completeData = {};

    // 读取流
    while (true) {
      const { done, value } = await reader.read();
      
      if (done) {
        break;
      }
      
      // 解码二进制数据
      const chunk = decoder.decode(value, { stream: true });
      buffer += chunk;
      
      // 处理收到的数据块
      const lines = buffer.split('\n');
      buffer = lines.pop() || ''; // 最后一行可能是不完整的，保留到下次处理
      
      for (const line of lines) {
        if (line.trim() === '') continue;
        
        try {
          // 尝试解析JSON
          if (line.startsWith('data:')) {
            const data = JSON.parse(line.substring(5).trim());
            
            // 更新完整数据
            completeData = { ...completeData, ...data };
            
            // 调用回调处理数据块
            if (onChunk && typeof onChunk === 'function') {
              onChunk(data);
            }
          }
        } catch (e) {
          console.warn('解析流数据失败:', e, line);
        }
      }
    }
    
    // 处理完成回调
    if (onComplete && typeof onComplete === 'function') {
      onComplete(completeData);
    }
    
    return completeData;
  } catch (error) {
    console.error('处理流式响应失败:', error);
    
    // 错误回调
    if (onError && typeof onError === 'function') {
      onError(error);
    }
    
    throw error;
  }
};

/**
 * 处理音频流式响应
 * @param {Object} response - 从Coze API返回的流式响应
 * @param {Function} onProgress - 处理进度更新的回调函数
 * @param {Function} onComplete - 处理完成时的回调函数，接收音频Blob对象
 * @param {Function} onError - 处理错误的回调函数
 * @returns {Promise<Blob>} 音频Blob对象
 */
export const handleAudioStreamResponse = async (response, onProgress, onComplete, onError) => {
  try {
    let audioBase64 = '';
    let audioMimeType = 'audio/mp3'; // 默认MIME类型
    
    // 处理每个数据块
    await handleStreamResponse(
      response,
      (chunk) => {
        // 音频数据可能会分多个块返回，需要拼接
        if (chunk.audio) {
          audioBase64 += chunk.audio;
        }
        
        // 如果有音频类型信息，更新MIME类型
        if (chunk.audio_type) {
          audioMimeType = chunk.audio_type;
        }
        
        // 如果有进度信息，调用进度回调
        if (chunk.progress && onProgress && typeof onProgress === 'function') {
          onProgress(chunk.progress);
        }
      },
      () => {
        // 流式处理完成，转换Base64为Blob
        if (audioBase64) {
          const audioBlob = base64ToBlob(audioBase64, audioMimeType);
          
          // 完成回调
          if (onComplete && typeof onComplete === 'function') {
            onComplete(audioBlob);
          }
          
          return audioBlob;
        }
      },
      onError
    );
    
    // 如果有音频数据，返回Blob对象
    if (audioBase64) {
      return base64ToBlob(audioBase64, audioMimeType);
    }
    
    throw new Error('未接收到任何音频数据');
  } catch (error) {
    console.error('处理音频流式响应失败:', error);
    
    // 错误回调
    if (onError && typeof onError === 'function') {
      onError(error);
    }
    
    throw error;
  }
};

/**
 * 处理文本流式响应
 * @param {Object} response - 从Coze API返回的流式响应
 * @param {Function} onToken - 处理每个文本token的回调函数
 * @param {Function} onComplete - 处理完成时的回调函数，接收完整文本
 * @param {Function} onError - 处理错误的回调函数
 * @returns {Promise<string>} 完整的文本结果
 */
export const handleTextStreamResponse = async (response, onToken, onComplete, onError) => {
  try {
    let fullText = '';
    
    // 处理每个数据块
    await handleStreamResponse(
      response,
      (chunk) => {
        // 如果有文本数据
        if (chunk.text) {
          fullText += chunk.text;
          
          // 调用token回调
          if (onToken && typeof onToken === 'function') {
            onToken(chunk.text, fullText);
          }
        }
      },
      () => {
        // 完成回调
        if (onComplete && typeof onComplete === 'function') {
          onComplete(fullText);
        }
        
        return fullText;
      },
      onError
    );
    
    return fullText;
  } catch (error) {
    console.error('处理文本流式响应失败:', error);
    
    // 错误回调
    if (onError && typeof onError === 'function') {
      onError(error);
    }
    
    throw error;
  }
};

/**
 * 将Base64字符串转换为Blob对象
 * @param {string} base64 - Base64编码的字符串
 * @param {string} mimeType - MIME类型
 * @returns {Blob} Blob对象
 */
export const base64ToBlob = (base64, mimeType) => {
  try {
    const byteCharacters = atob(base64);
    const byteArrays = [];
    
    for (let offset = 0; offset < byteCharacters.length; offset += 512) {
      const slice = byteCharacters.slice(offset, offset + 512);
      
      const byteNumbers = new Array(slice.length);
      for (let i = 0; i < slice.length; i++) {
        byteNumbers[i] = slice.charCodeAt(i);
      }
      
      const byteArray = new Uint8Array(byteNumbers);
      byteArrays.push(byteArray);
    }
    
    return new Blob(byteArrays, { type: mimeType });
  } catch (error) {
    console.error('Base64转Blob失败:', error);
    throw error;
  }
};

/**
 * 将Blob对象转换为Base64字符串
 * @param {Blob} blob - Blob对象
 * @returns {Promise<string>} Base64编码的字符串
 */
export const blobToBase64 = (blob) => {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.readAsDataURL(blob);
    reader.onload = () => {
      // 移除数据URL前缀（例如"data:audio/mp3;base64,"）
      const base64 = reader.result.split(',')[1];
      resolve(base64);
    };
    reader.onerror = (error) => reject(error);
  });
}; 