/**
 * 将 v6.1.2.8 的 run_context.json 转换成按 Round > 步骤 > 数据 组织的图结构
 * v3: 增加 [Q] 和 [SUG] 标识前缀
 */

// 得分提升阈值：与Python代码保持一致
const REQUIRED_SCORE_GAIN = 0.02;

function convertV8ToGraphV2(runContext, searchResults, extractionData) {
  const nodes = {};
  const edges = [];
  const iterations = {};
  extractionData = extractionData || {}; // 默认为空对象

  const o = runContext.o || '原始问题';
  const rounds = runContext.rounds || [];

  // 添加原始问题根节点
  const rootId = 'root_o';
  nodes[rootId] = {
    type: 'root',
    query: o,
    level: 0,
    relevance_score: 1.0,
    strategy: '原始问题',
    iteration: 0,
    is_selected: true
  };

  iterations[0] = [rootId];

  // 处理每一轮
  rounds.forEach((round, roundIndex) => {
    if (round.type === 'initialization') {
      // Round 0: 初始化阶段（新架构）
      const roundNum = 0;
      const roundId = `round_${roundNum}`;

      // 创建 Round 节点
      nodes[roundId] = {
        type: 'round',
        query: `初始化-原始检索query分段`,
        level: roundNum * 10,
        relevance_score: 0,
        strategy: '初始化',
        iteration: roundNum,
        is_selected: true
      };

      edges.push({
        from: rootId,
        to: roundId,
        edge_type: 'root_to_round',
        strategy: '初始化'
      });

      if (!iterations[roundNum * 10]) iterations[roundNum * 10] = [];
      iterations[roundNum * 10].push(roundId);

      // 步骤1: 分段
      if (round.segments && round.segments.length > 0) {
        const segStepId = `step_seg_r${roundNum}`;
        nodes[segStepId] = {
          type: 'step',
          query: `步骤1: 分段 (${round.segments.length}个segment)`,
          level: roundNum * 10 + 1,
          relevance_score: 0,
          strategy: '分段',
          iteration: roundNum,
          is_selected: true
        };

        edges.push({
          from: roundId,
          to: segStepId,
          edge_type: 'round_to_step',
          strategy: '分段'
        });

        iterations[roundNum * 10 + 1] = [segStepId];

        // 为每个 Segment 创建节点
        round.segments.forEach((seg, segIndex) => {
          const segId = `segment_${segIndex}_r${roundNum}`;
          nodes[segId] = {
            type: 'segment',
            query: `[${seg.type}] ${seg.text}`,
            level: roundNum * 10 + 2,
            relevance_score: seg.score || 0,
            evaluationReason: seg.reason || '',
            strategy: seg.type,
            iteration: roundNum,
            is_selected: true,
            segment_type: seg.type,
            domain_index: seg.domain_index,
            domain_type: seg.type  // 新增：让可视化显示类型而不是D0
          };

          edges.push({
            from: segStepId,
            to: segId,
            edge_type: 'step_to_segment',
            strategy: seg.type
          });

          if (!iterations[roundNum * 10 + 2]) iterations[roundNum * 10 + 2] = [];
          iterations[roundNum * 10 + 2].push(segId);

          // 为每个 Word 创建节点
          if (seg.words && seg.words.length > 0) {
            seg.words.forEach((word, wordIndex) => {
              const wordId = `word_${word.text}_seg${segIndex}_${wordIndex}`;
              nodes[wordId] = {
                type: 'word',
                query: word.text,
                level: roundNum * 10 + 3,
                relevance_score: word.score || 0,
                evaluationReason: word.reason || '',
                strategy: 'Word',
                iteration: roundNum,
                is_selected: true
              };

              edges.push({
                from: segId,
                to: wordId,
                edge_type: 'segment_to_word',
                strategy: 'Word'
              });

              if (!iterations[roundNum * 10 + 3]) iterations[roundNum * 10 + 3] = [];
              iterations[roundNum * 10 + 3].push(wordId);
            });
          }
        });
      }

      // 步骤2: 域内组词
      if (round.step2_domain_combinations && round.step2_domain_combinations.length > 0) {
        const combStepId = `step_comb_r${roundNum}`;
        nodes[combStepId] = {
          type: 'step',
          query: `步骤2: 域内组词 (${round.step2_domain_combinations.length}个组合)`,
          level: roundNum * 10 + 1,
          relevance_score: 0,
          strategy: '域内组词',
          iteration: roundNum,
          is_selected: true
        };

        edges.push({
          from: roundId,
          to: combStepId,
          edge_type: 'round_to_step',
          strategy: '域内组词'
        });

        if (!iterations[roundNum * 10 + 1]) iterations[roundNum * 10 + 1] = [];
        iterations[roundNum * 10 + 1].push(combStepId);

        // 为每个域内组合创建节点
        round.step2_domain_combinations.forEach((comb, combIndex) => {
          const combId = `comb_${comb.text}_r${roundNum}_${combIndex}`;
          const sourceWordsStr = comb.source_words ? comb.source_words.map(words => words.join(',')).join(' + ') : '';

          nodes[combId] = {
            type: 'domain_combination',
            query: `${comb.text} ${comb.type_label}`,
            level: roundNum * 10 + 2,
            relevance_score: comb.score || 0,
            evaluationReason: comb.reason || '',
            strategy: '域内组合',
            iteration: roundNum,
            is_selected: true,
            type_label: comb.type_label,
            source_words: comb.source_words,
            source_segment: comb.source_segment,
            domain_index: comb.domain_index
          };

          edges.push({
            from: combStepId,
            to: combId,
            edge_type: 'step_to_comb',
            strategy: '域内组合'
          });

          if (!iterations[roundNum * 10 + 2]) iterations[roundNum * 10 + 2] = [];
          iterations[roundNum * 10 + 2].push(combId);
        });
      }

    } else {
      // 普通轮次
      const roundNum = round.round_num;
      const roundId = `round_${roundNum}`;

      // 创建 Round 节点
      nodes[roundId] = {
        type: 'round',
        query: `第${roundNum}轮递归-扩展检索词&搜索`,
        level: roundNum * 10, // 使用10的倍数作为层级
        relevance_score: 0,
        strategy: `第${roundNum}轮`,
        iteration: roundNum,
        is_selected: true
      };

      edges.push({
        from: rootId,
        to: roundId,
        edge_type: 'root_to_round',
        strategy: `第${roundNum}轮`
      });

      if (!iterations[roundNum * 10]) iterations[roundNum * 10] = [];
      iterations[roundNum * 10].push(roundId);

      // 步骤1: 请求&评估推荐词
      if (round.sug_details && Object.keys(round.sug_details).length > 0) {
        const sugStepId = `step_sug_r${roundNum}`;
        const totalSugs = Object.values(round.sug_details).reduce((sum, list) => sum + list.length, 0);

        nodes[sugStepId] = {
          type: 'step',
          query: `步骤1: 请求&评估推荐词 (${totalSugs}个)`,
          level: roundNum * 10 + 1,
          relevance_score: 0,
          strategy: '请求&评估推荐词',
          iteration: roundNum,
          is_selected: true
        };

        edges.push({
          from: roundId,
          to: sugStepId,
          edge_type: 'round_to_step',
          strategy: '推荐词'
        });

        iterations[roundNum * 10].push(sugStepId);

        // 为每个 Q 创建节点
        Object.keys(round.sug_details).forEach((qText, qIndex) => {
          // 从q_list_1中查找对应的q获取分数和理由
          // Round 0: 从q_list_1查找; Round 1+: 从input_queries查找
          let qData = {};
          if (roundNum === 0) {
            qData = round.q_list_1?.find(q => q.text === qText) || {};
          } else {
            // 从当前轮的input_queries中查找
            qData = round.input_queries?.find(q => q.text === qText) || {};
          }
          const qId = `q_${qText}_r${roundNum}_${qIndex}`;
          nodes[qId] = {
            type: 'q',
            query: '[Q] ' + qText,
            level: roundNum * 10 + 2,
            relevance_score: qData.score || 0,
            evaluationReason: qData.reason || '',
            strategy: 'Query',
            iteration: roundNum,
            is_selected: true,
            type_label: qData.type_label || qData.typeLabel || '',
            domain_index: qData.domain_index,
            domain_type: qData.domain_type || ''
          };

          edges.push({
            from: sugStepId,
            to: qId,
            edge_type: 'step_to_q',
            strategy: 'Query'
          });

          if (!iterations[roundNum * 10 + 2]) iterations[roundNum * 10 + 2] = [];
          iterations[roundNum * 10 + 2].push(qId);

          // 为每个 Q 的 sug 创建节点
          const sugs = round.sug_details[qText] || [];
          const qScore = qData.score || 0;  // 获取父Q的得分

          sugs.forEach((sug, sugIndex) => {
            const sugScore = sug.score || 0;
            // 比较得分决定颜色：SUG得分 >= Q得分 + 0.05 → 绿色，否则 → 红色
            const scoreColor = (sugScore >= qScore + REQUIRED_SCORE_GAIN) ? '#22c55e' : '#ef4444';

            const sugId = `sug_${sug.text}_r${roundNum}_q${qIndex}_${sugIndex}`;
            nodes[sugId] = {
              type: 'sug',
              query: '[SUG] ' + sug.text,
              level: roundNum * 10 + 3,
              relevance_score: sugScore,
              evaluationReason: sug.reason || '',
              strategy: '推荐词',
              iteration: roundNum,
              is_selected: true,
              scoreColor: scoreColor,  // 新增：用于控制文字颜色
              parentQScore: qScore     // 新增：保存父Q得分用于调试
            };

            edges.push({
              from: qId,
              to: sugId,
              edge_type: 'q_to_sug',
              strategy: '推荐词'
            });

            if (!iterations[roundNum * 10 + 3]) iterations[roundNum * 10 + 3] = [];
            iterations[roundNum * 10 + 3].push(sugId);
          });
        });
      }

      // 步骤2: 域内组词（Round 1+）
      // 兼容旧字段名 domain_combinations_top10
      const domainCombinations = round.domain_combinations || round.domain_combinations_top10 || [];
      if (domainCombinations.length > 0) {
        const combStepId = `step_comb_r${roundNum}`;
        nodes[combStepId] = {
          type: 'step',
          query: roundNum === 1
            ? `步骤2: 域内组合 (${domainCombinations.length}个组合)`
            : `步骤2: 跨${roundNum}个域组合 (${domainCombinations.length}个组合)`,
          level: roundNum * 10 + 1,
          relevance_score: 0,
          strategy: '域内组词',
          iteration: roundNum,
          is_selected: true
        };

        edges.push({
          from: roundId,
          to: combStepId,
          edge_type: 'round_to_step',
          strategy: '域内组词'
        });

        iterations[roundNum * 10].push(combStepId);

        // 为每个域内组合创建节点
        domainCombinations.forEach((comb, combIndex) => {
          const combId = `comb_${comb.text}_r${roundNum}_${combIndex}`;
          const domainsStr = comb.domains ? comb.domains.map(d => `D${d}`).join(',') : '';
          const wordDetails = comb.source_word_details || [];
          const isAboveSources = comb.is_above_source_scores || false;
          const scoreColor = wordDetails.length > 0
            ? (isAboveSources ? '#22c55e' : '#ef4444')
            : null;

          nodes[combId] = {
            type: 'domain_combination',
            query: `${comb.text}`,  // 移除 type_label，稍后在UI中单独显示
            level: roundNum * 10 + 2,
            relevance_score: comb.score || 0,
            evaluationReason: comb.reason || '',
            strategy: '域内组合',
            iteration: roundNum,
            is_selected: true,
            type_label: comb.type_label || '',
            source_words: comb.source_words || [],
            from_segments: comb.from_segments || [],
            domains: comb.domains || [],
            domains_str: domainsStr,
            source_word_details: wordDetails,
            source_scores: comb.source_scores || [],
            is_above_sources: isAboveSources,
            max_source_score: comb.max_source_score ?? null,
            scoreColor: scoreColor
          };

          edges.push({
            from: combStepId,
            to: combId,
            edge_type: 'step_to_comb',
            strategy: '域内组合'
          });

          if (!iterations[roundNum * 10 + 2]) iterations[roundNum * 10 + 2] = [];
          iterations[roundNum * 10 + 2].push(combId);
        });
      }

      // 步骤3: 筛选并执行搜索
      const searchStepId = `step_search_r${roundNum}`;
      const searchCountText = round.search_count > 0
        ? `筛选${round.high_score_sug_count}个高分词，搜索${round.search_count}次，${round.total_posts}个帖子`
        : `无高分推荐词，未执行搜索`;

      nodes[searchStepId] = {
        type: 'step',
        query: `步骤3: 筛选并执行搜索 (${searchCountText})`,
        level: roundNum * 10 + 1,
        relevance_score: 0,
        strategy: '筛选并执行搜索',
        iteration: roundNum,
        is_selected: true
      };

      edges.push({
        from: roundId,
        to: searchStepId,
        edge_type: 'round_to_step',
        strategy: '搜索'
      });

      iterations[roundNum * 10].push(searchStepId);

      // 只有在有搜索结果时才添加搜索词和帖子
      // 优先使用 round.search_results（新格式），否则使用外部传入的 searchResults（兼容旧版本）
      const roundSearchResults = round.search_results || searchResults;
      if (round.search_count > 0 && roundSearchResults) {
        if (Array.isArray(roundSearchResults)) {
          roundSearchResults.forEach((search, searchIndex) => {
            const searchWordId = `search_${search.text}_r${roundNum}_${searchIndex}`;
            nodes[searchWordId] = {
              type: 'search_word',
              query: '[SEARCH] ' + search.text,
              level: roundNum * 10 + 2,
              relevance_score: search.score_with_o || 0,
              strategy: '搜索词',
              iteration: roundNum,
              is_selected: true
            };

            edges.push({
              from: searchStepId,
              to: searchWordId,
              edge_type: 'step_to_search_word',
              strategy: '搜索词'
            });

            if (!iterations[roundNum * 10 + 2]) iterations[roundNum * 10 + 2] = [];
            iterations[roundNum * 10 + 2].push(searchWordId);

            // 添加帖子
            if (search.post_list && search.post_list.length > 0) {
              search.post_list.forEach((post, postIndex) => {
                const postId = `post_${post.note_id}_${searchIndex}_${postIndex}`;

                // 准备图片列表，将URL字符串转换为对象格式供轮播图使用
                const imageList = (post.images || []).map(url => ({
                  image_url: url
                }));

                nodes[postId] = {
                  type: 'post',
                  query: '[R] ' + post.title,
                  level: roundNum * 10 + 3,
                  relevance_score: 0,
                  strategy: '帖子',
                  iteration: roundNum,
                  is_selected: true,
                  note_id: post.note_id,
                  note_url: post.note_url,
                  body_text: post.body_text || '',
                  images: post.images || [],
                  image_list: imageList,
                  interact_info: post.interact_info || {},
                  // 附加多模态提取数据
                  extraction: extractionData && extractionData[post.note_id] ? extractionData[post.note_id] : null,
                  // 评估数据 (V2)
                  is_knowledge: post.is_knowledge !== undefined ? post.is_knowledge : null,
                  knowledge_reason: post.knowledge_reason || '',
                  knowledge_score: post.knowledge_score !== undefined ? post.knowledge_score : null,
                  knowledge_level: post.knowledge_level !== undefined ? post.knowledge_level : null,
                  knowledge_evaluation: post.knowledge_evaluation || null,

                  post_relevance_score: post.relevance_score !== undefined ? post.relevance_score : null,
                  relevance_level: post.relevance_level || '',
                  relevance_reason: post.relevance_reason || '',
                  relevance_conclusion: post.relevance_conclusion || '',
                  relevance_evaluation: post.relevance_evaluation || null,

                  // 评估数据 (V3)
                  is_content_knowledge: post.is_content_knowledge !== undefined ? post.is_content_knowledge : null,
                  purpose_score: post.purpose_score !== undefined ? post.purpose_score : null,
                  category_score: post.category_score !== undefined ? post.category_score : null,
                  final_score: post.final_score !== undefined ? post.final_score : null,
                  match_level: post.match_level || '',
                  evaluator_version: post.evaluator_version || '',
                  content_knowledge_evaluation: post.content_knowledge_evaluation || null,
                  purpose_evaluation: post.purpose_evaluation || null,
                  category_evaluation: post.category_evaluation || null
                };

                edges.push({
                  from: searchWordId,
                  to: postId,
                  edge_type: 'search_word_to_post',
                  strategy: '搜索结果'
                });

                // 如果有提取数据，创建对应的分析节点
                if (extractionData && extractionData[post.note_id]) {
                  const analysisId = `analysis_${post.note_id}_${searchIndex}_${postIndex}`;

                  nodes[analysisId] = {
                    type: 'analysis',
                    query: '[AI分析] ' + post.title,
                    level: roundNum * 10 + 4,
                    relevance_score: 0,
                    strategy: 'AI分析',
                    iteration: roundNum,
                    is_selected: true,
                    note_id: post.note_id,
                    note_url: post.note_url,
                    title: post.title,
                    body_text: post.body_text || '',
                    interact_info: post.interact_info || {},
                    extraction: extractionData[post.note_id],
                    image_list: imageList
                  };

                  edges.push({
                    from: postId,
                    to: analysisId,
                    edge_type: 'post_to_analysis',
                    strategy: 'AI分析'
                  });

                  if (!iterations[roundNum * 10 + 4]) iterations[roundNum * 10 + 4] = [];
                  iterations[roundNum * 10 + 4].push(analysisId);
                }

                if (!iterations[roundNum * 10 + 3]) iterations[roundNum * 10 + 3] = [];
                iterations[roundNum * 10 + 3].push(postId);
              });
            }
          });
        }
      }

      // 步骤3: 加词生成新查询
      if (round.add_word_details && Object.keys(round.add_word_details).length > 0) {
        const addWordStepId = `step_add_r${roundNum}`;
        const totalAddWords = Object.values(round.add_word_details).reduce((sum, list) => sum + list.length, 0);

        nodes[addWordStepId] = {
          type: 'step',
          query: `步骤3: 加词生成新查询 (${totalAddWords}个)`,
          level: roundNum * 10 + 1,
          relevance_score: 0,
          strategy: '加词生成新查询',
          iteration: roundNum,
          is_selected: true
        };

        edges.push({
          from: roundId,
          to: addWordStepId,
          edge_type: 'round_to_step',
          strategy: '加词'
        });

        iterations[roundNum * 10].push(addWordStepId);

        // 为每个 Seed 创建节点
        Object.keys(round.add_word_details).forEach((seedText, seedIndex) => {
          const seedId = `seed_${seedText}_r${roundNum}_${seedIndex}`;

          // 查找seed的来源信息和分数 - 动态从正确的轮次查找
          let seedInfo = {};
          if (roundNum === 1) {
            // Round 1：种子来自 Round 0 的 seed_list
            const round0 = rounds.find(r => r.round_num === 0 || r.type === 'initialization');
            seedInfo = round0?.seed_list?.find(s => s.text === seedText) || {};
          } else {
            // Round 2+：种子来自前一轮的 seed_list_next
            const prevRound = rounds.find(r => r.round_num === roundNum - 1);
            seedInfo = prevRound?.seed_list_next?.find(s => s.text === seedText) || {};
          }
          const fromType = seedInfo.from_type || seedInfo.from || 'unknown';

          // 根据来源设置strategy
          let strategy;
          if (fromType === 'seg') {
            strategy = '初始分词';
          } else if (fromType === 'add') {
            strategy = '加词';
          } else if (fromType === 'sug') {
            strategy = '调用sug';
          } else {
            strategy = 'Seed';  // 默认灰色
          }

          nodes[seedId] = {
            type: 'seed',
            query: seedText,
            level: roundNum * 10 + 2,
            relevance_score: seedInfo.score || 0,  // 从seedInfo读取种子的得分
            strategy: strategy,
            iteration: roundNum,
            is_selected: true
          };

          edges.push({
            from: addWordStepId,
            to: seedId,
            edge_type: 'step_to_seed',
            strategy: 'Seed'
          });

          if (!iterations[roundNum * 10 + 2]) iterations[roundNum * 10 + 2] = [];
          iterations[roundNum * 10 + 2].push(seedId);

          // 为每个 Seed 的组合词创建节点
          const combinedWords = round.add_word_details[seedText] || [];
          combinedWords.forEach((word, wordIndex) => {
            const wordScore = word.score || 0;
            const seedScore = word.seed_score || 0;
            // 比较得分决定颜色：组合词得分 > 种子得分 → 绿色，否则 → 红色
            const scoreColor = wordScore > seedScore ? '#22c55e' : '#ef4444';

            const wordId = `add_${word.text}_r${roundNum}_seed${seedIndex}_${wordIndex}`;
            nodes[wordId] = {
              type: 'add_word',
              query: '[Q] ' + word.text,
              level: roundNum * 10 + 3,
              relevance_score: wordScore,
              evaluationReason: word.reason || '',
              strategy: '加词生成',
              iteration: roundNum,
              is_selected: true,
              selected_word: word.selected_word,
              seed_score: seedScore,  // 原始种子的得分
              scoreColor: scoreColor  // 用于控制文字颜色
            };

            edges.push({
              from: seedId,
              to: wordId,
              edge_type: 'seed_to_add_word',
              strategy: '组合词'
            });

            if (!iterations[roundNum * 10 + 3]) iterations[roundNum * 10 + 3] = [];
            iterations[roundNum * 10 + 3].push(wordId);
          });
        });
      }

      // 步骤4: 筛选推荐词进入下轮
      const filteredSugs = round.output_q_list?.filter(q => q.from === 'sug') || [];
      if (filteredSugs.length > 0) {
        const filterStepId = `step_filter_r${roundNum}`;
        nodes[filterStepId] = {
          type: 'step',
          query: `步骤4: 筛选推荐词进入下轮 (${filteredSugs.length}个)`,
          level: roundNum * 10 + 1,
          relevance_score: 0,
          strategy: '筛选推荐词进入下轮',
          iteration: roundNum,
          is_selected: true
        };

        edges.push({
          from: roundId,
          to: filterStepId,
          edge_type: 'round_to_step',
          strategy: '筛选'
        });

        iterations[roundNum * 10].push(filterStepId);

        // 添加筛选出的sug
        filteredSugs.forEach((sug, sugIndex) => {
          const sugScore = sug.score || 0;

          // 尝试从sug_details中找到这个sug对应的父Q得分
          let parentQScore = 0;
          if (round.sug_details) {
            for (const [qText, sugs] of Object.entries(round.sug_details)) {
              const matchingSug = sugs.find(s => s.text === sug.text);
              if (matchingSug) {
                // 找到父Q的得分
                let qData = {};
                if (roundNum === 0) {
                  qData = round.q_list_1?.find(q => q.text === qText) || {};
                } else {
                  qData = round.input_queries?.find(q => q.text === qText) || {};
                }
                parentQScore = qData.score || 0;
                break;
              }
            }
          }

          // 比较得分决定颜色：SUG得分 > Q得分 → 绿色，否则 → 红色
          const scoreColor = (sugScore >= parentQScore + REQUIRED_SCORE_GAIN) ? '#22c55e' : '#ef4444';

          const sugId = `filtered_sug_${sug.text}_r${roundNum}_${sugIndex}`;
          nodes[sugId] = {
            type: 'filtered_sug',
            query: '[SUG] ' + sug.text,
            level: roundNum * 10 + 2,
            relevance_score: sugScore,
            strategy: '进入下轮',
            iteration: roundNum,
            is_selected: true,
            scoreColor: scoreColor,       // 新增：用于控制文字颜色
            parentQScore: parentQScore    // 新增：保存父Q得分用于调试
          };

          edges.push({
            from: filterStepId,
            to: sugId,
            edge_type: 'step_to_filtered_sug',
            strategy: '进入下轮'
          });

          if (!iterations[roundNum * 10 + 2]) iterations[roundNum * 10 + 2] = [];
          iterations[roundNum * 10 + 2].push(sugId);
        });
      }

      // 步骤4: 构建下一轮（Round 1+）
      const highScoreCombinations = round.high_score_combinations || [];
      const highGainSugs = round.high_gain_sugs || [];
      const nextRoundItems = [...highScoreCombinations, ...highGainSugs];

      if (nextRoundItems.length > 0) {
        const nextRoundStepId = `step_next_round_r${roundNum}`;
        nodes[nextRoundStepId] = {
          type: 'step',
          query: `步骤4: 构建下一轮 (${nextRoundItems.length}个查询)`,
          level: roundNum * 10 + 1,
          relevance_score: 0,
          strategy: '构建下一轮',
          iteration: roundNum,
          is_selected: true
        };

        edges.push({
          from: roundId,
          to: nextRoundStepId,
          edge_type: 'round_to_step',
          strategy: '构建下一轮'
        });

        iterations[roundNum * 10].push(nextRoundStepId);

        // 创建查询节点
        nextRoundItems.forEach((item, index) => {
          const itemId = `next_round_${item.text}_r${roundNum}_${index}`;
          const isSugItem = item.type === 'sug';

          nodes[itemId] = {
            type: 'next_round_item',
            query: '[Q] ' + item.text,
            level: roundNum * 10 + 2,
            relevance_score: item.score || 0,
            strategy: item.type === 'combination' ? '域内组合' : '高增益SUG',
            iteration: roundNum,
            is_selected: true,
            type_label: item.type_label || '',
            item_type: item.type,
            is_suggestion: isSugItem,
            suggestion_label: isSugItem ? '[suggestion]' : ''
          };

          edges.push({
            from: nextRoundStepId,
            to: itemId,
            edge_type: 'step_to_next_round',
            strategy: item.type === 'combination' ? '域内组合' : 'SUG'
          });

          if (!iterations[roundNum * 10 + 2]) iterations[roundNum * 10 + 2] = [];
          iterations[roundNum * 10 + 2].push(itemId);
        });
      }
    }
  });

  return {
    nodes,
    edges,
    iterations
  };
}

