#!/usr/bin/env node
/**
 * News Aggregator for OpenClaw (with translation to Chinese)
 * 聚合国内外科技与军事新闻，自动筛选并生成要点。对英文源内容进行中文翻译。
 * 输出格式：纯文本 + 表情符号，适合 QQ 聊天
 */

import fetch from 'node-fetch';

// 新闻源列表（按需扩展），lang: 'zh' 或 'en'
const SOURCES = {
  domesticTech: [
    { name: '36氪', url: 'https://36kr.com/information/tech/', lang: 'zh' },
    { name: '机器之心', url: 'https://www.jiqizhixin.com/', lang: 'zh' },
    { name: '量子位', url: 'https://www.1baijia.com/', lang: 'zh' },
    { name: 'IT之家', url: 'https://www.ithome.com/', lang: 'zh' }
  ],
  domesticMilitary: [
    { name: '观察者网', url: 'https://www.guancha.cn/', lang: 'zh' },
    { name: '澎湃新闻', url: 'https://www.thepaper.cn/', lang: 'zh' },
    { name: '腾讯军事', url: 'https://new.qq.com/om/mil/', lang: 'zh' }
  ],
  internationalTech: [
    { name: 'TechCrunch', url: 'https://techcrunch.com/', lang: 'en' },
    { name: 'The Verge', url: 'https://www.theverge.com/', lang: 'en' },
    { name: 'Wired', url: 'https://www.wired.com/', lang: 'en' },
    { name: 'Ars Technica', url: 'https://arstechnica.com/', lang: 'en' }
  ],
  internationalMilitary: [
    { name: 'Defense News', url: 'https://www.defensenews.com/', lang: 'en' },
    { name: "Jane's Defence", url: 'https://www.janes.com/', lang: 'en' },
    { name: 'Military Times', url: 'https://www.militarytimes.com/', lang: 'en' }
  ]
};

// 简易文章类
class Article {
  constructor(title, link, source, pubDate, summary, lang) {
    this.title = title;
    this.link = link;
    this.source = source;
    this.pubDate = pubDate;
    this.summary = summary;
    this.lang = lang; // 原始内容语言
  }
}

// 文本翻译（使用 MyMemory 免费 API）
async function translateText(text, from = 'en', to = 'zh') {
  if (!text || text.length === 0) return text;
  try {
    const encoded = encodeURIComponent(text);
    const url = `https://api.mymemory.translated.net/get?q=${encoded}&langpair=${from}|${to}`;
    const res = await fetch(url, { timeout: 10000 });
    if (!res.ok) throw new Error(`HTTP ${res.status}`);
    const data = await res.json();
    if (data.responseStatus === 200) {
      return data.responseData.translatedText;
    } else {
      console.warn(`Translation API status ${data.responseStatus}: ${data.responseDetails || ''}`);
      return text;
    }
  } catch (err) {
    console.warn(`Translate failed: ${err.message}; using original.`);
    return text;
  }
}

// 批量翻译文章（英文源）
async function translateArticles(articles) {
  const tasks = articles.map(async (a) => {
    if (a.lang === 'en') {
      const [titleZh, summaryZh] = await Promise.all([
        translateText(a.title, 'en', 'zh'),
        translateText(a.summary, 'en', 'zh')
      ]);
      a.title = titleZh;
      a.summary = summaryZh;
    }
  });
  await Promise.all(tasks);
}

// 抓取单个网页的标题和摘要（简化版）
async function fetchArticleInfo(src) {
  try {
    const res = await fetch(src.url, {
      headers: { 'User-Agent': 'Mozilla/5.0 (compatible; OpenClawBot/1.0)' },
      timeout: 8000
    });
    if (!res.ok) return null;
    const html = await res.text();

    // 提取标题 <title>...</title>
    const titleMatch = html.match(/<title[^>]*>([^<]+)<\/title>/i);
    const title = titleMatch ? titleMatch[1].trim() : '无标题';

    // 尝试从 meta description 取摘要
    const descMatch = html.match(/<meta[^>]*name="description"[^>]*content="([^"]+)"/i);
    let summary = descMatch ? descMatch[1].trim() : '暂无摘要';

    // 截断过长的摘要
    if (summary.length > 150) summary = summary.substring(0, 150) + '...';

    return new Article(
      title,
      src.url,
      src.name,
      new Date().toISOString(),
      summary,
      src.lang
    );
  } catch (err) {
    return null;
  }
}

