import { useDispatch, useSelector, TypedUseSelectorHook } from 'react-redux';
import type { RootState, AppDispatch } from './store';
import { useCallback } from 'react';

// Use throughout your app instead of plain `useDispatch` and `useSelector`
export const useAppDispatch = () => useDispatch<AppDispatch>();
export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector;

// Custom hooks for common patterns

/**
 * Hook to check if the app is online
 */
export const useIsOnline = () => {
  return useAppSelector((state) => state.network?.isOnline ?? true);
};

/**
 * Hook to check if there are pending sync actions
 */
export const useHasPendingSync = () => {
  const pendingActions = useAppSelector((state) => state.offline?.pendingActions ?? []);
  return pendingActions.length > 0;
};

/**
 * Hook to get sync status
 */
export const useSyncStatus = () => {
  const syncInProgress = useAppSelector((state) => state.offline?.syncInProgress ?? false);
  const lastSyncTime = useAppSelector((state) => state.offline?.lastSyncTime);
  const pendingCount = useAppSelector((state) => state.offline?.pendingActions?.length ?? 0);

  return {
    syncing: syncInProgress,
    lastSync: lastSyncTime,
    pendingCount,
  };
};

/**
 * Hook for optimistic updates
 * Provides a function that dispatches both optimistic and actual actions
 */
export const useOptimisticAction = <T extends any[], R>(
  optimisticAction: (...args: T) => any,
  actualAction: (...args: T) => any
) => {
  const dispatch = useAppDispatch();
  const isOnline = useIsOnline();

  return useCallback(
    async (...args: T) => {
      // Always dispatch optimistic action for immediate UI update
      dispatch(optimisticAction(...args));

      // If online, dispatch actual action
      if (isOnline) {
        try {
          const result = await dispatch(actualAction(...args));
          return result;
        } catch (error) {
          // Rollback will be handled by the rejected case in the slice
          throw error;
        }
      }

      // If offline, the action will be queued by the middleware
      return Promise.resolve();
    },
    [dispatch, optimisticAction, actualAction, isOnline]
  );
};

/**
 * Hook to get network quality information
 */
export const useNetworkQuality = () => {
  const quality = useAppSelector((state) => state.network?.connectionQuality ?? 'excellent');
  const latency = useAppSelector((state) => state.network?.latency);

  return { quality, latency };
};

/**
 * Hook to check if a specific entity is being optimistically updated
 */
export const useIsOptimistic = (entityType: 'activities' | 'children', id: string) => {
  return useAppSelector((state) => {
    const entity = state[entityType]?.entities?.[id];
    return entity?._optimistic ?? false;
  });
};
