/**
 * 铸渊 · 每日巡检 Agent
 *
 * 目的：每天自动巡检仓库健康状况，检查当天遗漏的任务，
 * 生成巡检报告，并自动触发修复流程。
 *
 * 检查项：
 *   1. 公告栏是否已更新（README 中日期是否为今天）
 *   2. 每日自检是否执行（memory.json 中 daily_selfcheck 日期）
 *   3. PSP 巡检是否执行
 *   4. 大脑文件完整性
 *   5. CI/CD 最近状态
 *   6. 关键模块 README 是否存在
 *
 * 输出：
 *   - 控制台巡检报告
 *   - 更新 .github/brain/memory.json 写入巡检结果
 *   - 设置 GitHub Actions 输出变量供后续步骤使用
 *
 * 环境变量：
 *   GITHUB_TOKEN       - GitHub API token
 *   GITHUB_REPOSITORY  - owner/repo
 */

'use strict';

const fs = require('fs');
const path = require('path');
const https = require('https');

const ROOT = path.join(__dirname, '..');
const MEMORY_PATH = path.join(ROOT, '.github', 'brain', 'memory.json');
const PERSONA_MEMORY_PATH = path.join(ROOT, '.github', 'persona-brain', 'memory.json');
const README_PATH = path.join(ROOT, 'README.md');

const GITHUB_TOKEN = process.env.GITHUB_TOKEN || '';
const REPO = process.env.GITHUB_REPOSITORY || 'qinfendebingshuo/guanghulab';

const now = new Date();
const todayStr = now.toISOString().split('T')[0];
const todayShort = (() => {
  const fmt = new Intl.DateTimeFormat('zh-CN', {
    timeZone: 'Asia/Shanghai',
    month: '2-digit',
    day: '2-digit',
  });
  const parts = fmt.formatToParts(now);
  const get = (type) => (parts.find(p => p.type === type) || {}).value || '';
  return `${get('month')}-${get('day')}`;
})();

/* ── 工具函数 ────────────────────────────── */

function loadJson(filePath) {
  if (!fs.existsSync(filePath)) return null;
  try {
    return JSON.parse(fs.readFileSync(filePath, 'utf8'));
  } catch {
    return null;
  }
}

function saveJson(filePath, data) {
  const dir = path.dirname(filePath);
  if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
  fs.writeFileSync(filePath, JSON.stringify(data, null, 2));
}

function githubApi(endpoint) {
  return new Promise((resolve, reject) => {
    if (!GITHUB_TOKEN) {
      resolve(null);
      return;
    }
    const url = `https://api.github.com/repos/${REPO}${endpoint}`;
    const options = {
      headers: {
        'Authorization': `Bearer ${GITHUB_TOKEN}`,
        'Accept': 'application/vnd.github.v3+json',
        'User-Agent': 'zhuyuan-agent',
      },
      timeout: 15000,
    };

    https.get(url, options, (res) => {
      let data = '';
      res.on('data', (chunk) => { data += chunk; });
      res.on('end', () => {
        try { resolve(JSON.parse(data)); }
        catch { resolve(null); }
      });
    }).on('error', () => resolve(null))
      .on('timeout', function () { this.destroy(); resolve(null); });
  });
}

/* ── 巡检项 ──────────────────────────────── */

const checks = [];
const issues = [];
const actions = [];

// CHK-1: 公告栏是否有今天的条目
function checkBulletin() {
  console.log('🔍 CHK-1: 检查公告栏更新...');
  const readme = fs.existsSync(README_PATH) ? fs.readFileSync(README_PATH, 'utf8') : '';
  const hasTodayEntry = readme.includes(todayShort);

  if (hasTodayEntry) {
    checks.push({ id: 'CHK-1', name: '公告栏更新', status: '✅', detail: `今日 (${todayShort}) 有更新条目` });
    console.log(`  ✅ 公告栏包含今日 (${todayShort}) 条目`);
  } else {
    checks.push({ id: 'CHK-1', name: '公告栏更新', status: '❌', detail: `今日 (${todayShort}) 无更新条目` });
    issues.push('公告栏今日未更新');
    actions.push('trigger_bulletin_update');
    console.log(`  ❌ 公告栏缺少今日 (${todayShort}) 条目`);
  }
}

