/**
 * Simple metrics collector for DashCaddy API
 * Tracks request counts, durations, errors, and business metrics
 * No external dependencies — all in-memory
 */

class Metrics {
  constructor() {
    this.startTime = Date.now();
    this.requests = {
      total: 0,
      byStatus: {},
      byMethod: {},
      byPath: {}
    };
    this.errors = {
      total: 0,
      byType: {}
    };
    this.business = {
      containersDeployed: 0,
      containersDeleted: 0,
      containerUpdates: 0,
      dnsRecordsCreated: 0,
      backupsCreated: 0,
      totpLogins: 0,
      siteAdded: 0,
      siteRemoved: 0,
      credentialRotations: 0
    };
  }

  recordRequest(method, path, statusCode, durationMs) {
    this.requests.total++;
    this.requests.byStatus[statusCode] = (this.requests.byStatus[statusCode] || 0) + 1;
    this.requests.byMethod[method] = (this.requests.byMethod[method] || 0) + 1;

    const normalized = this.normalizePath(path);
    if (!this.requests.byPath[normalized]) {
      this.requests.byPath[normalized] = { count: 0, totalDuration: 0 };
    }
    const entry = this.requests.byPath[normalized];
    entry.count++;
    entry.totalDuration += durationMs;
  }

  recordError(errorType) {
    this.errors.total++;
    this.errors.byType[errorType] = (this.errors.byType[errorType] || 0) + 1;
  }

  recordBusinessEvent(eventType) {
    if (eventType in this.business) {
      this.business[eventType]++;
    }
  }

  normalizePath(p) {
    return p
      .replace(/\/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/gi, '/:id')
      .replace(/\/[0-9a-f]{12,}/gi, '/:id')
      .replace(/\/\d+/g, '/:n');
  }

  getSummary() {
    const uptimeMs = Date.now() - this.startTime;
    const uptimeSec = Math.floor(uptimeMs / 1000);

    const topEndpoints = Object.entries(this.requests.byPath)
      .sort((a, b) => b[1].count - a[1].count)
      .slice(0, 15)
      .map(([path, s]) => ({ path, count: s.count, avgMs: Math.round(s.totalDuration / s.count) }));

    return {
      uptime: { ms: uptimeMs, human: this.formatUptime(uptimeSec) },
      requests: {
        total: this.requests.total,
        perSecond: uptimeSec > 0 ? +(this.requests.total / uptimeSec).toFixed(2) : 0,
        byStatus: this.requests.byStatus,
        byMethod: this.requests.byMethod,
        topEndpoints
      },
      errors: {
        total: this.errors.total,
        rate: this.requests.total > 0 ? +((this.errors.total / this.requests.total) * 100).toFixed(2) : 0,
        byType: this.errors.byType
      },
      business: this.business,
      process: {
        memory: process.memoryUsage(),
        pid: process.pid,
        nodeVersion: process.version
      }
    };
  }

  formatUptime(sec) {
    const d = Math.floor(sec / 86400);
    const h = Math.floor((sec % 86400) / 3600);
    const m = Math.floor((sec % 3600) / 60);
    const s = sec % 60;
    if (d > 0) return `${d}d ${h}h ${m}m`;
    if (h > 0) return `${h}h ${m}m ${s}s`;
    if (m > 0) return `${m}m ${s}s`;
    return `${s}s`;
  }

  reset() {
    this.startTime = Date.now();
    this.requests = { total: 0, byStatus: {}, byMethod: {}, byPath: {} };
    this.errors = { total: 0, byType: {} };
  }
}

module.exports = new Metrics();
