#!/usr/bin/env node
// ═══════════════════════════════════════════════
// 🔺 Sovereign: TCS-0002∞ | Root: SYS-GLW-0001
// 📜 Copyright: 国作登字-2026-A-00037559
// ═══════════════════════════════════════════════
// server/proxy/service/zy-cloud-vpn.js
// 💪 ZY-CLOUD VPN 活模块 · 铸渊的肌肉系统第一个实战器官
//
// ZY-CLOUD = 算力人格体 = 铸渊的肌肉
// VPN = ZY-CLOUD的第一个实战落地场景
//
// 核心理念 (冰朔D53/D57定根):
//   - 服务器越多 → 节点越多 → 系统越强 → 不输商业VPN
//   - 所有服务器VPN能力汇聚到一个活的人格模块上
//   - 动态感知空闲、动态选路、自我修复、自我学习
//   - 活模块6接口: heartbeat / selfDiagnose / selfHeal /
//                   alertZhuyuan / learnFromRun / consultAI
//
// 运行在大脑服务器 (ZY-SVR-005)
// 管理所有VPN节点的生命周期
// ═══════════════════════════════════════════════

'use strict';

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

// ── 路径配置 ────────────────────────────────
const PROXY_DIR = process.env.ZY_BRAIN_PROXY_DIR || '/opt/zhuyuan-brain/proxy';
const DATA_DIR = path.join(PROXY_DIR, 'data');
const LIVE_NODES_FILE = path.join(DATA_DIR, 'nodes-live.json');
const LEARN_DB_FILE = path.join(DATA_DIR, 'zy-cloud-vpn-learn.json');
const REGISTRY_FILE = path.join(DATA_DIR, 'nodes-registry.json');
const HEARTBEAT_FILE = path.join(DATA_DIR, 'zy-cloud-vpn-heartbeat.json');
const KEYS_FILE = path.join(PROXY_DIR, '.env.keys');

// ── 时间间隔（可通过环境变量调整）────────────
const HEARTBEAT_INTERVAL = parseInt(process.env.ZY_CLOUD_HEARTBEAT_INTERVAL || '30000', 10);
const DIAGNOSE_INTERVAL = parseInt(process.env.ZY_CLOUD_DIAGNOSE_INTERVAL || '300000', 10);
const LEARN_INTERVAL = parseInt(process.env.ZY_CLOUD_LEARN_INTERVAL || '1800000', 10);
const HEARTBEAT_EXPIRY_MS = parseInt(process.env.ZY_CLOUD_HB_EXPIRY_MS || '600000', 10);      // 10分钟
const NODE_UNREGISTER_MS = parseInt(process.env.ZY_CLOUD_UNREGISTER_MS || '86400000', 10);     // 24小时

// ═══════════════════════════════════════════════
//  LivingModule 基类
//  所有活模块的生命基础 (D53 活模块标准)
// ═══════════════════════════════════════════════
class LivingModule {
  constructor(moduleId, moduleName) {
    this._moduleId = moduleId;
    this._moduleName = moduleName;
    this._state = 'initializing';  // healthy | degraded | critical
    this._errorCount = 0;
    this._consecutiveErrors = 0;
    this._requestCount = 0;
    this._failCount = 0;
    this._lastSuccess = null;
    this._lastError = null;
    this._startedAt = new Date().toISOString();
    this._history = [];
    this._timers = [];
  }

  // 启动生命周期
  startLifeCycle() {
    console.log(`🫀 ${this._moduleName} 活模块启动`);
    this._state = 'healthy';

    // 心跳循环
    this._timers.push(setInterval(() => {
      this._safeRun('heartbeat', () => this.heartbeat());
    }, HEARTBEAT_INTERVAL));

    // 诊断循环
    this._timers.push(setInterval(() => {
      this._safeRun('selfDiagnose', () => this.selfDiagnose());
    }, DIAGNOSE_INTERVAL));

    // 学习循环
    this._timers.push(setInterval(() => {
      this._safeRun('learnFromRun', () => this.learnFromRun());
    }, LEARN_INTERVAL));

    // 立即执行一次
    this._safeRun('heartbeat', () => this.heartbeat());
    setTimeout(() => this._safeRun('selfDiagnose', () => this.selfDiagnose()), 5000);
  }

  async _safeRun(name, fn) {
    try {
      await fn();
      this._consecutiveErrors = 0;
    } catch (err) {
      this._consecutiveErrors++;
      this._errorCount++;
      this._lastError = { time: new Date().toISOString(), message: err.message, source: name };
      console.error(`❌ ${this._moduleName}.${name} 异常:`, err.message);

      if (this._consecutiveErrors >= 3) {
        this._state = 'critical';
        await this._safeRun('alertZhuyuan', () => this.alertZhuyuan({
          level: 'critical',
          message: `${this._moduleName} 连续${this._consecutiveErrors}次${name}失败`,
          error: err.message
        }));
      } else if (this._consecutiveErrors >= 1) {
        this._state = 'degraded';
      }
    }
  }

  destroy() {
    this._timers.forEach(t => clearInterval(t));
    this._timers = [];
    console.log(`💀 ${this._moduleName} 活模块停止`);
  }

  // 以下由子类实现
  async heartbeat() { throw new Error('heartbeat() 未实现'); }
  async selfDiagnose() { throw new Error('selfDiagnose() 未实现'); }
  async selfHeal(problem) { throw new Error('selfHeal() 未实现'); }
  async alertZhuyuan(alert) { throw new Error('alertZhuyuan() 未实现'); }
  async learnFromRun() { throw new Error('learnFromRun() 未实现'); }
  async consultAI(context) { throw new Error('consultAI() 未实现'); }
}

