import React, { createContext, useContext, useState, ReactNode, useCallback, useMemo } from 'react';
import LoadingSpinner from './LoadingSpinner';

// Definimos la interfaz para el contexto del loading
interface LoadingContextType {
  isLoading: boolean;
  showLoading: (message?: string) => void;
  hideLoading: () => void;
}

// Creamos el contexto con valores por defecto
const LoadingContext = createContext<LoadingContextType | undefined>(undefined);

// Definimos las props para el LoadingProvider
interface LoadingProviderProps {
  children: ReactNode; // El contenido que el provider envolverá
}

// Creamos el componente del Provider
export const LoadingProvider: React.FC<LoadingProviderProps> = ({ children }) => {
  const [isLoading, setIsLoading] = useState(false);
  const [message, setMessage] = useState<string | undefined>(undefined);

  // Memoizar callbacks para evitar re-renders innecesarios
  const showLoading = useCallback((msg?: string) => {
    setMessage(msg);
    setIsLoading(true);
  }, []);

  const hideLoading = useCallback(() => {
    setIsLoading(false);
    setMessage(undefined);
  }, []);

  // Memoizar el valor del contexto
  const contextValue = useMemo<LoadingContextType>(() => ({
    isLoading,
    showLoading,
    hideLoading,
  }), [isLoading, showLoading, hideLoading]);

  return (
    <LoadingContext.Provider value={contextValue}>
      {children}
      {isLoading && <LoadingSpinner message={message} />}
    </LoadingContext.Provider>
  );
};

// Hook personalizado para consumir el contexto fácilmente
export const useLoading = (): LoadingContextType => {
  const context = useContext(LoadingContext);
  if (context === undefined) {
    throw new Error('useLoading must be used within a LoadingProvider');
  }
  return context;
};
