/**
 * 帮助中心 AI 助手 —— 知识库构建脚本
 *
 * 作用：扫描 docs/ 下所有 Markdown 文档，去掉 frontmatter 与图片/代码噪声，
 *      按标题（# / ## / ###）切分成可检索的段落（chunk），输出为 knowledge.json，
 *      供前端 AI 助手做“客户端检索（RAG）”使用。
 *
 * 用法：node scripts/build-knowledge.js
 *      （文档有更新后重新运行一次即可）
 */
const fs = require('fs');
const path = require('path');

const DOCS_DIR = path.resolve(__dirname, '..', 'docs');
const OUT_FILE = path.resolve(__dirname, '..', 'src', 'components', 'AIAssistant', 'knowledge.json');

/** 收集所有 .md 文件（相对路径） */
function walkMd(dir, base = '') {
  const out = [];
  for (const name of fs.readdirSync(dir)) {
    const full = path.join(dir, name);
    const rel = base ? `${base}/${name}` : name;
    const stat = fs.statSync(full);
    if (stat.isDirectory()) out.push(...walkMd(full, rel));
    else if (name.endsWith('.md')) out.push({ abs: full, rel });
  }
  return out;
}

/** 去掉 frontmatter（--- ... ---） */
function stripFrontmatter(text) {
  if (text.startsWith('---')) {
    const end = text.indexOf('\n---', 3);
    if (end !== -1) return text.slice(end + 4).replace(/^\s*\n/, '');
  }
  return text;
}

/** 取 frontmatter 里的 sidebar_label / label，作为页面友好标题 */
function frontTitle(text, fileRel) {
  const m = text.match(/^---([\s\S]*?)---/);
  let label = '';
  if (m) {
    const lm = m[1].match(/sidebar_label:\s*['"]?([^'"\n]+)['"]?/);
    const km = m[1].match(/label:\s*['"]?([^'"\n]+)['"]?/);
    label = (lm && lm[1].trim()) || (km && km[1].trim()) || '';
  }
  if (!label) {
    label = path.basename(fileRel, '.md');
  }
  return label.trim();
}

/** 计算页面在站点中的访问路径，与 Docusaurus routeBasePath:'/' 对齐 */
function pageRoute(fileRel, text) {
  let slug = '';
  const m = text.match(/^---([\s\S]*?)---/);
  if (m) {
    const sm = m[1].match(/slug:\s*['"]?([^'"\n]+)['"]?/);
    if (sm) slug = sm[1].trim();
  }
  if (slug && slug !== '/') {
    // 以 slug 里的内容作为路径（去掉前导斜杠）
    return slug.replace(/^\/+/, '');
  }
  // 默认：目录/文件名（去掉 .md）。intro.md 的 slug 是 / 单独处理。
  const noExt = fileRel.replace(/\.md$/, '');
  if (noExt === 'intro') return '';
  return noExt;
}

/** 清洗一段文本：去掉图片、HTML、链接保留文字、多余空行 */
function cleanText(text) {
  return text
    .replace(/!\[[^\]]*\]\([^)]*\)/g, '') // 图片
    .replace(/<[^>]+>/g, ' ') // HTML 标签
    .replace(/\[([^\]]+)\]\([^)]*\)/g, '$1') // 链接保留文字
    .replace(/`{1,3}/g, '') // 代码反引号
    .replace(/^\s{0,3}>\s?/gm, '') // 引用符
    .replace(/\n{3,}/g, '\n\n')
    .trim();
}

/** 按标题把一页切成多个 chunk */
function chunkPage(text, pageLabel, route, fileName) {
  const lines = text.split('\n');
  const chunks = [];
  let curSection = pageLabel; // 当前小节标题
  let buf = [];

  const flush = () => {
    const body = cleanText(buf.join('\n'));
    if (body && body.length > 8) {
      chunks.push({
        title: pageLabel,
        section: curSection,
        path: '/' + route,
        source: fileName,
        text: body,
      });
    }
    buf = [];
  };

  for (const raw of lines) {
    const hm = raw.match(/^(#{1,4})\s+(.*)/);
    if (hm) {
      flush();
      const level = hm[1].length;
      const headText = cleanText(hm[2]);
      // 用一级标题作为页面标题候选，二三级作为小节
      if (level === 1) {
        if (headText) { /* 一级标题作为页面正文一部分，不单独覆盖 pageLabel */ }
      }
      curSection = headText || pageLabel;
      buf.push(raw); // 保留标题文字进正文
    } else {
      buf.push(raw);
    }
  }
  flush();
  return chunks;
}

function main() {
  if (!fs.existsSync(DOCS_DIR)) {
    console.error('[build-knowledge] docs 目录不存在:', DOCS_DIR);
    process.exit(1);
  }
  const files = walkMd(DOCS_DIR);
  const all = [];
  let pageCount = 0;
  for (const f of files) {
    let raw;
    try {
      raw = fs.readFileSync(f.abs, 'utf8');
    } catch (e) {
      console.warn('[build-knowledge] 读取失败:', f.rel, e.message);
      continue;
    }
    const label = frontTitle(raw, f.rel);
    const route = pageRoute(f.rel, raw);
    const body = stripFrontmatter(raw);
    const chunks = chunkPage(body, label, route, f.rel);
    if (chunks.length) {
      all.push(...chunks);
      pageCount += 1;
    }
  }

  fs.mkdirSync(path.dirname(OUT_FILE), { recursive: true });
  fs.writeFileSync(OUT_FILE, JSON.stringify(all, null, 0), 'utf8');
  console.log(`[build-knowledge] 完成：${pageCount} 个文档，${all.length} 个段落 -> ${path.relative(process.cwd(), OUT_FILE)}`);
}

main();
