import { Middleware } from '@reduxjs/toolkit';
import { RootState } from '../store';
import { setOnlineStatus } from '../slices/networkSlice';
import { addPendingAction, removePendingAction, incrementRetryCount } from '../slices/offlineSlice';

/**
 * Offline middleware - intercepts actions and queues them when offline
 */
export const offlineMiddleware: Middleware<{}, RootState> = (store) => (next) => (action: any) => {
  const state = store.getState();
  const isOnline = state.network?.isOnline ?? true;

  // Check if this is an async action that should be queued
  const isOfflineableAction =
    action.type?.includes('/create') ||
    action.type?.includes('/update') ||
    action.type?.includes('/delete');

  // If offline and action should be queued
  if (!isOnline && isOfflineableAction && action.meta?.requestId) {
    console.log('[Offline Middleware] Queuing action:', action.type);

    // Queue the action
    store.dispatch(
      addPendingAction({
        type: action.type,
        payload: action.payload,
      })
    );

    // Still process the optimistic update
    return next(action);
  }

  // If online, process normally
  return next(action);
};

/**
 * Network status detector - listens for online/offline events
 */
export const setupNetworkDetection = (dispatch: any) => {
  if (typeof window === 'undefined') return;

  const handleOnline = () => {
    console.log('[Network] Connection restored');
    dispatch(setOnlineStatus(true));
  };

  const handleOffline = () => {
    console.log('[Network] Connection lost');
    dispatch(setOnlineStatus(false));
  };

  // Listen to browser online/offline events
  window.addEventListener('online', handleOnline);
  window.addEventListener('offline', handleOffline);

  // Periodic connectivity check
  const checkConnectivity = async () => {
    try {
      const startTime = Date.now();
      const response = await fetch('/api/health', {
        method: 'HEAD',
        cache: 'no-cache',
      });
      const latency = Date.now() - startTime;

      // Consider online if we got ANY response (even 404)
      // Only mark offline on actual network errors
      dispatch(setOnlineStatus(true));
    } catch (error) {
      // Only network errors (no connection) should mark as offline
      dispatch(setOnlineStatus(false));
    }
  };

  // Check connectivity every 30 seconds
  const intervalId = setInterval(checkConnectivity, 30000);

  // Initial check
  checkConnectivity();

  // Cleanup function
  return () => {
    window.removeEventListener('online', handleOnline);
    window.removeEventListener('offline', handleOffline);
    clearInterval(intervalId);
  };
};
