import type { APIRoute } from 'astro';

// Module-level counters (persist across requests within same process)
let requestCount = 0;
let errorCount = 0;
const processStartTime = Date.now();

// Simple response time tracking (last 100 samples)
const responseTimes: number[] = [];
const MAX_SAMPLES = 100;

export function recordRequest(durationMs: number, isError = false) {
  requestCount++;
  if (isError) errorCount++;
  responseTimes.push(durationMs);
  if (responseTimes.length > MAX_SAMPLES) responseTimes.shift();
}

function percentile(sorted: number[], p: number): number {
  if (sorted.length === 0) return 0;
  const idx = Math.ceil((p / 100) * sorted.length) - 1;
  return sorted[Math.max(0, idx)];
}

export const GET: APIRoute = async ({ request }) => {
  // Restrict metrics to internal/authorized access only
  const authHeader = request.headers.get('Authorization');
  const metricsToken = import.meta.env.METRICS_TOKEN;

  if (metricsToken && authHeader !== `Bearer ${metricsToken}`) {
    return new Response(JSON.stringify({ error: 'Unauthorized' }), {
      status: 401,
      headers: { 'Content-Type': 'application/json' },
    });
  }

  const memUsage = process.memoryUsage();
  const uptimeSeconds = Math.floor((Date.now() - processStartTime) / 1000);

  const sorted = [...responseTimes].sort((a, b) => a - b);
  const avgResponseTime = sorted.length > 0
    ? Math.round(sorted.reduce((a, b) => a + b, 0) / sorted.length)
    : 0;

  const metrics = {
    timestamp: new Date().toISOString(),
    uptime: {
      seconds: uptimeSeconds,
      human: formatUptime(uptimeSeconds),
    },
    requests: {
      total: requestCount,
      errors: errorCount,
      errorRate: requestCount > 0 ? ((errorCount / requestCount) * 100).toFixed(2) + '%' : '0%',
    },
    responseTime: {
      avgMs: avgResponseTime,
      p50Ms: percentile(sorted, 50),
      p95Ms: percentile(sorted, 95),
      p99Ms: percentile(sorted, 99),
      samples: sorted.length,
    },
    memory: {
      heapUsedMB: Math.round(memUsage.heapUsed / 1024 / 1024),
      heapTotalMB: Math.round(memUsage.heapTotal / 1024 / 1024),
      externalMB: Math.round(memUsage.external / 1024 / 1024),
      rssMB: Math.round(memUsage.rss / 1024 / 1024),
    },
    process: {
      pid: process.pid,
      nodeVersion: process.version,
      platform: process.platform,
    },
  };

  return new Response(JSON.stringify(metrics, null, 2), {
    status: 200,
    headers: {
      'Content-Type': 'application/json',
      'Cache-Control': 'no-cache, no-store, must-revalidate',
    },
  });
};

function formatUptime(seconds: number): string {
  const d = Math.floor(seconds / 86400);
  const h = Math.floor((seconds % 86400) / 3600);
  const m = Math.floor((seconds % 3600) / 60);
  const s = seconds % 60;
  const parts = [];
  if (d > 0) parts.push(`${d}d`);
  if (h > 0) parts.push(`${h}h`);
  if (m > 0) parts.push(`${m}m`);
  parts.push(`${s}s`);
  return parts.join(' ');
}
