/**
 * 运行记录回放 utils：从持久化的 logs JSON 中还原运行时态数据。
 *
 * 后端 HermesBridgeClient.java 在 SSE 推送的同时，已将所有事件持久化到
 * WorkflowRunNode.logs（JSON 数组）。前端运行记录页从这里还原：
 *   - streamingThinking：拼接所有 THINKING 日志的 message
 *   - toolHistory：从 TOOL_CALL / TOOL_RESULT 按时间顺序配对
 *   - todos：取最后一条 TODO_UPDATE 的 detail（JSON 字符串），兼容数组 / {todos: [...]}
 *   - nonThinkingLogs：过滤掉 THINKING 类型后的日志列表（用于执行日志面板）
 *
 * 这样运行记录页能完整复现编辑器"运行结果"Tab 中除"实时态"外的所有内容。
 */

/**
 * 安全解析 JSON 字符串，失败返回 null。
 */
function parseJson(str) {
  if (!str) return null
  try { return JSON.parse(str) } catch { return null }
}

/**
 * 从日志数组中提取思考过程（THINKING 类型日志的 message 拼接）。
 * @param {string} logsJson 节点的 logs 字段（JSON 字符串）
 * @returns {string} 完整思考过程文本；无则返回空串
 */
export function extractStreamingThinking(logsJson) {
  const logs = parseJson(logsJson)
  if (!Array.isArray(logs)) return ''
  return logs
    .filter(l => l.type === 'THINKING')
    .map(l => l.message || '')
    .join('')
}

/**
 * 从日志数组中还原工具调用历史（按时间顺序的 [{name, argsSummary, result}]）。
 *
 * 配对规则：
 *   - TOOL_CALL 日志：message=toolName，detail=argsSummary
 *   - TOOL_RESULT 日志：message=toolName，detail=resultSummary
 *   - 相邻的 TOOL_CALL → TOOL_RESULT 配对一个完整工具调用
 *   - 若 TOOL_CALL 后跟另一个 TOOL_CALL（无 result），仍作为一条记录入栈，result=null
 *
 * @param {string} logsJson 节点的 logs 字段（JSON 字符串）
 * @returns {Array<{name:string, argsSummary:string, result:string|null}>}
 */
export function extractToolHistory(logsJson) {
  const logs = parseJson(logsJson)
  if (!Array.isArray(logs)) return []
  const history = []
  let pending = null  // 等待 result 的 tool_call
  for (const log of logs) {
    if (log.type === 'TOOL_CALL') {
      // 上一个 tool_call 没 result，直接入栈
      if (pending) {
        history.push(pending)
      }
      pending = {
        name: log.message || '(unknown)',
        argsSummary: log.detail || '',
        result: null,
      }
    } else if (log.type === 'TOOL_RESULT') {
      if (pending) {
        pending.result = log.detail || ''
        history.push(pending)
        pending = null
      } else {
        // 异常：tool_result 无对应 tool_call，作为孤儿记录
        history.push({
          name: log.message || '(unknown)',
          argsSummary: '',
          result: log.detail || '',
        })
      }
    }
  }
  // 兜底：最后一个未配对的 tool_call
  if (pending) {
    history.push(pending)
  }
  // 编辑器实时展示是 unshift 顺序（最新在前），保持一致
  return history.reverse()
}

/**
 * 从日志数组中取最后一条 TODO_UPDATE，解析出 todos 数组。
 * 兼容两种格式：
 *   - 数组：[{content, status, ...}, ...]
 *   - 对象：{todos: [...], summary: {...}}（Hermes 内置 todo_tool 实际返回结构）
 *
 * @param {string} logsJson 节点的 logs 字段（JSON 字符串）
 * @returns {Array} todos 数组；无则返回空数组
 */
export function extractLatestTodos(logsJson) {
  const logs = parseJson(logsJson)
  if (!Array.isArray(logs)) return []
  // 从后往前找第一条 TODO_UPDATE
  for (let i = logs.length - 1; i >= 0; i--) {
    if (logs[i].type === 'TODO_UPDATE') {
      const detail = logs[i].detail || ''
      try {
        const parsed = JSON.parse(detail)
        const arr = Array.isArray(parsed) ? parsed : (parsed?.todos || [])
        return Array.isArray(arr) ? arr : []
      } catch { /* ignore */ }
    }
  }
  return []
}

/**
 * 过滤掉 THINKING 类型日志：思考过程已在 .nrc-thinking 集中展示，
 * 执行日志面板再显示会造成内容重复。
 * @param {string} logsJson 节点的 logs 字段（JSON 字符串）
 * @returns {Array} 非 THINKING 类型的日志数组
 */
export function extractNonThinkingLogs(logsJson) {
  const logs = parseJson(logsJson)
  if (!Array.isArray(logs)) return []
  return logs.filter(l => l.type !== 'THINKING')
}

/**
 * 将节点（来自后端 WorkflowRunNode）转换为编辑器 nodeResults 中的节点格式。
 *
 * 用于让运行记录页直接复用 AgentThinkingPanel 等组件：
 *   - status: 后端返回的是大写（SUCCESS/FAILED/...），转换为小写以匹配组件判断
 *   - streamingThinking / toolHistory / todos 从 logs 还原
 *   - currentStatus / currentTool 留空（节点已完成，无实时态）
 *
 * @param {Object} node 后端 WorkflowRunNode（含 logs / output / contextSnapshot）
 * @returns {Object} 编辑器节点格式
 */
export function buildReplayNode(node) {
  const logsJson = node?.logs || ''
  return {
    nodeId: node?.nodeId,
    type: node?.nodeType,
    label: node?.label || node?.nodeId || '节点',
    status: (node?.status || '').toLowerCase(),
    output: node?.output ? parseJson(node.output) : null,
    logs: extractNonThinkingLogs(logsJson),
    contextSnapshot: node?.contextSnapshot ? parseJson(node.contextSnapshot) : null,
    error: node?.error || '',
    // 从持久化 logs 还原的运行时态
    streamingThinking: extractStreamingThinking(logsJson),
    toolHistory: extractToolHistory(logsJson),
    todos: extractLatestTodos(logsJson),
    // 已完成节点无实时态
    currentStatus: '',
    currentTool: null,
  }
}
