/**
 * 剥离示例报表 XML 中的 base64 图片数据，生成轻量结构版，供 LLM 阅读以节省 token。
 *
 * - 递归遍历 src/examples/sample-center/xml，保持子目录结构，输出到 xml-nobase64。
 * - 仅用正则清空 <base64-data> 的 CDATA 图片负载（保留标签与占位提示），
 *   不做 XML 重序列化，避免破坏 CDATA / 原有格式（fast-xml-parser 往返有丢 CDATA 风险）。
 * - 打印剥离前后总大小与节省百分比，便于量化收益。
 *
 * 用法：npm run strip-base64
 */
import { promises as fs } from 'node:fs';
import * as path from 'node:path';
import { fileURLToPath } from 'node:url';

const scriptDir = path.dirname(fileURLToPath(import.meta.url));
const projectRoot = path.resolve(scriptDir, '..');
const SRC_ROOT = path.join(projectRoot, 'src', 'examples', 'sample-center', 'xml');
const OUT_ROOT = path.join(projectRoot, 'src', 'examples', 'sample-center', 'xml-nobase64');

// data URI 形式：data:image/png;base64,xxxx（CDATA 内不会出现 "]]>"，可安全非贪婪匹配）
const BASE64_RE = /<base64-data><!\[CDATA\[data:[^;]*;base64,[^]*?\]\]><\/base64-data>/g;
const IMG_TYPE_RE = /^data:image\/([a-zA-Z0-9.+-]+);base64,/;

let processed = 0;
let stripped = 0;
let srcBytes = 0;
let outBytes = 0;

async function walk(dir: string, rel: string): Promise<void> {
  const entries = await fs.readdir(dir, { withFileTypes: true });
  for (const ent of entries) {
    const full = path.join(dir, ent.name);
    const nextRel = path.join(rel, ent.name);
    if (ent.isDirectory()) {
      await walk(full, nextRel);
    } else if (ent.isFile() && ent.name.toLowerCase().endsWith('.xml')) {
      await convertFile(full, nextRel);
    }
  }
}

async function convertFile(full: string, rel: string): Promise<void> {
  const xml = await fs.readFile(full, 'utf-8');
  srcBytes += Buffer.byteLength(xml, 'utf-8');

  let hits = 0;
  const strippedXml = xml.replace(BASE64_RE, (m) => {
    hits++;
    const typeMatch = m.match(IMG_TYPE_RE);
    const imgType = typeMatch ? typeMatch[1] : 'unknown';
    return `<base64-data><![CDATA[data:image/${imgType};base64,[图片数据已剥离，阅读结构时忽略]]]></base64-data>`;
  });
  stripped += hits;

  const outPath = path.join(OUT_ROOT, rel);
  await fs.mkdir(path.dirname(outPath), { recursive: true });
  await fs.writeFile(outPath, strippedXml, 'utf-8');
  outBytes += Buffer.byteLength(strippedXml, 'utf-8');
  processed++;
  console.log(`  ${hits > 0 ? `剥离 ${hits} 处: ` : '无 base64: '}${rel}`);
}

async function main(): Promise<void> {
  console.log(`源目录: ${SRC_ROOT}`);
  console.log(`输出目录: ${OUT_ROOT}`);
  await fs.mkdir(OUT_ROOT, { recursive: true });
  await walk(SRC_ROOT, '');

  const saved = srcBytes - outBytes;
  const pct = srcBytes > 0 ? ((saved / srcBytes) * 100).toFixed(1) : '0.0';
  console.log('\n==== 汇总 ====');
  console.log(`  处理文件: ${processed}`);
  console.log(`  剥离 base64 处数: ${stripped}`);
  console.log(`  原大小:   ${(srcBytes / 1024).toFixed(1)} KB`);
  console.log(`  剥离后:   ${(outBytes / 1024).toFixed(1)} KB`);
  console.log(`  节省:     ${(saved / 1024).toFixed(1)} KB (${pct}%)`);
}

main().catch((e) => {
  console.error(e);
  process.exit(1);
});