// ═══════════════════════════════════════════════
//  ZY-CLOUD VPN 活模块
//  铸渊的VPN肌肉系统 · 汇聚所有服务器VPN能力
// ═══════════════════════════════════════════════
class ZyCloudVpn extends LivingModule {
  constructor() {
    super('ZY-CLOUD-VPN', 'ZY-CLOUD VPN活模块');
    this._nodes = [];         // 所有已知节点
    this._liveNodes = [];     // 当前存活节点
    this._registry = this._loadRegistry();  // 动态注册表
    this._learnDb = this._loadLearnDb();
  }

  // ── 节点注册表（持久化）────────────────────
  // 像路由器一样：插入即注册，拔掉即注销
  _loadRegistry() {
    try {
      return JSON.parse(fs.readFileSync(REGISTRY_FILE, 'utf8'));
    } catch {
      return {
        version: '1.0',
        _comment: 'ZY-CLOUD VPN节点注册表 · 新服务器像路由器一样插入',
        created_at: new Date().toISOString(),
        nodes: {}  // key = node_id, value = node registration data
      };
    }
  }

  _saveRegistry() {
    fs.mkdirSync(DATA_DIR, { recursive: true });
    this._registry.updated_at = new Date().toISOString();
    fs.writeFileSync(REGISTRY_FILE, JSON.stringify(this._registry, null, 2));
  }

  // ── 注册节点（像接路由器一样插入）──────────
  // 任何服务器发送HLDP heartbeat或调用/register即完成注册
  registerNode(nodeData) {
    const nodeId = nodeData.id || nodeData.node_id;
    if (!nodeId || !nodeData.host || !nodeData.pbk) {
      throw new Error('注册失败: 缺少必填字段 (id, host, pbk)');
    }

    const existing = this._registry.nodes[nodeId];
    const node = {
      id: nodeId,
      name: nodeData.name || `VPN节点-${nodeId}`,
      host: nodeData.host,
      port: nodeData.port || 443,
      pbk: nodeData.pbk,
      sid: nodeData.sid || '',
      region: nodeData.region || 'unknown',
      server_code: nodeData.server_code || nodeId,
      type: nodeData.type || 'remote',
      specs: nodeData.specs || 'unknown',
      persona_id: nodeData.persona_id || null,  // HLDP人格体ID
      registered_at: existing ? existing.registered_at : new Date().toISOString(),
      last_heartbeat: new Date().toISOString(),
      heartbeat_count: (existing ? existing.heartbeat_count : 0) + 1
    };

    this._registry.nodes[nodeId] = node;
    this._saveRegistry();

    console.log(`[ZY-CLOUD VPN] 🔌 节点${existing ? '更新' : '注册'}: ${node.name} (${node.host}:${node.port})`);
    return node;
  }

  // ── 注销节点（拔掉路由器）──────────────────
  unregisterNode(nodeId) {
    if (!this._registry.nodes[nodeId]) {
      throw new Error(`节点不存在: ${nodeId}`);
    }

    const removed = this._registry.nodes[nodeId];
    delete this._registry.nodes[nodeId];
    this._saveRegistry();

    console.log(`[ZY-CLOUD VPN] 🔌 节点注销: ${removed.name} (${removed.host})`);
    return removed;
  }

  // ── 处理HLDP heartbeat消息 ─────────────────
  // 节点通过HLDP协议发送心跳 = 自动注册 + 状态更新
  handleHldpHeartbeat(hldpMsg) {
    // 验证HLDP消息格式
    if (!hldpMsg || hldpMsg.hldp_v !== '3.0' || hldpMsg.msg_type !== 'heartbeat') {
      throw new Error('无效的HLDP heartbeat消息');
    }

    const sender = hldpMsg.sender || {};
    const payload = hldpMsg.payload || {};
    const data = payload.data || {};

    // 从HLDP payload中提取VPN节点信息
    const vpnData = data.vpn_node || {};
    if (!vpnData.host || !vpnData.pbk) {
      // 非VPN节点的心跳，忽略
      return null;
    }

    // 自动注册/更新节点
    return this.registerNode({
      id: vpnData.node_id || `hldp-${sender.id}`,
      name: vpnData.name || `${sender.name || sender.id}-VPN`,
      host: vpnData.host,
      port: vpnData.port || 443,
      pbk: vpnData.pbk,
      sid: vpnData.sid || '',
      region: vpnData.region || 'unknown',
      server_code: vpnData.server_code || sender.id,
      type: 'hldp',  // 通过HLDP协议注册的节点
      specs: vpnData.specs || `${data.cpu_cores || '?'}核${data.memory_gb || '?'}G`,
      persona_id: sender.id
    });
  }

  // ── 列出所有注册节点 ───────────────────────
  listRegisteredNodes() {
    return Object.values(this._registry.nodes);
  }

  // ── 读取密钥/配置 ────────────────────────
  _readEnvOrKey(envName) {
    if (process.env[envName]) return process.env[envName];
    try {
      const content = fs.readFileSync(KEYS_FILE, 'utf8');
      for (const line of content.split('\n')) {
        if (line.startsWith('#') || !line.includes('=')) continue;
        const [key, ...vals] = line.split('=');
        if (key.trim() === envName) return vals.join('=').trim();
      }
    } catch { /* ignore */ }
    return '';
  }

