const client = require('prom-client');

const register = new client.Registry();

client.collectDefaultMetrics({
  prefix: 'ped_ai_',
  register
});

const httpRequestsTotal = new client.Counter({
  name: 'ped_ai_http_requests_total',
  help: 'Total HTTP requests received by Ped-AI',
  labelNames: ['method', 'route', 'status_code'],
  registers: [register]
});

const httpRequestDuration = new client.Histogram({
  name: 'ped_ai_http_request_duration_seconds',
  help: 'HTTP request duration in seconds',
  labelNames: ['method', 'route', 'status_code'],
  buckets: [0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10],
  registers: [register]
});

const httpRequestsInProgress = new client.Gauge({
  name: 'ped_ai_http_requests_in_progress',
  help: 'Number of Ped-AI HTTP requests currently in progress',
  labelNames: ['method', 'route'],
  registers: [register]
});

function normalizeRoute(req, statusCode) {
  var routePath = req.route && req.route.path;
  var baseUrl = req.baseUrl || '';
  if (Array.isArray(routePath)) return baseUrl + routePath[0];
  if (routePath) return baseUrl + routePath;
  if (statusCode === 404) return 'unmatched';

  var path = req.path || req.url || 'unknown';
  return path
    .replace(/\b[0-9a-f]{8,}\b/gi, ':id')
    .replace(/\b\d+\b/g, ':id')
    .replace(/\?.*$/, '');
}

function metricsMiddleware(req, res, next) {
  if (req.path === '/metrics') return next();

  var route = req.route ? normalizeRoute(req) : 'pending';
  var method = req.method;
  var endTimer = httpRequestDuration.startTimer({ method, route });
  httpRequestsInProgress.inc({ method, route });

  res.on('finish', function() {
    var finalRoute = normalizeRoute(req, res.statusCode);
    var labels = {
      method,
      route: finalRoute,
      status_code: String(res.statusCode)
    };
    httpRequestsTotal.inc(labels);
    endTimer({ route: finalRoute, status_code: String(res.statusCode) });
    httpRequestsInProgress.dec({ method, route });
  });

  next();
}

async function metricsHandler(req, res) {
  res.setHeader('Content-Type', register.contentType);
  res.end(await register.metrics());
}

module.exports = {
  metricsHandler,
  metricsMiddleware,
  register
};