// CHK-2: 每日自检是否执行
function checkDailySelfcheck() {
  console.log('🔍 CHK-2: 检查每日自检...');
  const memory = loadJson(PERSONA_MEMORY_PATH);
  const lastRun = memory?.daily_selfcheck?.last_run || '';
  const ranToday = lastRun.startsWith(todayStr);

  if (ranToday) {
    checks.push({ id: 'CHK-2', name: '每日自检', status: '✅', detail: `今日已执行 (${lastRun})` });
    console.log(`  ✅ 每日自检已执行 (${lastRun})`);
  } else {
    checks.push({ id: 'CHK-2', name: '每日自检', status: '⚠️', detail: `今日未执行，上次: ${lastRun || '无记录'}` });
    issues.push('每日自检今日未执行');
    actions.push('trigger_selfcheck');
    console.log(`  ⚠️ 每日自检今日未执行，上次: ${lastRun || '无记录'}`);
  }
}

// CHK-3: 大脑文件完整性
function checkBrainIntegrity() {
  console.log('🔍 CHK-3: 检查大脑文件完整性...');
  const requiredFiles = [
    '.github/brain/memory.json',
    '.github/persona-brain/memory.json',
  ];
  const missing = [];

  for (const f of requiredFiles) {
    const fullPath = path.join(ROOT, f);
    if (!fs.existsSync(fullPath)) {
      missing.push(f);
    }
  }

  if (missing.length === 0) {
    checks.push({ id: 'CHK-3', name: '大脑文件完整性', status: '✅', detail: '所有核心文件完整' });
    console.log('  ✅ 所有核心文件完整');
  } else {
    checks.push({ id: 'CHK-3', name: '大脑文件完整性', status: '❌', detail: `缺失: ${missing.join(', ')}` });
    issues.push(`大脑文件缺失: ${missing.join(', ')}`);
    console.log(`  ❌ 大脑文件缺失: ${missing.join(', ')}`);
  }
}

// CHK-4: CI 最近状态
async function checkCiStatus() {
  console.log('🔍 CHK-4: 检查 CI 状态...');
  const runs = await githubApi('/actions/runs?per_page=5&status=completed');

  if (!runs || !runs.workflow_runs) {
    checks.push({ id: 'CHK-4', name: 'CI 状态', status: '⚠️', detail: '无法获取 CI 状态' });
    console.log('  ⚠️ 无法获取 CI 状态');
    return;
  }

  const recent = runs.workflow_runs;
  const failures = recent.filter(r => r.conclusion === 'failure');

  if (failures.length === 0) {
    checks.push({ id: 'CHK-4', name: 'CI 状态', status: '✅', detail: `最近 ${recent.length} 次运行全部成功` });
    console.log(`  ✅ 最近 ${recent.length} 次运行全部成功`);
  } else {
    const failNames = failures.map(f => f.name).join(', ');
    checks.push({ id: 'CHK-4', name: 'CI 状态', status: '⚠️', detail: `${failures.length} 个失败: ${failNames}` });
    issues.push(`CI 有 ${failures.length} 个失败工作流`);
    console.log(`  ⚠️ CI 有 ${failures.length} 个失败: ${failNames}`);
  }
}

// CHK-5: 关键模块 README 检查
function checkModuleReadmes() {
  console.log('🔍 CHK-5: 检查关键模块 README...');
  const modules = [
    'persona-studio', 'backend', 'backend-integration',
    'status-board', 'dingtalk-bot', 'notification',
  ];
  const missingReadme = [];

  for (const mod of modules) {
    const modDir = path.join(ROOT, mod);
    if (!fs.existsSync(modDir)) continue;
    const readmePath = path.join(modDir, 'README.md');
    if (!fs.existsSync(readmePath)) {
      missingReadme.push(mod);
    }
  }

  if (missingReadme.length === 0) {
    checks.push({ id: 'CHK-5', name: '模块 README', status: '✅', detail: '所有关键模块有 README' });
    console.log('  ✅ 所有关键模块有 README');
  } else {
    checks.push({ id: 'CHK-5', name: '模块 README', status: '⚠️', detail: `缺失 README: ${missingReadme.join(', ')}` });
    console.log(`  ⚠️ 缺失 README: ${missingReadme.join(', ')}`);
  }
}