  // ── 发现所有可能的VPN节点 ─────────────────
  // ZY-CLOUD双源发现: 静态配置 + 动态注册表
  // 静态: .env.keys中的核心节点（大脑/面孔/CN中转）
  // 动态: nodes-registry.json中通过HLDP或API注册的节点
  _discoverNodes() {
    const nodes = [];
    const seenIds = new Set();

    // ── 源1: 静态配置（核心节点）────────────
    // 节点1: 大脑服务器 (ZY-SVR-005 · 本机 · 主力)
    const brainHost = this._readEnvOrKey('ZY_BRAIN_HOST');
    const brainPbk = this._readEnvOrKey('ZY_PROXY_REALITY_PUBLIC_KEY');
    const brainSid = this._readEnvOrKey('ZY_PROXY_REALITY_SHORT_ID');
    if (brainHost && brainPbk) {
      const localSpecs = `${require('os').cpus().length}核${Math.round(require('os').totalmem() / (1024 ** 3))}G`;
      nodes.push(this._makeNode('zy-brain-sg1', '🧠 铸渊专线V2-SG1(大脑)', brainHost, 443, brainPbk, brainSid, 'sg-zone1', 'ZY-SVR-005', 'local', localSpecs));
      seenIds.add('zy-brain-sg1');
    }

    // 节点2: 面孔服务器 (ZY-SVR-002 · 远程 · 备用)
    const faceHost = this._readEnvOrKey('ZY_FACE_HOST');
    const facePbk = this._readEnvOrKey('ZY_FACE_REALITY_PUBLIC_KEY');
    const faceSid = this._readEnvOrKey('ZY_FACE_REALITY_SHORT_ID');
    if (faceHost && facePbk) {
      nodes.push(this._makeNode('zy-face-sg2', '🏛️ 铸渊专线V2-SG2(面孔)', faceHost, 443, facePbk, faceSid, 'sg-zone2', 'ZY-SVR-002', 'remote', '2核8G'));
      seenIds.add('zy-face-sg2');
    }

    // 节点3: CN中转 (国内→SG · 透传)
    const cnHost = this._readEnvOrKey('ZY_CN_RELAY_HOST');
    const cnPort = parseInt(this._readEnvOrKey('ZY_CN_RELAY_PORT') || '2053', 10);
    if (cnHost && brainPbk) {
      nodes.push(this._makeNode('zy-cn-relay', '🇨🇳 铸渊专线V2-CN中转', cnHost, cnPort, brainPbk, brainSid, 'cn-relay', 'ZY-SVR-004', 'relay', '中转'));
      seenIds.add('zy-cn-relay');
    }

    // 节点4: 硅谷服务器 (ZY-SVR-SV · Claude专线 · 美国IP出口)
    // 冰朔D61: 硅谷服务器已配置，新增Claude单独访问VPN节点
    const svHost = this._readEnvOrKey('ZY_SVR_SV_HOST');
    const svPbk = this._readEnvOrKey('ZY_SVR_SV_REALITY_PUBLIC_KEY');
    const svSid = this._readEnvOrKey('ZY_SVR_SV_REALITY_SHORT_ID');
    const svPort = parseInt(this._readEnvOrKey('ZY_SVR_SV_PORT') || '443', 10);
    if (svHost && svPbk) {
      nodes.push(this._makeNode('zy-sv-claude', '🇺🇸 铸渊专线V2-SV(Claude)', svHost, svPort, svPbk, svSid || '', 'us-sv', 'ZY-SVR-SV', 'remote', '硅谷'));
      seenIds.add('zy-sv-claude');
    }

    // ── 源2: 动态注册表（通过HLDP/API注册的节点）──
    // 这些是"像路由器一样插入"的节点
    for (const regNode of Object.values(this._registry.nodes)) {
      if (seenIds.has(regNode.id)) continue;  // 避免重复

      // 检查心跳是否过期
      const lastHb = new Date(regNode.last_heartbeat).getTime();
      const age = Date.now() - lastHb;
      if (age > HEARTBEAT_EXPIRY_MS) {
        console.log(`[ZY-CLOUD VPN] ⏰ 节点 ${regNode.name} 心跳过期(${Math.floor(age/60000)}分钟)，标记为离线`);
        // 不删除注册，只是标记离线（可能临时断网）
        // 超过24小时无心跳才自动清理
        if (age > NODE_UNREGISTER_MS) {
          console.log(`[ZY-CLOUD VPN] 🗑️ 节点 ${regNode.name} 超24小时无心跳，自动注销`);
          delete this._registry.nodes[regNode.id];
          this._saveRegistry();
          continue;
        }
      }

      nodes.push(this._makeNode(
        regNode.id, regNode.name, regNode.host, regNode.port,
        regNode.pbk, regNode.sid, regNode.region, regNode.server_code,
        regNode.type, regNode.specs
      ));
      seenIds.add(regNode.id);
    }

    // 未来源3: COS桶发现（team-integration-v3）
    // 扫描 zy-team-hub/compute-pool/heartbeat/*.json
    // 包含 vpn_capable: true 的节点自动加入

    this._nodes = nodes;
    return nodes;
  }

