import { useEffect, useCallback } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import {
  setOnlineStatus,
  setSyncInProgress,
  removePendingAction,
  incrementRetryCount,
  updateLastSyncTime,
} from '@/store/slices/offlineSlice';
import apiClient from '@/lib/api/client';

interface RootState {
  offline: {
    isOnline: boolean;
    pendingActions: any[];
    syncInProgress: boolean;
  };
}

const MAX_RETRY_ATTEMPTS = 3;

export const useOfflineSync = () => {
  const dispatch = useDispatch();
  const { isOnline, pendingActions, syncInProgress } = useSelector(
    (state: RootState) => state.offline
  );

  // Monitor online/offline status
  useEffect(() => {
    const handleOnline = () => {
      dispatch(setOnlineStatus(true));
    };

    const handleOffline = () => {
      dispatch(setOnlineStatus(false));
    };

    // Set initial status
    dispatch(setOnlineStatus(navigator.onLine));

    window.addEventListener('online', handleOnline);
    window.addEventListener('offline', handleOffline);

    return () => {
      window.removeEventListener('online', handleOnline);
      window.removeEventListener('offline', handleOffline);
    };
  }, [dispatch]);

  // Sync pending actions when online
  const syncPendingActions = useCallback(async () => {
    if (!isOnline || pendingActions.length === 0 || syncInProgress) {
      return;
    }

    dispatch(setSyncInProgress(true));

    for (const action of pendingActions) {
      try {
        // Attempt to replay the action
        await replayAction(action);

        // Remove from pending actions on success
        dispatch(removePendingAction(action.id));
      } catch (error) {
        console.error(`Failed to sync action ${action.id}:`, error);

        // Increment retry count
        dispatch(incrementRetryCount(action.id));

        // If max retries exceeded, remove the action
        if (action.retryCount >= MAX_RETRY_ATTEMPTS) {
          console.warn(`Max retries exceeded for action ${action.id}, removing from queue`);
          dispatch(removePendingAction(action.id));
        }
      }
    }

    dispatch(setSyncInProgress(false));
    dispatch(updateLastSyncTime());
  }, [isOnline, pendingActions, syncInProgress, dispatch]);

  // Trigger sync when coming online
  useEffect(() => {
    if (isOnline && pendingActions.length > 0) {
      syncPendingActions();
    }
  }, [isOnline, pendingActions.length, syncPendingActions]);

  // Replay a specific action
  const replayAction = async (action: any) => {
    const { type, payload } = action;

    switch (type) {
      case 'CREATE_ACTIVITY':
        return await apiClient.post('/api/v1/activities', payload);

      case 'UPDATE_ACTIVITY':
        return await apiClient.put(`/api/v1/activities/${payload.id}`, payload);

      case 'DELETE_ACTIVITY':
        return await apiClient.delete(`/api/v1/activities/${payload.id}`);

      case 'CREATE_CHILD':
        return await apiClient.post('/api/v1/children', payload);

      case 'UPDATE_CHILD':
        return await apiClient.put(`/api/v1/children/${payload.id}`, payload);

      default:
        throw new Error(`Unknown action type: ${type}`);
    }
  };

  return {
    isOnline,
    pendingActionsCount: pendingActions.length,
    syncInProgress,
    syncPendingActions,
  };
};
