const MAX_SAMPLES = 1_000;

export interface BucketStats {
  p50: number | null;
  p95: number | null;
  count: number;
}

export class LatencyHistogram {
  private readonly buckets = new Map<string, number[]>();

  record(route: string, durationMs: number): void {
    let bucket = this.buckets.get(route);
    if (!bucket) {
      bucket = [];
      this.buckets.set(route, bucket);
    }
    if (bucket.length >= MAX_SAMPLES) {
      bucket.shift();
    }
    bucket.push(durationMs);
  }

  percentile(route: string, pct: number): number | null {
    const bucket = this.buckets.get(route);
    if (!bucket || bucket.length === 0) return null;
    const sorted = [...bucket].sort((a, b) => a - b);
    const idx = Math.floor((pct / 100) * sorted.length);
    return sorted[Math.min(idx, sorted.length - 1)] ?? null;
  }

  snapshot(): Record<string, BucketStats> {
    const out: Record<string, BucketStats> = {};
    for (const [route, bucket] of this.buckets.entries()) {
      out[route] = {
        p50: this.percentile(route, 50),
        p95: this.percentile(route, 95),
        count: bucket.length,
      };
    }
    return out;
  }
}

export const latencyHistogram = new LatencyHistogram();