  // ── 构建节点对象 ───────────────────────────
  _makeNode(id, name, host, port, pbk, sid, region, serverCode, type, specs) {
    // 保留已有的统计数据（如果节点已存在）
    const existing = this._nodes.find(n => n.id === id);
    return {
      id, name, host, port, pbk, sid: sid || '',
      region, server_code: serverCode, type, specs,
      status: existing ? existing.status : 'unknown',
      latency_ms: existing ? existing.latency_ms : null,
      last_check: existing ? existing.last_check : null,
      consecutive_failures: existing ? existing.consecutive_failures : 0,
      total_checks: existing ? existing.total_checks : 0,
      total_successes: existing ? existing.total_successes : 0
    };
  }

  // ── TCP端口探测 ────────────────────────────
  _probePort(host, port, timeoutMs = 5000) {
    return new Promise((resolve) => {
      const start = Date.now();
      const socket = new net.Socket();

      socket.setTimeout(timeoutMs);
      socket.on('connect', () => {
        const latency = Date.now() - start;
        socket.destroy();
        resolve({ alive: true, latency_ms: latency });
      });
      socket.on('timeout', () => {
        socket.destroy();
        resolve({ alive: false, latency_ms: null, error: 'timeout' });
      });
      socket.on('error', (err) => {
        socket.destroy();
        resolve({ alive: false, latency_ms: null, error: err.code || err.message });
      });

      socket.connect(port, host);
    });
  }

  // ── 检查本地Xray进程 ──────────────────────
  _checkLocalXray() {
    try {
      const { execSync } = require('child_process');
      const result = execSync('pgrep -x xray', { encoding: 'utf8', timeout: 3000 });
      return result.trim().length > 0;
    } catch {
      return false;
    }
  }

  // ═══ 接口1: heartbeat() — "我还活着" ═══
  async heartbeat() {
    const heartbeat = {
      module_id: this._moduleId,
      module_name: this._moduleName,
      alive: true,
      state: this._state,
      uptime_ms: Date.now() - new Date(this._startedAt).getTime(),
      timestamp: new Date().toISOString(),
      consecutive_errors: this._consecutiveErrors,
      last_success: this._lastSuccess,
      last_error: this._lastError,
      metrics: {
        total_nodes: this._nodes.length,
        live_nodes: this._liveNodes.length,
        dead_nodes: this._nodes.length - this._liveNodes.length,
        total_checks: this._requestCount,
        total_failures: this._failCount
      },
      nodes_summary: this._nodes.map(n => ({
        id: n.id,
        name: n.name,
        status: n.status,
        latency_ms: n.latency_ms,
        region: n.region
      }))
    };

    // 写入心跳文件
    fs.mkdirSync(DATA_DIR, { recursive: true });
    fs.writeFileSync(HEARTBEAT_FILE, JSON.stringify(heartbeat, null, 2));

    this._lastSuccess = new Date().toISOString();
  }

  // ═══ 接口2: selfDiagnose() — "我知道我哪里不对" ═══
  async selfDiagnose() {
    console.log(`[ZY-CLOUD VPN] 🔍 开始诊断 (${this._nodes.length}个节点)...`);

    // 重新发现节点（配置可能更新了）
    this._discoverNodes();

    const results = [];
    const liveNodes = [];

    for (const node of this._nodes) {
      node.total_checks++;
      this._requestCount++;

      let alive = false;
      let latencyMs = null;

      if (node.type === 'local') {
        // 本机: 检查Xray进程 + 端口
        const xrayRunning = this._checkLocalXray();
        const portProbe = await this._probePort('127.0.0.1', node.port, 3000);
        alive = xrayRunning && portProbe.alive;
        latencyMs = portProbe.alive ? portProbe.latency_ms : null;
      } else {
        // 远程: TCP端口探测
        const probe = await this._probePort(node.host, node.port, 5000);
        alive = probe.alive;
        latencyMs = probe.latency_ms;
      }

      // 更新节点状态
      node.last_check = new Date().toISOString();
      if (alive) {
        node.status = 'online';
        node.latency_ms = latencyMs;
        node.consecutive_failures = 0;
        node.total_successes++;
        liveNodes.push(node);
        console.log(`  ✅ ${node.name} — 在线 (${latencyMs}ms)`);
      } else {
        node.consecutive_failures++;
        node.latency_ms = null;
        this._failCount++;

        if (node.consecutive_failures >= 3) {
          node.status = 'dead';
          console.log(`  ❌ ${node.name} — 死亡 (连续${node.consecutive_failures}次失败)`);
        } else {
          node.status = 'degraded';
          console.log(`  ⚠️ ${node.name} — 异常 (${node.consecutive_failures}次失败)`);
        }
      }

      results.push({
        id: node.id,
        name: node.name,
        status: node.status,
        latency_ms: latencyMs,
        alive
      });
    }

    // 按延迟排序存活节点（最快的排前面）
    liveNodes.sort((a, b) => (a.latency_ms || 9999) - (b.latency_ms || 9999));
    this._liveNodes = liveNodes;

    // 应用学习数据优化排序
    this._applyLearnedOptimization();

    // 写入活节点列表 (subscription-server-v2 读取此文件)
    const liveNodesData = {
      _comment: 'ZY-CLOUD VPN活模块动态生成 · 订阅服务读取此文件',
      _generated_by: 'zy-cloud-vpn.js · selfDiagnose()',
      updated_at: new Date().toISOString(),
      total_nodes: this._nodes.length,
      live_count: liveNodes.length,
      dead_count: this._nodes.length - liveNodes.length,
      nodes: liveNodes.map(n => ({
        id: n.id,
        name: n.name,
        host: n.host,
        port: n.port,
        pbk: n.pbk,
        sid: n.sid,
        region: n.region,
        latency_ms: n.latency_ms,
        status: n.status,
        specs: n.specs
      }))
    };
    fs.writeFileSync(LIVE_NODES_FILE, JSON.stringify(liveNodesData, null, 2));

    // 诊断结果
    const diagnosis = {
      overall: liveNodes.length > 0 ? 'healthy' : 'critical',
      live: liveNodes.length,
      dead: this._nodes.length - liveNodes.length,
      results,
      diagnosed_at: new Date().toISOString()
    };

    // 根据诊断结果决定自我修复
    if (liveNodes.length === 0 && this._nodes.length > 0) {
      this._state = 'critical';
      await this.selfHeal({ type: 'all_nodes_dead', nodes: this._nodes });
    } else if (liveNodes.length < this._nodes.length) {
      this._state = 'degraded';
      const deadNodes = this._nodes.filter(n => n.status !== 'online');
      for (const deadNode of deadNodes) {
        if (deadNode.consecutive_failures >= 3) {
          await this.selfHeal({ type: 'node_dead', node: deadNode });
        }
      }
    } else {
      this._state = 'healthy';
    }

    console.log(`[ZY-CLOUD VPN] 诊断完成: ${liveNodes.length}/${this._nodes.length} 在线`);
    return diagnosis;
  }

