/**
 * 性能监控模块
 * 监控各服务进程的 CPU、内存使用情况
 */

import pidusage from 'pidusage';
import { processManager } from './process-manager.js';
import { SERVICES } from './config.js';

class PerformanceMonitor {
  constructor() {
    /** @type {Map<string, Array<{ts: number, cpu: number, mem: number}>>} */
    this.history = new Map();
    this.interval = null;

    // Ring buffer for actual HTTP request latencies (ms)
    this.latencyBuffer = [];
    this.maxLatencySamples = 500;

    for (const id of Object.keys(SERVICES)) {
      this.history.set(id, []);
    }
  }

  /** Record an HTTP request duration (ms). Called by middleware. */
  recordLatency(durationMs) {
    this.latencyBuffer.push(durationMs);
    if (this.latencyBuffer.length > this.maxLatencySamples) {
      this.latencyBuffer.splice(0, this.latencyBuffer.length - this.maxLatencySamples);
    }
  }

  /** Get average request latency from recent samples. Returns null if no data. */
  getAverageLatency() {
    if (this.latencyBuffer.length === 0) return null;
    const sum = this.latencyBuffer.reduce((a, b) => a + b, 0);
    return Math.round(sum / this.latencyBuffer.length);
  }

  /**
   * 开始定期采样 (每3秒)
   */
  start() {
    if (this.interval) return;
    this.interval = setInterval(() => this.sample(), 3000);
    this.interval.unref(); // 不阻止进程退出
  }

  /**
   * 停止采样
   */
  stop() {
    if (this.interval) {
      clearInterval(this.interval);
      this.interval = null;
    }
  }

  /**
   * 采样一次
   */
  async sample() {
    for (const [id, info] of processManager.processes) {
      if (!info.pid) continue;
      try {
        const stats = await pidusage(info.pid);
        const history = this.history.get(id);
        history.push({
          ts: Date.now(),
          cpu: Math.round(stats.cpu * 100) / 100,
          mem: Math.round(stats.memory / 1024 / 1024 * 100) / 100, // MB
        });
        // 保留最近300条 (约15分钟)
        if (history.length > 300) {
          history.splice(0, history.length - 300);
        }
      } catch {
        // 进程可能已退出
      }
    }
  }

  /**
   * 获取当前性能快照
   */
  async getSnapshot() {
    const result = {};
    for (const [id, info] of processManager.processes) {
      if (!info.pid) {
        result[id] = { pid: null, cpu: 0, mem: 0 };
        continue;
      }
      try {
        const stats = await pidusage(info.pid);
        result[id] = {
          pid: info.pid,
          cpu: Math.round(stats.cpu * 100) / 100,
          mem: Math.round(stats.memory / 1024 / 1024 * 100) / 100,
          elapsed: stats.elapsed,
        };
      } catch {
        result[id] = { pid: info.pid, cpu: 0, mem: 0 };
      }
    }
    return result;
  }

  /**
   * 获取历史数据
   */
  getHistory(serviceId) {
    return this.history.get(serviceId) || [];
  }

  /**
   * 获取所有服务的历史数据
   */
  getAllHistory() {
    const result = {};
    for (const id of this.history.keys()) {
      result[id] = this.history.get(id);
    }
    return result;
  }

  /**
   * 更新仪表盘数据 — 返回聚合的性能摘要供首页仪表盘使用
   * 调用方负责将数据渲染到 #performance-dashboard 元素
   * @returns {object} 仪表盘性能摘要
   */
  async updateDashboard() {
    const snapshot = await this.getSnapshot();
    const entries = Object.entries(snapshot);

    let totalCpu = 0, totalMem = 0, activeCount = 0;
    for (const [, p] of entries) {
      totalCpu += p.cpu || 0;
      totalMem += p.mem || 0;
      if (p.pid) activeCount++;
    }

    const avgCpu = entries.length > 0 ? Math.round(totalCpu / entries.length * 10) / 10 : 0;
    const totalMemRounded = Math.round(totalMem * 100) / 100;

    // 计算平均请求延迟 (基于实际 HTTP 请求耗时，非进程 uptime)
    const avgLatencyMs = this.getAverageLatency();

    // 获取最近历史用于趋势判断
    const recentHistory = this.getAllHistory();
    let trendCpu = 'stable', trendMem = 'stable';
    for (const [, hist] of Object.entries(recentHistory)) {
      if (hist.length < 5) continue;
      const recent = hist.slice(-5);
      const firstCpu = recent[0].cpu, lastCpu = recent[recent.length - 1].cpu;
      const firstMem = recent[0].mem, lastMem = recent[recent.length - 1].mem;
      if (lastCpu > firstCpu * 1.15) trendCpu = 'up';
      else if (lastCpu < firstCpu * 0.85) trendCpu = 'down';
      if (lastMem > firstMem * 1.15) trendMem = 'up';
      else if (lastMem < firstMem * 0.85) trendMem = 'down';
    }

    return {
      timestamp: Date.now(),
      summary: {
        avgCpu,
        totalMemMB: totalMemRounded,
        activeProcesses: activeCount,
        monitoredServices: entries.length,
        avgLatencyMs,
        trend: { cpu: trendCpu, mem: trendMem },
      },
      perService: snapshot,
    };
  }
}

export const performanceMonitor = new PerformanceMonitor();