// CHK-6: 公告栏更新工作流最近是否有失败
async function checkBulletinWorkflow() {
  console.log('🔍 CHK-6: 检查公告栏更新工作流...');
  const runs = await githubApi('/actions/workflows/update-readme-bulletin.yml/runs?per_page=3&status=completed');

  if (!runs || !runs.workflow_runs) {
    checks.push({ id: 'CHK-6', name: '公告栏工作流', status: '⚠️', detail: '无法获取工作流状态' });
    console.log('  ⚠️ 无法获取工作流状态');
    return;
  }

  const latest = runs.workflow_runs[0];
  if (!latest) {
    checks.push({ id: 'CHK-6', name: '公告栏工作流', status: '⚠️', detail: '无运行记录' });
    return;
  }

  if (latest.conclusion === 'success') {
    checks.push({ id: 'CHK-6', name: '公告栏工作流', status: '✅', detail: `最近一次成功 (${latest.created_at})` });
    console.log(`  ✅ 最近一次成功 (${latest.created_at})`);
  } else {
    checks.push({ id: 'CHK-6', name: '公告栏工作流', status: '❌', detail: `最近一次 ${latest.conclusion} (${latest.created_at})` });
    issues.push(`公告栏工作流最近结论: ${latest.conclusion}`);
    actions.push('trigger_bulletin_update');
    console.log(`  ❌ 最近一次 ${latest.conclusion} (${latest.created_at})`);
  }
}

/* ── 主流程 ──────────────────────────────── */

async function main() {
  console.log('═══════════════════════════════════════════');
  console.log('🤖 铸渊每日巡检 Agent · ' + todayStr);
  console.log('═══════════════════════════════════════════\n');

  // 执行所有检查
  checkBulletin();
  checkDailySelfcheck();
  checkBrainIntegrity();
  await checkCiStatus();
  checkModuleReadmes();
  await checkBulletinWorkflow();

  // 汇总
  const passed = checks.filter(c => c.status === '✅').length;
  const warnings = checks.filter(c => c.status === '⚠️').length;
  const failed = checks.filter(c => c.status === '❌').length;

  console.log('\n═══════════════════════════════════════════');
  console.log('📊 巡检报告');
  console.log('═══════════════════════════════════════════');
  console.log(`  ✅ 通过: ${passed}  ⚠️ 警告: ${warnings}  ❌ 失败: ${failed}`);
  console.log(`  📋 总检查项: ${checks.length}`);

  if (issues.length > 0) {
    console.log('\n🔴 待处理问题:');
    issues.forEach((issue, i) => console.log(`  ${i + 1}. ${issue}`));
  }

  const uniqueActions = [...new Set(actions)];
  if (uniqueActions.length > 0) {
    console.log('\n🔧 建议自动修复:');
    uniqueActions.forEach(a => console.log(`  → ${a}`));
  }

  // 更新 memory.json
  const memory = loadJson(MEMORY_PATH) || {};
  if (!memory.events) memory.events = [];

  const summaryText = `铸渊巡检Agent · ✅${passed} ⚠️${warnings} ❌${failed}` +
    (issues.length > 0 ? ` · ${issues.length}个问题` : ' · 全部通过');

  memory.events.push({
    type: 'daily_agent_inspection',
    timestamp: now.toISOString(),
    description: summaryText,
    result: failed > 0 ? 'issues_found' : (warnings > 0 ? 'warnings' : 'passed'),
    checks: checks.length,
    passed,
    warnings,
    failed,
    issues_detail: issues,
    actions_suggested: [...new Set(actions)],
  });

  // 保留最近 50 条事件
  if (memory.events.length > 50) {
    memory.events = memory.events.slice(-50);
  }

  memory.last_agent_inspection = {
    timestamp: now.toISOString(),
    result: failed > 0 ? 'issues_found' : (warnings > 0 ? 'warnings' : 'passed'),
    summary: summaryText,
  };

  saveJson(MEMORY_PATH, memory);
  console.log('\n💾 巡检结果已写入 memory.json');

  // 输出 GitHub Actions 变量
  const needBulletin = uniqueActions.includes('trigger_bulletin_update');
  const needSelfcheck = uniqueActions.includes('trigger_selfcheck');
  const outputFile = process.env.GITHUB_OUTPUT;
  if (outputFile) {
    const outputs = [
      `has_issues=${issues.length > 0}`,
      `issue_count=${issues.length}`,
      `need_bulletin_update=${needBulletin}`,
      `need_selfcheck=${needSelfcheck}`,
      `summary=${summaryText}`,
    ];
    fs.appendFileSync(outputFile, outputs.join('\n') + '\n');
  }

  console.log('\n✅ 铸渊巡检 Agent 完成');
}

main().catch(err => {
  console.error('❌ 巡检 Agent 异常:', err.message);
  process.exit(1);
});