/**
 * 简化版转换：专注于query和post的演化
 * - 合并所有query节点（不区分seg/sug/add_word）
 * - 合并相同的帖子节点
 * - 步骤信息放在边上
 * - 隐藏Round/Step节点
 */
function convertV8ToGraphSimplified(runContext, searchResults, extractionData) {
  const mergedNodes = {};
  const edges = [];
  const iterations = {};
  extractionData = extractionData || {}; // 默认为空对象

  const o = runContext.o || '原始问题';
  const rounds = runContext.rounds || [];

  // 添加原始问题根节点
  const rootId = 'root_o';
  mergedNodes[rootId] = {
    type: 'root',
    query: o,
    level: 0,
    relevance_score: 1.0,
    strategy: '原始问题',
    iteration: 0,
    is_selected: true,
    occurrences: [{round: 0, role: 'root', score: 1.0}]
  };
  iterations[0] = [rootId];

  // 用于记录节点之间的演化关系
  const queryEvolution = {}; // {text: {occurrences: [], parentTexts: [], childTexts: []}}
  const postMap = {}; // {note_id: {...}}

  // 第一遍：收集所有query和post
  rounds.forEach((round, roundIndex) => {
    const roundNum = round.round_num || roundIndex;

    if (round.type === 'initialization') {
      // Round 0: 收集分词结果
      (round.q_list_1 || []).forEach(q => {
        if (!queryEvolution[q.text]) {
          queryEvolution[q.text] = {
            occurrences: [],
            parentTexts: new Set([o]), // 来自原始问题
            childTexts: new Set()
          };
        }
        queryEvolution[q.text].occurrences.push({
          round: roundNum,
          role: 'segmentation',
          strategy: '分词',
          score: q.score,
          reason: q.reason,
          type_label: q.type_label || q.typeLabel || ''
        });
      });
    } else {
      // Round 1+

      // 收集sug_details (推荐词)
      Object.entries(round.sug_details || {}).forEach(([parentText, sugs]) => {
        sugs.forEach(sug => {
          if (!queryEvolution[sug.text]) {
            queryEvolution[sug.text] = {
              occurrences: [],
              parentTexts: new Set(),
              childTexts: new Set()
            };
          }
          queryEvolution[sug.text].occurrences.push({
            round: roundNum,
            role: 'sug',
            strategy: '调用sug',
            score: sug.score,
            reason: sug.reason,
            type_label: sug.type_label || sug.typeLabel || ''
          });
          queryEvolution[sug.text].parentTexts.add(parentText);
          if (queryEvolution[parentText]) {
            queryEvolution[parentText].childTexts.add(sug.text);
          }
        });
      });

      // 收集add_word_details (加词结果)
      Object.entries(round.add_word_details || {}).forEach(([seedText, words]) => {
        words.forEach(word => {
          if (!queryEvolution[word.text]) {
            queryEvolution[word.text] = {
              occurrences: [],
              parentTexts: new Set(),
              childTexts: new Set()
            };
          }
          queryEvolution[word.text].occurrences.push({
            round: roundNum,
            role: 'add_word',
            strategy: '加词',
            score: word.score,
            reason: word.reason,
            selectedWord: word.selected_word,
            seedScore: word.seed_score,  // 添加原始种子的得分
            type_label: word.type_label || word.typeLabel || ''
          });
          queryEvolution[word.text].parentTexts.add(seedText);
          if (queryEvolution[seedText]) {
            queryEvolution[seedText].childTexts.add(word.text);
          }
        });
      });

      // 收集搜索结果和帖子
      const roundSearchResults = round.search_results || searchResults;
      if (roundSearchResults && Array.isArray(roundSearchResults)) {
        roundSearchResults.forEach(search => {
          const searchText = search.text;

          // 标记这个query被用于搜索
          if (queryEvolution[searchText]) {
            queryEvolution[searchText].occurrences.push({
              round: roundNum,
              role: 'search',
              strategy: '执行搜索',
              score: search.score_with_o,
              postCount: search.post_list ? search.post_list.length : 0
            });
          }

          // 收集帖子
          if (search.post_list && search.post_list.length > 0) {
            search.post_list.forEach(post => {
              if (!postMap[post.note_id]) {
                postMap[post.note_id] = {
                  ...post,
                  foundByQueries: new Set(),
                  foundInRounds: new Set()
                };
              }
              postMap[post.note_id].foundByQueries.add(searchText);
              postMap[post.note_id].foundInRounds.add(roundNum);

              // 建立query到post的关系
              if (!queryEvolution[searchText].posts) {
                queryEvolution[searchText].posts = new Set();
              }
              queryEvolution[searchText].posts.add(post.note_id);
            });
          }
        });
      }
    }
  });

  // 第二遍：创建合并后的节点
  Object.entries(queryEvolution).forEach(([text, data]) => {
    const nodeId = `query_${text}`;

    // 获取最新的分数
    const latestOccurrence = data.occurrences[data.occurrences.length - 1] || {};
    const hasSearchResults = data.posts && data.posts.size > 0;

    mergedNodes[nodeId] = {
      type: 'query',
      query: '[Q] ' + text,
      level: Math.max(...data.occurrences.map(o => o.round), 0) * 10 + 2,
      relevance_score: latestOccurrence.score || 0,
      evaluationReason: latestOccurrence.reason || '',
      strategy: data.occurrences.map(o => o.strategy).join(' + '),
      primaryStrategy: latestOccurrence.strategy || '未知',  // 添加主要策略字段
      iteration: Math.max(...data.occurrences.map(o => o.round), 0),
      is_selected: true,
      occurrences: data.occurrences,
      hasSearchResults: hasSearchResults,
      postCount: data.posts ? data.posts.size : 0,
      selectedWord: data.occurrences.find(o => o.selectedWord)?.selectedWord || '',
      seed_score: data.occurrences.find(o => o.seedScore)?.seedScore,  // 添加原始种子的得分
      type_label: latestOccurrence.type_label || ''  // 使用最新的 type_label
    };

    // 添加到对应的轮次
    const maxRound = Math.max(...data.occurrences.map(o => o.round), 0);
    const iterKey = maxRound * 10 + 2;
    if (!iterations[iterKey]) iterations[iterKey] = [];
    iterations[iterKey].push(nodeId);
  });

  // 创建帖子节点
  Object.entries(postMap).forEach(([noteId, post]) => {
    const postId = `post_${noteId}`;

    const imageList = (post.images || []).map(url => ({
      image_url: url
    }));

    mergedNodes[postId] = {
      type: 'post',
      query: '[R] ' + post.title,
      level: 100, // 放在最后
      relevance_score: 0,
      strategy: '帖子',
      iteration: Math.max(...Array.from(post.foundInRounds)),
      is_selected: true,
      note_id: post.note_id,
      note_url: post.note_url,
      body_text: post.body_text || '',
      images: post.images || [],
      image_list: imageList,
      interact_info: post.interact_info || {},
      foundByQueries: Array.from(post.foundByQueries),
      foundInRounds: Array.from(post.foundInRounds),
      // 附加多模态提取数据
      extraction: extractionData && extractionData[post.note_id] ? extractionData[post.note_id] : null,
      // 评估数据 (V2)
      is_knowledge: post.is_knowledge !== undefined ? post.is_knowledge : null,
      knowledge_reason: post.knowledge_reason || '',
      post_relevance_score: post.relevance_score !== undefined ? post.relevance_score : null,
      relevance_level: post.relevance_level || '',
      relevance_reason: post.relevance_reason || '',
      // 评估数据 (V3)
      is_content_knowledge: post.is_content_knowledge !== undefined ? post.is_content_knowledge : null,
      purpose_score: post.purpose_score !== undefined ? post.purpose_score : null,
      category_score: post.category_score !== undefined ? post.category_score : null,
      final_score: post.final_score !== undefined ? post.final_score : null,
      match_level: post.match_level || '',
      evaluator_version: post.evaluator_version || '',
      content_knowledge_evaluation: post.content_knowledge_evaluation || null,
      purpose_evaluation: post.purpose_evaluation || null,
      category_evaluation: post.category_evaluation || null
    };

    if (!iterations[100]) iterations[100] = [];
    iterations[100].push(postId);

    // 如果有提取数据，创建对应的分析节点
    if (extractionData && extractionData[post.note_id]) {
      const analysisId = `analysis_${noteId}`;

      mergedNodes[analysisId] = {
        type: 'analysis',
        query: '[AI分析] ' + post.title,
        level: 101,
        relevance_score: 0,
        strategy: 'AI分析',
        iteration: Math.max(...Array.from(post.foundInRounds)),
        is_selected: true,
        note_id: post.note_id,
        note_url: post.note_url,
        title: post.title,
        body_text: post.body_text || '',
        interact_info: post.interact_info || {},
        extraction: extractionData[post.note_id],
        image_list: imageList
      };

      edges.push({
        from: postId,
        to: analysisId,
        edge_type: 'post_to_analysis',
        strategy: 'AI分析',
        label: 'AI分析',
        round: Math.max(...Array.from(post.foundInRounds))
      });

      if (!iterations[101]) iterations[101] = [];
      iterations[101].push(analysisId);
    }
  });

  // 第三遍：创建边
  // 1. 原始问题 -> 分词结果
  Object.entries(queryEvolution).forEach(([text, data]) => {
    const nodeId = `query_${text}`;
    const segOccurrence = data.occurrences.find(o => o.role === 'segmentation');

    if (segOccurrence && data.parentTexts.has(o)) {
      edges.push({
        from: rootId,
        to: nodeId,
        edge_type: 'segmentation',
        strategy: '分词',
        label: '分词',
        round: 0
      });
    }
  });

  // 2. Query演化关系
  Object.entries(queryEvolution).forEach(([text, data]) => {
    const nodeId = `query_${text}`;

    data.parentTexts.forEach(parentText => {
      if (parentText === o) return; // 跳过原始问题（已处理）

      const parentNodeId = `query_${parentText}`;
      if (!mergedNodes[parentNodeId]) return;

      // 找到这个演化的策略和轮次
      const occurrence = data.occurrences.find(o =>
        o.role === 'sug' || o.role === 'add_word'
      );

      edges.push({
        from: parentNodeId,
        to: nodeId,
        edge_type: occurrence?.role || 'evolution',
        strategy: occurrence?.strategy || '演化',
        label: `${occurrence?.strategy || '演化'} (R${occurrence?.round || 0})`,
        round: occurrence?.round || 0
      });
    });
  });

  // 3. Query -> Post (搜索关系)
  Object.entries(queryEvolution).forEach(([text, data]) => {
    const nodeId = `query_${text}`;

    if (data.posts && data.posts.size > 0) {
      const searchOccurrence = data.occurrences.find(o => o.role === 'search');

      data.posts.forEach(noteId => {
        const postId = `post_${noteId}`;
        edges.push({
          from: nodeId,
          to: postId,
          edge_type: 'search',
          strategy: '搜索',
          label: `搜索 (${data.posts.size}个帖子)`,
          round: searchOccurrence?.round || 0
        });
      });
    }
  });

  return {
    nodes: mergedNodes,
    edges,
    iterations
  };
}

module.exports = { convertV8ToGraphV2, convertV8ToGraphSimplified };
