/**
 * Configuration globale des optimisations de performance
 */

import { QueryClient } from '@tanstack/react-query';

// Configuration optimisée pour React Query
export const createOptimizedQueryClient = () => {
  return new QueryClient({
    defaultOptions: {
      queries: {
        // Configuration par défaut pour toutes les queries
        staleTime: 5 * 60 * 1000, // 5 minutes
        gcTime: 30 * 60 * 1000,   // 30 minutes  
        retry: 2,
        refetchOnWindowFocus: false,
        refetchOnReconnect: true,
        
        // Fonction de retry intelligente
        retryDelay: (attemptIndex) => Math.min(1000 * 2 ** attemptIndex, 30000),
      },
      mutations: {
        // Retry pour les mutations critiques uniquement
        retry: (failureCount, error: any) => {
          // Retry seulement pour les erreurs réseau, pas les erreurs 4xx
          if (error?.status >= 400 && error?.status < 500) return false;
          return failureCount < 2;
        },
      },
    },
  });
};

// Utilitaires de performance pour les composants
export const PerformanceUtils = {
  // Debounce pour les inputs de recherche
  debounce: <T extends (...args: any[]) => any>(func: T, wait: number): T => {
    let timeout: NodeJS.Timeout;
    return ((...args: Parameters<T>) => {
      clearTimeout(timeout);
      timeout = setTimeout(() => func(...args), wait);
    }) as T;
  },

  // Throttle pour les events de scroll
  throttle: <T extends (...args: any[]) => any>(func: T, limit: number): T => {
    let inThrottle: boolean;
    return ((...args: Parameters<T>) => {
      if (!inThrottle) {
        func(...args);
        inThrottle = true;
        setTimeout(() => (inThrottle = false), limit);
      }
    }) as T;
  },

  // Mesure du temps d'exécution d'une fonction
  measureTime: async <T>(name: string, fn: () => Promise<T>): Promise<T> => {
    const start = performance.now();
    try {
      const result = await fn();
      const duration = performance.now() - start;
      console.log(`[PERF] ${name}: ${duration.toFixed(2)}ms`);
      return result;
    } catch (error) {
      const duration = performance.now() - start;
      console.error(`[PERF ERROR] ${name}: ${duration.toFixed(2)}ms`, error);
      throw error;
    }
  },

  // Lazy loading pour les images
  createIntersectionObserver: (callback: (entries: IntersectionObserverEntry[]) => void) => {
    return new IntersectionObserver(callback, {
      root: null,
      rootMargin: '50px',
      threshold: 0.1,
    });
  },

  // Préchargement intelligent des données
  prefetchData: (queryClient: QueryClient, queryKey: string[], queryFn: () => Promise<any>) => {
    queryClient.prefetchQuery({
      queryKey,
      queryFn,
      staleTime: 10 * 60 * 1000, // 10 minutes pour les données préchargées
    });
  }
};

// Configuration des optimisations réseau
export const NetworkOptimizations = {
  // Headers optimaux pour les requêtes API
  getOptimalHeaders: () => ({
    'Accept': 'application/json',
    'Accept-Encoding': 'gzip, deflate, br',
    'Cache-Control': 'no-cache',
    'Connection': 'keep-alive',
  }),

  // Configuration Fetch optimisée
  createOptimizedFetch: () => {
    return async (url: string, options: RequestInit = {}) => {
      const optimizedOptions: RequestInit = {
        ...options,
        headers: {
          ...NetworkOptimizations.getOptimalHeaders(),
          ...options.headers,
        },
        // Timeout par défaut de 10 secondes
        signal: options.signal || AbortSignal.timeout(10000),
      };

      const response = await fetch(url, optimizedOptions);
      
      // Log des réponses lentes
      const responseTime = performance.now();
      if (responseTime > 2000) {
        console.warn(`[SLOW NETWORK] ${url}: ${responseTime}ms`);
      }

      return response;
    };
  }
};

// Bundle optimization hints pour Vite
export const BundleOptimizations = {
  // Composants à lazy load
  lazyComponents: [
    'AdminDashboard',
    'PharmacyAnalytics',
    'CourierDashboard',
    'OrderTracking'
  ],

  // Modules à précharger
  preloadModules: [
    'react-query',
    'lucide-react',
    '@radix-ui/react-dialog'
  ],

  // Configuration du code splitting
  chunkSizeWarningLimit: 1000, // 1MB max par chunk
};

// Métriques de performance personnalisées
export class PerformanceMetrics {
  private static metrics = new Map<string, number[]>();

  static record(key: string, value: number) {
    if (!this.metrics.has(key)) {
      this.metrics.set(key, []);
    }
    const values = this.metrics.get(key)!;
    values.push(value);
    
    // Garder seulement les 100 dernières valeurs
    if (values.length > 100) {
      values.shift();
    }
  }

  static getAverage(key: string): number {
    const values = this.metrics.get(key) || [];
    if (values.length === 0) return 0;
    return values.reduce((sum, val) => sum + val, 0) / values.length;
  }

  static getP95(key: string): number {
    const values = this.metrics.get(key) || [];
    if (values.length === 0) return 0;
    const sorted = [...values].sort((a, b) => a - b);
    const index = Math.floor(sorted.length * 0.95);
    return sorted[index] || 0;
  }

  static getAllMetrics(): Record<string, { average: number; p95: number; count: number }> {
    const result: Record<string, { average: number; p95: number; count: number }> = {};
    
    for (const [key] of this.metrics) {
      result[key] = {
        average: this.getAverage(key),
        p95: this.getP95(key),
        count: (this.metrics.get(key) || []).length
      };
    }
    
    return result;
  }

  static clear(key?: string) {
    if (key) {
      this.metrics.delete(key);
    } else {
      this.metrics.clear();
    }
  }
}

// Hook d'initialisation des optimisations
export const initializePerformanceOptimizations = () => {
  // Mesurer les Core Web Vitals
  if (typeof window !== 'undefined' && 'performance' in window) {
    // First Contentful Paint
    const paintObserver = new PerformanceObserver((list) => {
      for (const entry of list.getEntries()) {
        if (entry.name === 'first-contentful-paint') {
          PerformanceMetrics.record('FCP', entry.startTime);
        }
      }
    });
    paintObserver.observe({ entryTypes: ['paint'] });

    // Largest Contentful Paint
    const lcpObserver = new PerformanceObserver((list) => {
      const entries = list.getEntries();
      const lastEntry = entries[entries.length - 1];
      PerformanceMetrics.record('LCP', lastEntry.startTime);
    });
    lcpObserver.observe({ entryTypes: ['largest-contentful-paint'] });

    // Layout shifts
    const clsObserver = new PerformanceObserver((list) => {
      let clsValue = 0;
      for (const entry of list.getEntries() as any[]) {
        if (!entry.hadRecentInput) {
          clsValue += entry.value;
        }
      }
      PerformanceMetrics.record('CLS', clsValue);
    });
    clsObserver.observe({ entryTypes: ['layout-shift'] });
  }

  console.log('[PERFORMANCE] Optimizations initialized');
};