// FE-OP003: 前端性能优化
import React from 'react';

// 防抖函数
export const debounce = <T extends (...args: any[]) => any>(
  func: T,
  wait: number
): ((...args: Parameters<T>) => void) => {
  let timeout: NodeJS.Timeout | null = null;
  
  return (...args: Parameters<T>) => {
    if (timeout) clearTimeout(timeout);
    timeout = setTimeout(() => {
      func(...args);
    }, wait);
  };
};

// 节流函数
export const throttle = <T extends (...args: any[]) => any>(
  func: T,
  limit: number
): ((...args: Parameters<T>) => void) => {
  let inThrottle: boolean = false;
  
  return (...args: Parameters<T>) => {
    if (!inThrottle) {
      func(...args);
      inThrottle = true;
      setTimeout(() => {
        inThrottle = false;
      }, limit);
    }
  };
};

// 懒加载组件
export const lazyLoadComponent = (component: () => Promise<any>) => {
  return React.lazy(component);
};

// 图片懒加载
export const lazyLoadImage = (img: HTMLImageElement, src: string) => {
  const observer = new IntersectionObserver((entries) => {
    entries.forEach((entry) => {
      if (entry.isIntersecting) {
        img.src = src;
        observer.unobserve(img);
      }
    });
  });
  
  observer.observe(img);
  
  return () => observer.disconnect();
};

// 缓存函数结果
export const memoize = <T extends (...args: any[]) => any>(
  func: T
): ((...args: Parameters<T>) => ReturnType<T>) => {
  const cache = new Map<string, ReturnType<T>>();
  
  return (...args: Parameters<T>) => {
    const key = JSON.stringify(args);
    if (cache.has(key)) {
      return cache.get(key) as ReturnType<T>;
    }
    const result = func(...args);
    cache.set(key, result);
    return result;
  };
};

// 批量处理函数
export const batchProcess = <T>(
  items: T[],
  processFn: (item: T) => Promise<void>,
  batchSize: number = 10
): Promise<void> => {
  const batches = [];
  for (let i = 0; i < items.length; i += batchSize) {
    batches.push(items.slice(i, i + batchSize));
  }
  
  return batches.reduce(async (prev, batch) => {
    await prev;
    return Promise.all(batch.map(processFn));
  }, Promise.resolve());
};

// 预加载资源
export const preloadResource = (url: string, type: string = 'image') => {
  if (type === 'image') {
    const img = new Image();
    img.src = url;
  } else if (type === 'script') {
    const script = document.createElement('script');
    script.src = url;
    script.defer = true;
    document.head.appendChild(script);
  } else if (type === 'stylesheet') {
    const link = document.createElement('link');
    link.rel = 'stylesheet';
    link.href = url;
    document.head.appendChild(link);
  }
};

// 检测性能指标
export const measurePerformance = (name: string, fn: () => void) => {
  const start = performance.now();
  fn();
  const end = performance.now();
  console.log(`${name} took ${end - start}ms`);
};

// 优化渲染性能
export const useOptimizedRender = (deps: any[]) => {
  return React.useMemo(() => deps, deps);
};

// 优化列表渲染
export const optimizeListRender = <T>(
  items: T[],
  renderItem: (item: T, index: number) => React.ReactNode,
  keyExtractor: (item: T) => string | number
) => {
  return items.map((item, index) => {
    const key = keyExtractor(item);
    return React.useMemo(() => renderItem(item, index), [item, index, renderItem]);
  });
};

// 虚拟滚动组件
export const VirtualList: React.FC<{
  items: any[];
  itemHeight: number;
  containerHeight: number;
  renderItem: (item: any, index: number) => React.ReactNode;
  keyExtractor: (item: any) => string | number;
}> = ({ items, itemHeight, containerHeight, renderItem, keyExtractor }) => {
  const [scrollTop, setScrollTop] = React.useState(0);
  
  const handleScroll = (e: React.UIEvent<HTMLDivElement>) => {
    setScrollTop(e.currentTarget.scrollTop);
  };
  
  const startIndex = Math.floor(scrollTop / itemHeight);
  const endIndex = Math.min(
    startIndex + Math.ceil(containerHeight / itemHeight) + 1,
    items.length
  );
  
  const visibleItems = items.slice(startIndex, endIndex);
  const offsetY = startIndex * itemHeight;
  
  return (
    <div
      style={{
        height: containerHeight,
        overflowY: 'auto',
        position: 'relative',
      }}
      onScroll={handleScroll}
    >
      <div
        style={{
          height: items.length * itemHeight,
          position: 'relative',
        }}
      >
        <div
          style={{
            position: 'absolute',
            top: offsetY,
            left: 0,
            right: 0,
          }}
        >
          {visibleItems.map((item, index) => {
            const actualIndex = startIndex + index;
            return (
              <div
                key={keyExtractor(item)}
                style={{
                  height: itemHeight,
                }}
              >
                {renderItem(item, actualIndex)}
              </div>
            );
          })}
        </div>
      </div>
    </div>
  );
};

export default {
  debounce,
  throttle,
  lazyLoadComponent,
  lazyLoadImage,
  memoize,
  batchProcess,
  preloadResource,
  measurePerformance,
  useOptimizedRender,
  optimizeListRender,
  VirtualList,
};
