'use strict';

function createSessionDiagnostics({ limit = 80, clock = () => Date.now() } = {}) {
  const rings = new Map();
  const cap = Math.max(1, Math.min(Number(limit) || 80, 500));

  function record(sessionId, event, details = {}) {
    const id = String(sessionId || '').trim();
    if (!id) return null;
    const entry = {
      ts: clock(),
      event: String(event || 'event'),
      ...sanitizeDetails(details),
    };
    const ring = rings.get(id) || [];
    ring.push(entry);
    while (ring.length > cap) ring.shift();
    rings.set(id, ring);
    return entry;
  }

  function get(sessionId) {
    const id = String(sessionId || '').trim();
    return [...(rings.get(id) || [])];
  }

  function clear(sessionId) {
    rings.delete(String(sessionId || '').trim());
  }

  return { record, get, clear };
}

function sanitizeDetails(details) {
  const out = {};
  for (const [key, value] of Object.entries(details || {})) {
    if (value == null) continue;
    if (typeof value === 'string') {
      out[key] = value.length > 500 ? `${value.slice(0, 497)}...` : value;
    } else if (typeof value === 'number' || typeof value === 'boolean') {
      out[key] = value;
    } else if (Array.isArray(value)) {
      out[key] = value.slice(0, 20).map((item) => (
        typeof item === 'string' && item.length > 200 ? `${item.slice(0, 197)}...` : item
      ));
    } else if (typeof value === 'object') {
      out[key] = sanitizeDetails(value);
    }
  }
  return out;
}

module.exports = {
  createSessionDiagnostics,
  sanitizeDetails,
};
