/**
 * Request Context Manager
 * Provides correlation IDs and metadata for tracking requests across the system
 */

export interface RequestContext {
  requestId: string;
  userId?: string;
  timestamp: string;
  userAgent?: string;
  clientVersion?: string;
  traceId?: string; // For distributed tracing across multiple requests
}

export interface RequestMetadata {
  endpoint: string;
  method: string;
  statusCode?: number;
  duration?: number;
  error?: {
    type: string;
    message: string;
  };
}

class RequestContextManager {
  private contexts = new Map<string, RequestContext>();
  private readonly MAX_CONTEXTS = 1000; // Prevent memory leaks

  create(userId?: string, traceId?: string): RequestContext {
    // Cleanup old contexts if limit reached
    if (this.contexts.size >= this.MAX_CONTEXTS) {
      const firstKey = this.contexts.keys().next().value;
      if (firstKey) this.contexts.delete(firstKey);
    }

    const context: RequestContext = {
      requestId: crypto.randomUUID(),
      userId,
      timestamp: new Date().toISOString(),
      userAgent: typeof navigator !== 'undefined' ? navigator.userAgent : undefined,
      clientVersion: import.meta.env.VITE_APP_VERSION || '1.0.0',
      traceId: traceId || crypto.randomUUID(),
    };
    
    this.contexts.set(context.requestId, context);
    return context;
  }

  get(requestId: string): RequestContext | undefined {
    return this.contexts.get(requestId);
  }

  cleanup(requestId: string): void {
    this.contexts.delete(requestId);
  }

  // Get current context from thread-local storage pattern
  getCurrentContext(): RequestContext | undefined {
    // This is a simplified version - in production you'd use AsyncLocalStorage equivalent
    const keys = Array.from(this.contexts.keys());
    return keys.length > 0 ? this.contexts.get(keys[keys.length - 1]) : undefined;
  }
}

export const requestContext = new RequestContextManager();
