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

interface PaginationData {
  current_page: number;
  last_page: number;
  per_page: number;
  total: number;
  from?: number;
  to?: number;
}

interface UseInfiniteContratosProps {
  initialContratos: any[];
  initialPagination: PaginationData;
  filters?: Record<string, string>;
}

export const useInfiniteContratos = ({
  initialContratos,
  initialPagination,
  filters = {}
}: UseInfiniteContratosProps) => {
  const [contratos, setContratos] = useState(initialContratos);
  const [pagination, setPagination] = useState(initialPagination);
  const [isLoading, setIsLoading] = useState(false);
  const [hasMore, setHasMore] = useState(
    initialPagination.current_page < initialPagination.last_page
  );
  
  const sentinelRef = useRef<HTMLDivElement | null>(null);
  const loadingRef = useRef(false);
  /** Se incrementa al alinear con props Inertia; axios en vuelo debe ignorar respuestas de una generación anterior. */
  const listGenerationRef = useRef(0);
  const inertiaPropsRef = useRef({ initialContratos, initialPagination });
  inertiaPropsRef.current = { initialContratos, initialPagination };

  // Huella de lo que vino por Inertia/SSR: al borrar o revisitar, los props cambian pero useState no se reinicia solo.
  const serverListFingerprint = useMemo(
    () =>
      [
        initialPagination.total,
        initialPagination.current_page,
        initialPagination.last_page,
        initialPagination.per_page,
        ...(initialContratos || []).map((c: any) => `${c?.CodConCom ?? ''}:${c?.RefCon ?? ''}`),
      ].join('|'),
    [initialContratos, initialPagination]
  );

  useEffect(() => {
    listGenerationRef.current += 1;
    const { initialContratos: ic, initialPagination: ip } = inertiaPropsRef.current;
    setContratos(ic);
    setPagination(ip);
    setHasMore(ip.current_page < ip.last_page);
    loadingRef.current = false;
  }, [serverListFingerprint]);

  // Cargar más contratos
  const loadMore = useCallback(async () => {
    if (loadingRef.current || !hasMore) return;

    const generationAtStart = listGenerationRef.current;
    loadingRef.current = true;
    setIsLoading(true);

    try {
      const response = await axios.get((window as any).route('contratos.load-more'), {
        params: {
          page: pagination.current_page + 1,
          per_page: pagination.per_page,
          ...filters
        }
      });

      if (generationAtStart !== listGenerationRef.current) {
        return;
      }

      const newData = response.data;

      setContratos(prev => [...prev, ...newData.data]);
      setPagination({
        current_page: newData.current_page,
        last_page: newData.last_page,
        per_page: newData.per_page,
        total: newData.total,
        from: newData.from,
        to: newData.to,
      });
      setHasMore(newData.current_page < newData.last_page);
    } catch (error) {
      if ((error as any)?.code !== 'ERR_CANCELED') {
        console.error('Error cargando más contratos:', error);
      }
    } finally {
      setIsLoading(false);
      loadingRef.current = false;
    }
  }, [pagination.current_page, pagination.per_page, hasMore, filters]);

  // Reiniciar cuando cambien los filtros
  const resetWithFilters = useCallback(async (newFilters: Record<string, string>) => {
    const generationAtStart = listGenerationRef.current;
    setIsLoading(true);

    try {
      const response = await axios.get((window as any).route('contratos.load-more'), {
        params: {
          page: 1,
          per_page: pagination.per_page,
          ...newFilters
        }
      });

      if (generationAtStart !== listGenerationRef.current) {
        return;
      }

      const newData = response.data;

      setContratos(newData.data);
      setPagination({
        current_page: newData.current_page,
        last_page: newData.last_page,
        per_page: newData.per_page,
        total: newData.total,
        from: newData.from,
        to: newData.to,
      });
      setHasMore(newData.current_page < newData.last_page);
    } catch (error) {
      if ((error as any)?.code !== 'ERR_CANCELED') {
        console.error('Error filtrando contratos:', error);
      }
    } finally {
      setIsLoading(false);
    }
  }, [pagination.per_page]);

  // IntersectionObserver para detectar scroll
  useEffect(() => {
    const el = sentinelRef.current;
    if (!el) return;
    
    const observer = new IntersectionObserver(
      (entries) => {
        if (entries[0].isIntersecting && hasMore && !isLoading) {
          loadMore();
        }
      },
      { rootMargin: '200px' }
    );
    
    observer.observe(el);
    
    return () => observer.disconnect();
  }, [hasMore, isLoading, loadMore]);

  return {
    contratos,
    pagination,
    isLoading,
    hasMore,
    loadMore,
    resetWithFilters,
    sentinelRef
  };
};

export default useInfiniteContratos;