// 并发抓取一组源
async function fetchArticles(sources, limit = 5) {
  const tasks = sources.map(src => fetchArticleInfo(src));
  const results = await Promise.allSettled(tasks);
  const articles = [];
  for (const r of results) {
    if (r.status === 'fulfilled' && r.value) {
      articles.push(r.value);
      if (articles.length >= limit) break;
    }
  }
  return articles;
}

// 去重（基于链接）
function deduplicate(articles) {
  const seen = new Set();
  return articles.filter(a => {
    if (seen.has(a.link)) return false;
    seen.add(a.link);
    return true;
  });
}

// 提取文本中的关键数据（数字+单位、年份等）
function extractKeyDataFromText(text) {
  if (!text) return [];
  const patterns = [
    /(\d+(?:\.\d+)?\s*(?:亿|万元|亿美元|%|亿个|万|千))/g,
    /(\d+(?:\.\d+)?\s*(?:billion|million|thousand|USD|RMB))/gi,
    /(\d{4}\s*年)/g
  ];
  const found = new Set();
  for (const p of patterns) {
    let m;
    while ((m = p.exec(text)) !== null) {
      found.add(m[1].trim());
    }
  }
  return Array.from(found);
}

// 生成纯文本简报输出（带表情，适合 QQ 聊天）
function generateOutput(tech, military) {
  const now = new Date();
  const today = now.toLocaleDateString('zh-CN', { year: 'numeric', month: 'long', day: 'numeric' });

  let out = `📰 每日新闻简报 · ${today}\n\n`;
  out += `汇聚全球科技与军事要闻，提炼关键信息，助您快速掌握动态。\n\n`;

  // 汇总关键数据
  const allArticles = tech.concat(military);
  const allKeyData = allArticles.flatMap(a => extractKeyDataFromText(a.title + ' ' + a.summary));
  const uniqueData = [...new Set(allKeyData)];
  if (uniqueData.length > 0) {
    out += '📊 今日要点\n';
    uniqueData.forEach(d => out += `• ${d}\n`);
    out += '\n';
  }

  out += '🔬 科技新闻\n';
  if (tech.length === 0) {
    out += '今日暂无可用科技新闻。\n';
  } else {
    tech.forEach((a, idx) => {
      out += `\n${idx + 1}. ${a.title}\n`;
      out += `   📍 来源：${a.source}\n\n`;
      out += `   ${a.summary}\n`;
    });
  }

  out += '\n⚔️ 军事新闻\n';
  if (military.length === 0) {
    out += '今日暂无可用军事新闻。\n';
  } else {
    military.forEach((a, idx) => {
      out += `\n${idx + 1}. ${a.title}\n`;
      out += `   📍 来源：${a.source}\n\n`;
      out += `   ${a.summary}\n`;
    });
  }

  out += '\n────────────────────\n';
  out += '自动聚合 | 数据来源：公开网络 | 仅供参考';
  return out;
}

// 主流程
export async function main() {
  // 抓取科技 + 军事
  const techPromise = fetchArticles(SOURCES.domesticTech.concat(SOURCES.internationalTech), 5);
  const milPromise = fetchArticles(SOURCES.domesticMilitary.concat(SOURCES.internationalMilitary), 5);
  const [tech, mil] = await Promise.all([techPromise, milPromise]);

  // 翻译英文内容为中文
  await translateArticles(tech);
  await translateArticles(mil);

  // 去重
  const allTech = deduplicate(tech);
  const allMil = deduplicate(mil);

  // 生成输出
  const output = generateOutput(allTech, allMil);
  console.log(output);

  // 保存文件
  const fs = (await import('fs')).promises;
  const path = (await import('path')).resolve('news_aggregated.md');
  await fs.writeFile(path, output, 'utf8');
  console.log(`\n已保存至：${path}`);
}

// 如果直接运行 node index.js，则执行 main
if (process.argv[1] && process.argv[1].endsWith('index.js')) {
  main().catch(err => {
    console.error('Aggregation failed:', err);
    process.exit(1);
  });
}
