import { randomUUID } from 'node:crypto';

const startedAt = new Date().toISOString();
const telemetry = {
  total: 0, active: 0, errors: 0, blocked: 0,
  by_status: {}, by_method: {}, last_error_at: null, last_blocked_at: null,
  recent: [],
};

function safePath(req) { return String(req.path || req.url || '').split('?')[0].slice(0, 300); }
function enabled() { return !/^(0|false|no)$/i.test(String(process.env.VENDOO_JSON_LOGS || 'true')); }

export function recordSecurityBlock(reason) {
  telemetry.blocked += 1;
  telemetry.last_blocked_at = new Date().toISOString();
  if (enabled()) console.warn(JSON.stringify({ level: 'warn', event: 'security.blocked', reason, time: telemetry.last_blocked_at }));
}

export function requestContextMiddleware(req, res, next) {
  const requestId = String(req.get('x-vendoo-request-id') || randomUUID()).replace(/[^a-zA-Z0-9._:-]/g, '').slice(0, 100) || randomUUID();
  const correlationId = String(req.get('x-correlation-id') || requestId).replace(/[^a-zA-Z0-9._:-]/g, '').slice(0, 100) || requestId;
  const started = process.hrtime.bigint();
  req.requestId = requestId;
  req.correlationId = correlationId;
  res.setHeader('X-Vendoo-Request-ID', requestId);
  res.setHeader('X-Correlation-ID', correlationId);
  telemetry.total += 1; telemetry.active += 1;
  telemetry.by_method[req.method] = (telemetry.by_method[req.method] || 0) + 1;
  res.on('finish', () => {
    telemetry.active = Math.max(0, telemetry.active - 1);
    const durationMs = Number(process.hrtime.bigint() - started) / 1e6;
    const status = String(res.statusCode);
    telemetry.by_status[status] = (telemetry.by_status[status] || 0) + 1;
    if (res.statusCode >= 500) { telemetry.errors += 1; telemetry.last_error_at = new Date().toISOString(); }
    const entry = {
      time: new Date().toISOString(), request_id: requestId, correlation_id: correlationId,
      method: req.method, path: safePath(req), status: res.statusCode,
      duration_ms: Math.round(durationMs * 10) / 10, user_id: req.user?.id || null,
    };
    telemetry.recent.unshift(entry); telemetry.recent = telemetry.recent.slice(0, 50);
    if (enabled()) console.log(JSON.stringify({ level: res.statusCode >= 500 ? 'error' : 'info', event: 'http.request', ...entry }));
  });
  next();
}

export function getRequestTelemetry() {
  return { started_at: startedAt, ...telemetry, recent: telemetry.recent.map(item => ({ ...item })) };
}