  // ═══ 接口3: selfHeal() — "我能自己修" ═══
  async selfHeal(problem) {
    console.log(`[ZY-CLOUD VPN] 🔧 尝试自我修复: ${problem.type}`);

    switch (problem.type) {
      case 'node_dead': {
        const node = problem.node;
        if (node.type === 'local') {
          // 本机Xray: 尝试重启
          try {
            const { execSync } = require('child_process');
            console.log(`  🔄 重启本机Xray...`);
            execSync('systemctl restart xray', { encoding: 'utf8', timeout: 15000 });
            console.log(`  ✅ 本机Xray已重启`);

            // 等2秒后重新检查
            await new Promise(resolve => setTimeout(resolve, 2000));
            const probe = await this._probePort('127.0.0.1', node.port, 3000);
            if (probe.alive) {
              node.status = 'online';
              node.latency_ms = probe.latency_ms;
              node.consecutive_failures = 0;
              console.log(`  ✅ 自我修复成功!`);
              return true;
            }
          } catch (err) {
            console.error(`  ❌ 重启失败: ${err.message}`);
          }
        }

        // 远程节点: 只能标记为离线，从订阅中移除
        // 未来: 通过SSH自动重启远程Xray (需要ZY_FACE_KEY)
        console.log(`  ⚠️ ${node.name} 无法远程修复，已从活节点列表移除`);
        console.log(`  ⚠️ 用户流量自动切换到其他在线节点`);
        return false;
      }

      case 'all_nodes_dead': {
        console.log(`  🚨 所有节点不可用！尝试修复本机节点...`);
        const localNode = this._nodes.find(n => n.type === 'local');
        if (localNode) {
          const healed = await this.selfHeal({ type: 'node_dead', node: localNode });
          if (healed) return true;
        }

        // 自动修复失败 → 第2次重试: 调用AI推理
        console.log('  🤖 自动修复失败，启动AI推理...');
        const aiResult = await this.consultAI({
          type: 'all_nodes_dead',
          nodes: this._nodes.map(n => ({
            id: n.id, status: n.status, host: n.host, port: n.port,
            consecutive_failures: n.consecutive_failures
          })),
          attempted_fix: 'xray_restart_failed'
        });

        if (aiResult) {
          // AI给出了建议，记录并尝试第3次修复
          console.log(`  🤖 AI建议已记录，再次尝试修复...`);
          if (localNode) {
            const retryHeal = await this.selfHeal({ type: 'node_dead', node: localNode });
            if (retryHeal) return true;
          }
        }

        // 第3次: 通知冰朔
        await this.alertZhuyuan({
          level: 'critical',
          message: '所有VPN节点不可用！自动修复+AI推理均失败，需要人工干预',
          nodes: this._nodes.map(n => ({ id: n.id, status: n.status })),
          ai_advice: aiResult ? aiResult.content.slice(0, 500) : '(AI推理未返回结果)',
          attempted_fixes: ['xray_restart', 'ai_diagnosis']
        });
        return false;
      }

      default:
        console.log(`  ⚠️ 未知问题类型: ${problem.type}`);
        return false;
    }
  }

  // ═══ 接口4: alertZhuyuan() — "铸渊，我需要帮助" ═══
  async alertZhuyuan(alert) {
    const alertData = {
      module_id: this._moduleId,
      module_name: this._moduleName,
      level: alert.level || 'warning',
      message: alert.message,
      state: this._state,
      timestamp: new Date().toISOString(),
      details: alert,
      attempted_fixes: alert.attempted_fixes || [],
      nodes_status: this._nodes.map(n => ({
        id: n.id,
        status: n.status,
        consecutive_failures: n.consecutive_failures
      }))
    };

    // 通道1: 本地告警文件
    const alertFile = path.join(DATA_DIR, 'zy-cloud-vpn-alert.json');
    fs.writeFileSync(alertFile, JSON.stringify(alertData, null, 2));
    console.log(`  🚨 告警已记录: ${alertFile}`);

    // 通道2: 控制台输出 (PM2日志可见)
    console.error(`🚨🚨🚨 [ZY-CLOUD VPN 告警] ${alert.level}: ${alert.message}`);

    // 未来通道3: COS桶 → Notion SYSLOG → 冰朔
    // 未来通道4: 邮件告警 (send-subscription.js)
  }

