/**
 * Gestionnaire global des erreurs pour MediFlash SOS+
 */

export class ErrorHandler {
  private static errors: Array<{
    id: string;
    message: string;
    stack?: string;
    timestamp: Date;
    type: 'error' | 'warning' | 'info';
    context?: Record<string, any>;
  }> = [];

  static logError(error: Error | string, context?: Record<string, any>) {
    const errorEntry = {
      id: crypto.randomUUID(),
      message: typeof error === 'string' ? error : error.message,
      stack: typeof error !== 'string' ? error.stack : undefined,
      timestamp: new Date(),
      type: 'error' as const,
      context
    };

    this.errors.unshift(errorEntry);
    
    // Garder seulement les 100 dernières erreurs
    if (this.errors.length > 100) {
      this.errors = this.errors.slice(0, 100);
    }

    // Log en console pour le développement
    if (process.env.NODE_ENV === 'development') {
      console.error('[ErrorHandler]', errorEntry);
    }
  }

  static logWarning(message: string, context?: Record<string, any>) {
    const warningEntry = {
      id: crypto.randomUUID(),
      message,
      timestamp: new Date(),
      type: 'warning' as const,
      context
    };

    this.errors.unshift(warningEntry);
    
    if (this.errors.length > 100) {
      this.errors = this.errors.slice(0, 100);
    }

    if (process.env.NODE_ENV === 'development') {
      console.warn('[ErrorHandler]', warningEntry);
    }
  }

  static getErrors() {
    return [...this.errors];
  }

  static clearErrors() {
    this.errors = [];
  }
}

// Gestionnaire global pour les promesses rejetées non gérées
if (typeof window !== 'undefined') {
  window.addEventListener('unhandledrejection', (event) => {
    ErrorHandler.logError(
      event.reason instanceof Error ? event.reason : new Error(String(event.reason)),
      { type: 'unhandledrejection', url: window.location.href }
    );
    
    // Empêcher l'affichage de l'erreur dans la console par défaut
    event.preventDefault();
  });

  window.addEventListener('error', (event) => {
    ErrorHandler.logError(
      new Error(event.message),
      { 
        type: 'globalError', 
        filename: event.filename, 
        lineno: event.lineno, 
        colno: event.colno,
        url: window.location.href
      }
    );
  });
}

// Wrapper pour les fonctions async pour capturer les erreurs
export function withErrorHandling<T extends (...args: any[]) => Promise<any>>(
  fn: T,
  context?: string
): T {
  return (async (...args: Parameters<T>) => {
    try {
      return await fn(...args);
    } catch (error) {
      ErrorHandler.logError(
        error instanceof Error ? error : new Error(String(error)),
        { context, args: args.slice(0, 3) } // Limiter les args pour éviter les objets trop volumineux
      );
      throw error;
    }
  }) as T;
}