import { View, ScrollView } from '@tarojs/components';
import { useState, useEffect, useRef, useCallback } from 'react';

interface VirtualListProps<T> {
  data: T[];
  itemHeight: number;
  containerHeight: number;
  renderItem: (item: T, index: number) => JSX.Element;
  keyExtractor: (item: T, index: number) => string | number;
  onEndReached?: () => void;
  onEndReachedThreshold?: number;
}

export default function VirtualList<T>({
  data,
  itemHeight,
  containerHeight,
  renderItem,
  keyExtractor,
  onEndReached,
  onEndReachedThreshold = 0
}: VirtualListProps<T>) {
  const [startIndex, setStartIndex] = useState(0);
  const [endIndex, setEndIndex] = useState(Math.ceil(containerHeight / itemHeight) + 5);
  const scrollViewRef = useRef<any>(null);

  const visibleItemCount = Math.ceil(containerHeight / itemHeight) + 10;
  const offsetY = startIndex * itemHeight;

  const handleScroll = useCallback((e: any) => {
    const scrollTop = e.detail.scrollTop;
    const newStartIndex = Math.floor(scrollTop / itemHeight);
    const newEndIndex = newStartIndex + visibleItemCount;

    setStartIndex(Math.max(0, newStartIndex - 5));
    setEndIndex(Math.min(data.length, newEndIndex + 5));

    // 触底加载
    if (onEndReached && onEndReachedThreshold > 0) {
      const { scrollHeight, clientHeight } = e.detail;
      if (scrollHeight - scrollTop - clientHeight < onEndReachedThreshold) {
        onEndReached();
      }
    }
  }, [itemHeight, visibleItemCount, data.length, onEndReached, onEndReachedThreshold]);

  const visibleData = data.slice(startIndex, endIndex);

  return (
    <ScrollView
      ref={scrollViewRef}
      className="w-full"
      style={{ height: containerHeight }}
      scrollY
      onScroll={handleScroll}
      scrollWithAnimation
    >
      <View style={{ height: data.length * itemHeight, position: 'relative' }}>
        <View style={{ transform: `translateY(${offsetY}px)` }}>
          {visibleData.map((item, index) => (
            <View key={keyExtractor(item, startIndex + index)} style={{ height: itemHeight }}>
              {renderItem(item, startIndex + index)}
            </View>
          ))}
        </View>
      </View>
    </ScrollView>
  );
}