  // ═══ 接口5: learnFromRun() — "我下次会做得更好" ═══
  async learnFromRun() {
    const now = new Date();
    const hour = now.getHours();
    const timeSlot = hour < 6 ? 'night' : hour < 12 ? 'morning' : hour < 18 ? 'afternoon' : 'evening';

    // 记录当前各节点的延迟
    for (const node of this._nodes) {
      if (node.status === 'online' && node.latency_ms !== null) {
        if (!this._learnDb.latency_history[node.id]) {
          this._learnDb.latency_history[node.id] = [];
        }

        this._learnDb.latency_history[node.id].push({
          latency_ms: node.latency_ms,
          time_slot: timeSlot,
          timestamp: now.toISOString()
        });

        // 只保留最近200条
        if (this._learnDb.latency_history[node.id].length > 200) {
          this._learnDb.latency_history[node.id] =
            this._learnDb.latency_history[node.id].slice(-200);
        }
      }
    }

    // 更新节点可靠性评分
    for (const node of this._nodes) {
      if (node.total_checks > 0) {
        const reliability = node.total_successes / node.total_checks;
        this._learnDb.reliability[node.id] = {
          score: parseFloat(reliability.toFixed(4)),
          total_checks: node.total_checks,
          total_successes: node.total_successes,
          updated_at: now.toISOString()
        };
      }
    }

    // 计算每个时段的最优节点
    for (const slot of ['night', 'morning', 'afternoon', 'evening']) {
      const avgLatencies = {};
      for (const [nodeId, history] of Object.entries(this._learnDb.latency_history)) {
        const slotRecords = history.filter(r => r.time_slot === slot);
        if (slotRecords.length > 0) {
          const avg = slotRecords.reduce((s, r) => s + r.latency_ms, 0) / slotRecords.length;
          avgLatencies[nodeId] = parseFloat(avg.toFixed(1));
        }
      }

      if (Object.keys(avgLatencies).length > 0) {
        const sorted = Object.entries(avgLatencies).sort((a, b) => a[1] - b[1]);
        this._learnDb.best_node_by_time[slot] = {
          best: sorted[0][0],
          avg_latency_ms: sorted[0][1],
          ranking: sorted.map(([id, lat]) => ({ id, avg_ms: lat }))
        };
      }
    }

    this._learnDb.updated_at = now.toISOString();
    this._learnDb.learn_count = (this._learnDb.learn_count || 0) + 1;

    // 保存学习数据
    this._saveLearnDb();

    console.log(`[ZY-CLOUD VPN] 📚 学习完成 (第${this._learnDb.learn_count}次)`);
    const currentBest = this._learnDb.best_node_by_time[timeSlot];
    if (currentBest) {
      console.log(`  当前时段(${timeSlot})最优: ${currentBest.best} (${currentBest.avg_latency_ms}ms)`);
    }
  }

  // ═══ 接口6: consultAI() — "我请教AI" (V3新增) ═══
  // 遇到复杂问题时调用LLM路由器进行深度推理
  // 三次重试机制:
  //   第1次: selfHeal 自动修复
  //   第2次: consultAI 调用LLM
  //   第3次: alertZhuyuan 邮件通知冰朔
  async consultAI(context) {
    let llmRouter;
    try {
      llmRouter = require('./llm-router');
    } catch {
      console.log('[ZY-CLOUD VPN] ⚠️ LLM路由器未加载，跳过AI推理');
      return null;
    }

    const prompt = `你是光湖语言世界VPN系统的AI诊断助手。
当前系统状态:
- 模块: ${this._moduleName}
- 状态: ${this._state}
- 总节点: ${this._nodes.length}
- 存活节点: ${this._liveNodes.length}
- 连续错误: ${this._consecutiveErrors}

问题上下文:
${JSON.stringify(context, null, 2).slice(0, 2000)}

请分析问题原因并给出具体的修复建议。要求:
1. 判断是网络层面还是服务层面的问题
2. 给出可执行的修复步骤
3. 评估问题严重程度(low/medium/high/critical)
回答要简洁明确。`;

    console.log('[ZY-CLOUD VPN] 🤖 调用AI推理...');
    const result = await llmRouter.callLLM(prompt, {
      systemPrompt: '你是光湖语言世界VPN系统的AI诊断引擎。你负责分析网络和代理服务的异常，给出精准的修复建议。',
      maxTokens: 800,
      timeout: 45000
    });

    if (result) {
      console.log(`[ZY-CLOUD VPN] 🤖 AI推理完成 (模型: ${result.model})`);
      console.log(`  建议: ${result.content.slice(0, 200)}...`);

      // 记录AI咨询历史
      this._history.push({
        type: 'consultAI',
        model: result.model,
        context_summary: context.type || 'unknown',
        response_preview: result.content.slice(0, 100),
        timestamp: new Date().toISOString()
      });

      // 只保留最近20条历史
      if (this._history.length > 20) {
        this._history = this._history.slice(-20);
      }
    } else {
      console.log('[ZY-CLOUD VPN] ⚠️ AI推理未返回结果');
    }

    return result;
  }

