/**
 * VEZA V5 ULTRA - VIRTUAL LIST
 * High-performance virtual scrolling for large lists
 */

import { useRef } from 'react';
import { useVirtualizer } from '@tanstack/react-virtual';
import { motion } from 'framer-motion';
import { cn } from '@/lib/utils';

interface VirtualListProps<T> {
  items: T[];
  renderItem: (item: T, index: number) => React.ReactNode;
  estimatedItemSize?: number;
  className?: string;
  gap?: number;
  animated?: boolean;
  overscan?: number;
}

export function VirtualList<T>({
  items,
  renderItem,
  estimatedItemSize = 80,
  className = '',
  gap = 8,
  animated = true,
  overscan = 5,
}: VirtualListProps<T>) {
  const parentRef = useRef<HTMLDivElement>(null);

  const virtualizer = useVirtualizer({
    count: items.length,
    getScrollElement: () => parentRef.current,
    estimateSize: () => estimatedItemSize,
    overscan,
    gap,
  });

  const virtualItems = virtualizer.getVirtualItems();

  return (
    <div
      ref={parentRef}
      className={cn(
        'h-full overflow-auto scrollbar-thin',
        className
      )}
    >
      <div
        style={{
          height: `${virtualizer.getTotalSize()}px`,
          width: '100%',
          position: 'relative',
        }}
      >
        {virtualItems.map(virtualRow => {
          const item = items[virtualRow.index];
          const Component = animated ? motion.div : 'div';
          const animationProps = animated
            ? {
                initial: { opacity: 0, y: 20 },
                animate: { opacity: 1, y: 0 },
                transition: { duration: 0.2 },
              }
            : {};

          return (
            <Component
              key={virtualRow.key}
              data-index={virtualRow.index}
              ref={virtualizer.measureElement}
              style={{
                position: 'absolute',
                top: 0,
                left: 0,
                width: '100%',
                transform: `translateY(${virtualRow.start}px)`,
              }}
              {...animationProps}
            >
              {renderItem(item, virtualRow.index)}
            </Component>
          );
        })}
      </div>
    </div>
  );
}

// Grid variant for grid layouts
interface VirtualGridProps<T> {
  items: T[];
  renderItem: (item: T, index: number) => React.ReactNode;
  columns: number;
  estimatedItemHeight?: number;
  className?: string;
  gap?: number;
  animated?: boolean;
}

export function VirtualGrid<T>({
  items,
  renderItem,
  columns,
  estimatedItemHeight = 200,
  className = '',
  gap = 16,
  animated = true,
}: VirtualGridProps<T>) {
  const parentRef = useRef<HTMLDivElement>(null);

  // Calculate row count
  const rowCount = Math.ceil(items.length / columns);

  const virtualizer = useVirtualizer({
    count: rowCount,
    getScrollElement: () => parentRef.current,
    estimateSize: () => estimatedItemHeight,
    overscan: 3,
  });

  const virtualRows = virtualizer.getVirtualItems();

  return (
    <div
      ref={parentRef}
      className={cn(
        'h-full overflow-auto scrollbar-thin',
        className
      )}
    >
      <div
        style={{
          height: `${virtualizer.getTotalSize()}px`,
          width: '100%',
          position: 'relative',
        }}
      >
        {virtualRows.map(virtualRow => {
          const startIndex = virtualRow.index * columns;
          const endIndex = Math.min(startIndex + columns, items.length);
          const rowItems = items.slice(startIndex, endIndex);

          return (
            <div
              key={virtualRow.key}
              data-index={virtualRow.index}
              ref={virtualizer.measureElement}
              style={{
                position: 'absolute',
                top: 0,
                left: 0,
                width: '100%',
                transform: `translateY(${virtualRow.start}px)`,
              }}
            >
              <div
                className="grid"
                style={{
                  gridTemplateColumns: `repeat(${columns}, minmax(0, 1fr))`,
                  gap: `${gap}px`,
                }}
              >
                {rowItems.map((item, colIndex) => {
                  const index = startIndex + colIndex;
                  const Component = animated ? motion.div : 'div';
                  const animationProps = animated
                    ? {
                        initial: { opacity: 0, scale: 0.9 },
                        animate: { opacity: 1, scale: 1 },
                        transition: { 
                          duration: 0.2,
                          delay: colIndex * 0.05 
                        },
                      }
                    : {};

                  return (
                    <Component key={index} {...animationProps}>
                      {renderItem(item, index)}
                    </Component>
                  );
                })}
              </div>
            </div>
          );
        })}
      </div>
    </div>
  );
}

// Hook for manual virtual scrolling control
export function useVirtualScroll<T>(items: T[], estimatedSize: number = 80) {
  const parentRef = useRef<HTMLDivElement>(null);

  const virtualizer = useVirtualizer({
    count: items.length,
    getScrollElement: () => parentRef.current,
    estimateSize: () => estimatedSize,
    overscan: 5,
  });

  return {
    parentRef,
    virtualizer,
    virtualItems: virtualizer.getVirtualItems(),
    totalSize: virtualizer.getTotalSize(),
    scrollToIndex: (index: number) => {
      virtualizer.scrollToIndex(index, {
        align: 'start',
        behavior: 'smooth',
      });
    },
    scrollToOffset: (offset: number) => {
      virtualizer.scrollToOffset(offset, {
        align: 'start',
        behavior: 'smooth',
      });
    },
  };
}

