/**
 * Optimized List Hook
 * Provides memoized filtering, sorting, and pagination for large lists
 */

import { useMemo } from 'react';

export interface UseOptimizedListOptions<T> {
  items: T[];
  searchTerm?: string;
  searchFields?: (keyof T)[];
  sortField?: keyof T;
  sortDirection?: 'asc' | 'desc';
  pageSize?: number;
  currentPage?: number;
}

export interface UseOptimizedListResult<T> {
  filteredItems: T[];
  paginatedItems: T[];
  totalCount: number;
  pageCount: number;
}

export function useOptimizedList<T extends Record<string, any>>({
  items,
  searchTerm = '',
  searchFields = [],
  sortField,
  sortDirection = 'asc',
  pageSize,
  currentPage = 1,
}: UseOptimizedListOptions<T>): UseOptimizedListResult<T> {
  // Memoized filtering
  const filteredItems = useMemo(() => {
    if (!searchTerm || searchFields.length === 0) {
      return items;
    }

    const lowerSearchTerm = searchTerm.toLowerCase();
    return items.filter(item =>
      searchFields.some(field => {
        const value = item[field];
        if (value == null) return false;
        return String(value).toLowerCase().includes(lowerSearchTerm);
      })
    );
  }, [items, searchTerm, searchFields]);

  // Memoized sorting
  const sortedItems = useMemo(() => {
    if (!sortField) {
      return filteredItems;
    }

    return [...filteredItems].sort((a, b) => {
      const aValue = a[sortField];
      const bValue = b[sortField];

      if (aValue == null && bValue == null) return 0;
      if (aValue == null) return sortDirection === 'asc' ? 1 : -1;
      if (bValue == null) return sortDirection === 'asc' ? -1 : 1;

      if (typeof aValue === 'string' && typeof bValue === 'string') {
        return sortDirection === 'asc'
          ? aValue.localeCompare(bValue)
          : bValue.localeCompare(aValue);
      }

      if (typeof aValue === 'number' && typeof bValue === 'number') {
        return sortDirection === 'asc' ? aValue - bValue : bValue - aValue;
      }

      return 0;
    });
  }, [filteredItems, sortField, sortDirection]);

  // Memoized pagination
  const paginatedItems = useMemo(() => {
    if (!pageSize) {
      return sortedItems;
    }

    const startIndex = (currentPage - 1) * pageSize;
    const endIndex = startIndex + pageSize;
    return sortedItems.slice(startIndex, endIndex);
  }, [sortedItems, pageSize, currentPage]);

  // Calculate page count
  const pageCount = useMemo(() => {
    if (!pageSize) return 1;
    return Math.ceil(sortedItems.length / pageSize);
  }, [sortedItems.length, pageSize]);

  return {
    filteredItems: sortedItems,
    paginatedItems,
    totalCount: sortedItems.length,
    pageCount,
  };
}