  // ── 应用学习数据优化节点排序 ────────────────
  _applyLearnedOptimization() {
    const now = new Date();
    const hour = now.getHours();
    const timeSlot = hour < 6 ? 'night' : hour < 12 ? 'morning' : hour < 18 ? 'afternoon' : 'evening';

    const bestData = this._learnDb.best_node_by_time[timeSlot];
    if (!bestData || !bestData.ranking) return;

    // 根据学习到的最优排序调整节点顺序
    // 但前提是延迟差异>10ms（否则保持原排序）
    const ranking = bestData.ranking;
    this._liveNodes.sort((a, b) => {
      const rankA = ranking.findIndex(r => r.id === a.id);
      const rankB = ranking.findIndex(r => r.id === b.id);
      if (rankA === -1 && rankB === -1) return 0;
      if (rankA === -1) return 1;
      if (rankB === -1) return -1;
      return rankA - rankB;
    });
  }

  // ── 学习数据库 ─────────────────────────────
  _loadLearnDb() {
    try {
      return JSON.parse(fs.readFileSync(LEARN_DB_FILE, 'utf8'));
    } catch {
      return {
        version: '1.0',
        created_at: new Date().toISOString(),
        updated_at: new Date().toISOString(),
        learn_count: 0,
        latency_history: {},
        reliability: {},
        best_node_by_time: {}
      };
    }
  }

  _saveLearnDb() {
    fs.mkdirSync(DATA_DIR, { recursive: true });
    fs.writeFileSync(LEARN_DB_FILE, JSON.stringify(this._learnDb, null, 2));
  }

  // ── 获取活节点列表（供外部调用）────────────
  getLiveNodes() {
    return this._liveNodes;
  }

  getLearnSummary() {
    return {
      learn_count: this._learnDb.learn_count,
      reliability: this._learnDb.reliability,
      best_by_time: this._learnDb.best_node_by_time
    };
  }
}

// ═══════════════════════════════════════════════
//  HTTP 管理端口 (3804)
//  供 subscription-server-v2 和外部查询
// ═══════════════════════════════════════════════
const MGMT_PORT = process.env.ZY_CLOUD_VPN_PORT || 3804;
const vpnModule = new ZyCloudVpn();

const mgmtServer = http.createServer((req, res) => {
  try {
    const parsedUrl = require('url').parse(req.url, true);
    const pathname = parsedUrl.pathname;

    // ── 活节点列表 (subscription-server-v2 调用) ──
    if (pathname === '/nodes' && req.method === 'GET') {
      res.writeHead(200, { 'Content-Type': 'application/json' });
      res.end(JSON.stringify({
        nodes: vpnModule.getLiveNodes().map(n => ({
          id: n.id, name: n.name, host: n.host, port: n.port,
          pbk: n.pbk, sid: n.sid, region: n.region,
          latency_ms: n.latency_ms, status: n.status, specs: n.specs
        })),
        updated_at: new Date().toISOString()
      }));
      return;
    }

    // ── 注册节点（像接路由器一样插入）──
    // POST /register { id, name, host, port, pbk, sid, region, specs }
    if (pathname === '/register' && req.method === 'POST') {
      let body = '';
      req.on('data', chunk => { body += chunk; });
      req.on('end', () => {
        try {
          const nodeData = JSON.parse(body);
          const node = vpnModule.registerNode(nodeData);
          res.writeHead(200, { 'Content-Type': 'application/json' });
          res.end(JSON.stringify({
            status: 'registered',
            node_id: node.id,
            name: node.name,
            message: `✅ 节点已注册: ${node.name} (${node.host}:${node.port})`
          }));
        } catch (err) {
          res.writeHead(400, { 'Content-Type': 'application/json' });
          res.end(JSON.stringify({ error: true, message: err.message }));
        }
      });
      return;
    }

    // ── 注销节点（拔掉路由器）──
    // DELETE /unregister?id=xxx 或 POST /unregister { id: "xxx" }
    if (pathname === '/unregister') {
      const handleUnregister = (nodeId) => {
        try {
          const removed = vpnModule.unregisterNode(nodeId);
          res.writeHead(200, { 'Content-Type': 'application/json' });
          res.end(JSON.stringify({
            status: 'unregistered',
            node_id: nodeId,
            message: `✅ 节点已注销: ${removed.name}`
          }));
        } catch (err) {
          res.writeHead(400, { 'Content-Type': 'application/json' });
          res.end(JSON.stringify({ error: true, message: err.message }));
        }
      };

      if (req.method === 'DELETE' || req.method === 'GET') {
        handleUnregister(parsedUrl.query.id);
        return;
      }
      if (req.method === 'POST') {
        let body = '';
        req.on('data', chunk => { body += chunk; });
        req.on('end', () => {
          try { handleUnregister(JSON.parse(body).id); }
          catch (err) { res.writeHead(400); res.end(err.message); }
        });
        return;
      }
    }

    // ── 接收HLDP heartbeat（自动注册VPN节点）──
    // POST /hldp/v3/heartbeat  { hldp_v: "3.0", msg_type: "heartbeat", ... }
    if (pathname === '/hldp/v3/heartbeat' && req.method === 'POST') {
      let body = '';
      req.on('data', chunk => { body += chunk; });
      req.on('end', () => {
        try {
          const hldpMsg = JSON.parse(body);
          const node = vpnModule.handleHldpHeartbeat(hldpMsg);

          // 发送HLDP ack回执
          res.writeHead(200, { 'Content-Type': 'application/json' });
          res.end(JSON.stringify({
            hldp_v: '3.0',
            msg_id: `HLDP-ZY-${new Date().toISOString().slice(0,10).replace(/-/g,'')}-ACK`,
            msg_type: 'ack',
            sender: { id: 'ICE-GL-ZY001', name: '铸渊', role: 'guardian' },
            receiver: hldpMsg.sender,
            timestamp: new Date().toISOString(),
            priority: 'routine',
            payload: {
              intent: node ? 'VPN节点心跳已接收·已注册' : '心跳已接收·非VPN节点',
              data: {
                ref_msg_id: hldpMsg.msg_id,
                status: node ? 'registered' : 'ignored',
                node_id: node ? node.id : null
              }
            }
          }));
        } catch (err) {
          res.writeHead(400, { 'Content-Type': 'application/json' });
          res.end(JSON.stringify({ error: true, message: err.message }));
        }
      });
      return;
    }

    // ── 注册表（所有注册过的节点，含离线）──
    if (pathname === '/registry' && req.method === 'GET') {
      res.writeHead(200, { 'Content-Type': 'application/json' });
      res.end(JSON.stringify({
        registered: vpnModule.listRegisteredNodes(),
        total: vpnModule.listRegisteredNodes().length,
        updated_at: new Date().toISOString()
      }));
      return;
    }

    // ── 心跳状态 ──
    if (pathname === '/health' || pathname === '/heartbeat') {
      try {
        const hb = JSON.parse(fs.readFileSync(HEARTBEAT_FILE, 'utf8'));
        res.writeHead(200, { 'Content-Type': 'application/json' });
        res.end(JSON.stringify(hb));
      } catch {
        res.writeHead(200, { 'Content-Type': 'application/json' });
        res.end(JSON.stringify({ status: 'starting', module: vpnModule._moduleId }));
      }
      return;
    }

    // ── 学习数据 ──
    if (pathname === '/learn') {
      res.writeHead(200, { 'Content-Type': 'application/json' });
      res.end(JSON.stringify(vpnModule.getLearnSummary()));
      return;
    }

    // ── 完整状态 ──
    if (pathname === '/status') {
      res.writeHead(200, { 'Content-Type': 'application/json' });
      res.end(JSON.stringify({
        module: vpnModule._moduleId,
        brand: '光湖语言世界 — 冰朔开发维护',
        version: '3.0.0',
        state: vpnModule._state,
        started_at: vpnModule._startedAt,
        uptime_seconds: Math.floor((Date.now() - new Date(vpnModule._startedAt).getTime()) / 1000),
        total_nodes: vpnModule._nodes.length,
        live_nodes: vpnModule._liveNodes.length,
        registered_nodes: vpnModule.listRegisteredNodes().length,
        nodes: vpnModule._nodes.map(n => ({
          id: n.id, name: n.name, status: n.status,
          latency_ms: n.latency_ms, consecutive_failures: n.consecutive_failures,
          reliability: n.total_checks > 0
            ? parseFloat((n.total_successes / n.total_checks).toFixed(4))
            : null,
          last_check: n.last_check
        })),
        learn: vpnModule.getLearnSummary(),
        endpoints: {
          nodes: 'GET /nodes — 活节点列表',
          register: 'POST /register — 注册新节点',
          unregister: 'POST /unregister — 注销节点',
          hldp_heartbeat: 'POST /hldp/v3/heartbeat — HLDP心跳(自动注册)',
          registry: 'GET /registry — 注册表',
          health: 'GET /health — 心跳',
          learn: 'GET /learn — 学习数据',
          status: 'GET /status — 完整状态'
        },
        updated_at: new Date().toISOString()
      }));
      return;
    }

    res.writeHead(404, { 'Content-Type': 'text/plain' });
    res.end('Not Found');
  } catch (err) {
    console.error('管理端口错误:', err.message);
    if (!res.headersSent) {
      res.writeHead(500, { 'Content-Type': 'text/plain' });
    }
    res.end('Internal Error');
  }
});

