/**
 * useProgressiveVariations Hook
 * 
 * Progressively loads variations in chunks for better UX
 * - Shows skeleton rows immediately
 * - Loads data in batches (20-50 variations/batch)
 * - Real-time progress indicator
 * - Cancellable queries
 */

import { useState, useEffect, useCallback, useRef } from 'react';
import { useQuery } from '@tanstack/react-query';
import { getVariations } from '../services/variations';
import type { VariationsQueryParams, Variation } from '../types/variation';

interface ProgressiveLoadState {
  variations: Variation[];
  totalCount: number;
  loadedCount: number;
  isLoading: boolean;
  isComplete: boolean;
  progress: number; // 0-100
  error: Error | null;
}

const BATCH_SIZE = 30; // Optimális batch méret

/**
 * Progresszív betöltés hook
 */
export function useProgressiveVariations(params: VariationsQueryParams = {}) {
  const [state, setState] = useState<ProgressiveLoadState>({
    variations: [],
    totalCount: 0,
    loadedCount: 0,
    isLoading: true,
    isComplete: false,
    progress: 0,
    error: null,
  });
  
  const abortControllerRef = useRef<AbortController | null>(null);
  const isLoadingRef = useRef(false);
  
  // 1. Első query: csak total count lekérése (limit=1 gyorsaság miatt)
  const { data: initialData, isLoading: isCountLoading } = useQuery({
    queryKey: ['variations-count', params],
    queryFn: () => getVariations({ ...params, limit: 1, offset: 0 }),
    staleTime: 30000,
    refetchOnWindowFocus: false,
  });
  
  // 2. Batch betöltés effect
  useEffect(() => {
    if (isCountLoading || !initialData) return;
    
    const totalCount = initialData.data?.total || 0;
    if (totalCount === 0) {
      setState({
        variations: [],
        totalCount: 0,
        loadedCount: 0,
        isLoading: false,
        isComplete: true,
        progress: 100,
        error: null,
      });
      return;
    }
    
    // Initialize state with total count
    setState(prev => ({
      ...prev,
      totalCount,
      isLoading: true,
      isComplete: false,
    }));
    
    // Start loading batches
    loadNextBatch(0, totalCount);
    
    return () => {
      // Cleanup: cancel ongoing requests
      if (abortControllerRef.current) {
        abortControllerRef.current.abort();
      }
    };
  }, [initialData, isCountLoading, JSON.stringify(params)]);
  
  const loadNextBatch = useCallback(async (batchIndex: number, totalCount: number) => {
    if (isLoadingRef.current) return;
    
    const offset = batchIndex * BATCH_SIZE;
    if (offset >= totalCount) {
      // All batches loaded
      setState(prev => ({
        ...prev,
        isLoading: false,
        isComplete: true,
        progress: 100,
      }));
      return;
    }
    
    isLoadingRef.current = true;
    abortControllerRef.current = new AbortController();
    
    try {
      const batchData = await getVariations({
        ...params,
        limit: BATCH_SIZE,
        offset,
      });
      
      const newVariations = batchData.data?.variations || [];
      
      setState(prev => {
        const allVariations = [...prev.variations, ...newVariations];
        const loadedCount = allVariations.length;
        const progress = Math.min(Math.floor((loadedCount / totalCount) * 100), 100);
        
        return {
          ...prev,
          variations: allVariations,
          loadedCount,
          progress,
          isLoading: loadedCount < totalCount,
          isComplete: loadedCount >= totalCount,
        };
      });
      
      isLoadingRef.current = false;
      
      // Load next batch
      setTimeout(() => {
        loadNextBatch(batchIndex + 1, totalCount);
      }, 50); // 50ms delay between batches
      
    } catch (error: any) {
      if (error.name === 'AbortError') {
        console.log('[Progressive] Load cancelled');
        return;
      }
      
      console.error('[Progressive] Batch load failed:', error);
      setState(prev => ({
        ...prev,
        isLoading: false,
        error: error as Error,
      }));
      isLoadingRef.current = false;
    }
  }, [params]);
  
  // Cancel loading
  const cancel = useCallback(() => {
    if (abortControllerRef.current) {
      abortControllerRef.current.abort();
    }
    setState(prev => ({
      ...prev,
      isLoading: false,
    }));
  }, []);
  
  return {
    ...state,
    cancel,
  };
}
