import React, { lazy, Suspense } from 'react';
import { memoize } from './PerformanceOptimizer';
import { intelligentPreloader, resourceHints } from './BundleOptimizer';

// Função para criar componentes lazy com preload otimizado
const createOptimizedLazyComponent = (importFn: () => Promise<{ default: React.ComponentType<any> }>, key: string) => {
  const LazyComponent = lazy(importFn);
  
  // Registrar para preload inteligente
  intelligentPreloader.register(key, importFn);
  
  // Adicionar método de preload manual
  (LazyComponent as any).preload = importFn;
  
  return LazyComponent;
};

// Lazy loading dos componentes pesados para otimizar bundle
export const DualGameViewer = createOptimizedLazyComponent(() => import('../components/DualGameViewer'), 'DualGameViewer');
export const Statistics = createOptimizedLazyComponent(() => import('../components/Statistics'), 'Statistics');
export const ResultsAnalysis = createOptimizedLazyComponent(() => import('../components/ResultsAnalysis'), 'ResultsAnalysis');
export const ProbabilityCalculator = createOptimizedLazyComponent(() => import('../components/ProbabilityCalculator'), 'ProbabilityCalculator');
export const EnhancedLotomaniaGrid = createOptimizedLazyComponent(() => import('../components/EnhancedLotomaniaGrid'), 'EnhancedLotomaniaGrid');
export const LotomaniaFeatures = createOptimizedLazyComponent(() => import('../components/LotomaniaFeatures'), 'LotomaniaFeatures');
export const PrizeAnalysis = createOptimizedLazyComponent(() => import('../components/PrizeAnalysis'), 'PrizeAnalysis');
export const GameProfitabilityAnalysis = createOptimizedLazyComponent(() => import('../components/GameProfitabilityAnalysis'), 'GameProfitabilityAnalysis');
export const HistoricalTrends = createOptimizedLazyComponent(() => import('../components/HistoricalTrends'), 'HistoricalTrends');
export const SmartNumberGenerator = createOptimizedLazyComponent(() => import('../components/SmartNumberGenerator'), 'SmartNumberGenerator');

// Componente de loading personalizado com otimizações
interface ComponentLoaderProps {
  message?: string;
  size?: 'sm' | 'md' | 'lg';
}

export const ComponentLoader: React.FC<ComponentLoaderProps> = React.memo(({ 
  message = 'Carregando...', 
  size = 'md'
}) => {
  const sizeClasses = {
    sm: 'h-6 w-6',
    md: 'h-12 w-12',
    lg: 'h-16 w-16'
  };

  return (
    <div className="flex items-center justify-center p-8">
      <div className="flex flex-col items-center space-y-4">
        <div className={`animate-spin rounded-full border-b-2 border-blue-600 ${sizeClasses[size]}`}></div>
        <p className="text-gray-600 font-medium">{message}</p>
      </div>
    </div>
  );
});

ComponentLoader.displayName = 'ComponentLoader';

// HOC para adicionar loading automático a componentes lazy
export function withLoadingFallback<P extends object>(
  WrappedComponent: React.ComponentType<P>,
  loadingMessage?: string
): React.FC<P> {
  const WrappedWithSuspense: React.FC<P> = (props: P) => {
    return (
      <Suspense fallback={<ComponentLoader message={loadingMessage} />}>
        <WrappedComponent {...props} />
      </Suspense>
    );
  };
  
  WrappedWithSuspense.displayName = `withLoadingFallback(${WrappedComponent.displayName || WrappedComponent.name})`;
  
  return WrappedWithSuspense;
}

// Preload function para componentes críticos com cache memoizado
export const preloadCriticalComponents = memoize(async (): Promise<void> => {
  try {
    // Configurar resource hints
    resourceHints.setupApiHints();
    
    // Precarregar componentes críticos usando preloader inteligente
    await intelligentPreloader.preloadByPriority([
      'DualGameViewer',
      'EnhancedLotomaniaGrid',
      'Statistics'
    ]);
    
    console.log('✅ Componentes críticos pré-carregados');
  } catch (error) {
    console.warn('❌ Falha ao precarregar componentes:', error);
  }
});

// Função para preload condicional baseado na conexão e performance
export const conditionalPreload = (): void => {
  // Verificar performance e conexão antes de precarregar
  const shouldPreload = checkPreloadConditions();
  
  if (shouldPreload) {
    // Precarregar após idle callback se disponível
    if ('requestIdleCallback' in window) {
      (window as any).requestIdleCallback(
        () => preloadCriticalComponents(),
        { timeout: 3000 }
      );
    } else {
      setTimeout(() => preloadCriticalComponents(), 1000);
    }
  }
};

// Verificar condições para preload
function checkPreloadConditions(): boolean {
  // Verificar conexão
  if ('connection' in navigator) {
    const connection = (navigator as any).connection;
    if (connection) {
      // Não precarregar em conexões lentas ou dados limitados
      if (connection.saveData || connection.effectiveType === 'slow-2g' || connection.effectiveType === '2g') {
        return false;
      }
    }
  }
  
  // Verificar memória disponível
  if ('memory' in performance) {
    const memory = (performance as any).memory;
    if (memory && memory.usedJSHeapSize / memory.jsHeapSizeLimit > 0.8) {
      return false; // Não precarregar se usando muita memória
    }
  }
  
  // Verificar CPU (hardware concurrency como proxy)
  if (navigator.hardwareConcurrency && navigator.hardwareConcurrency < 4) {
    return false; // Não precarregar em dispositivos com poucos cores
  }
  
  return true;
}