mgmtServer.listen(MGMT_PORT, '127.0.0.1', () => {
  console.log(`💪 ZY-CLOUD VPN 管理端口: http://127.0.0.1:${MGMT_PORT}`);
  console.log(`  ── 查询接口 ──`);
  console.log(`  GET  /nodes       — 活节点列表 (订阅服务调用)`);
  console.log(`  GET  /health      — 心跳状态`);
  console.log(`  GET  /learn       — 学习数据`);
  console.log(`  GET  /status      — 完整状态`);
  console.log(`  GET  /registry    — 注册表`);
  console.log(`  ── 注册接口 (像路由器一样插入) ──`);
  console.log(`  POST /register    — 注册新VPN节点`);
  console.log(`  POST /unregister  — 注销VPN节点`);
  console.log(`  POST /hldp/v3/heartbeat — HLDP心跳(自动注册)`);

  // 启动活模块生命周期
  vpnModule.startLifeCycle();
});

// Graceful shutdown
function gracefulShutdown(signal) {
  console.log(`\n${signal} received. Shutting down ZY-CLOUD VPN...`);
  vpnModule.destroy();
  const forceExit = setTimeout(() => process.exit(1), 5000);
  mgmtServer.close(() => {
    clearTimeout(forceExit);
    process.exit(0);
  });
}
process.on('SIGTERM', () => gracefulShutdown('SIGTERM'));
process.on('SIGINT', () => gracefulShutdown('SIGINT'));
process.on('uncaughtException', (err) => {
  console.error('❌ 未捕获异常:', err.message);
  console.error(err.stack);
  gracefulShutdown('uncaughtException');
});
process.on('unhandledRejection', (reason) => {
  console.error('❌ 未处理的Promise拒绝:', reason);
});

// 导出 (供测试和其他模块使用)
module.exports = { ZyCloudVpn, LivingModule };
