import React, { useState, useRef, useEffect, useMemo } from 'react';

interface VirtualListProps {
  data: any[];
  itemHeight: number;
  height: number;
  overscan?: number;
  renderItem: (item: any, index: number) => React.ReactNode;
  keyExtractor: (item: any) => string;
}

export const VirtualList: React.FC<VirtualListProps> = ({
  data,
  itemHeight,
  height,
  overscan = 5,
  renderItem,
  keyExtractor,
}) => {
  const [scrollTop, setScrollTop] = useState(0);
  const containerRef = useRef<HTMLDivElement>(null);

  const totalHeight = useMemo(() => data.length * itemHeight, [data.length, itemHeight]);
  const startIndex = useMemo(() => Math.max(0, Math.floor(scrollTop / itemHeight) - overscan), [scrollTop, itemHeight, overscan]);
  const endIndex = useMemo(() => Math.min(data.length - 1, Math.ceil(scrollTop / itemHeight) + overscan), [scrollTop, itemHeight, overscan, data.length]);
  const visibleItems = useMemo(() => data.slice(startIndex, endIndex + 1), [data, startIndex, endIndex]);
  const offsetTop = useMemo(() => startIndex * itemHeight, [startIndex, itemHeight]);

  const handleScroll = () => {
    if (containerRef.current) {
      setScrollTop(containerRef.current.scrollTop);
    }
  };

  return (
    <div
      ref={containerRef}
      style={{ height, overflow: 'auto', position: 'relative' }}
      onScroll={handleScroll}
    >
      <div style={{ height: totalHeight, position: 'relative' }}>
        <div style={{ position: 'absolute', top: offsetTop, width: '100%' }}>
          {visibleItems.map((item, index) => (
            <div
              key={keyExtractor(item)}
              style={{ height: itemHeight, width: '100%' }}
            >
              {renderItem(item, startIndex + index)}
            </div>
          ))}
        </div>
      </div>
    </div>
  );
};

export default VirtualList;