import { useEffect, useState } from 'react';
import { useOnlineStatus } from './useOnlineStatus';
import { offlineStorage, type QueuedAction } from '@/services/offline-storage';
import { syncManager } from '@/services/sync-manager';

const MAX_RETRIES = 3;

/**
 * Hook pour gérer les actions hors ligne avec IndexedDB
 * Queue les actions quand offline et sync quand online
 */
export function useOfflineQueue() {
  const [queuedActions, setQueuedActions] = useState<QueuedAction[]>([]);
  const isOnline = useOnlineStatus();

  // Charger les actions en queue au démarrage
  useEffect(() => {
    const loadActions = async () => {
      try {
        const actions = await offlineStorage.getAll<QueuedAction>('queued_actions');
        setQueuedActions(actions.filter(a => a.status !== 'completed'));
      } catch (error) {
        console.error('Failed to load offline queue:', error);
      }
    };
    
    loadActions();
  }, []);

  // Sync automatique quand on revient online
  useEffect(() => {
    if (isOnline && queuedActions.length > 0) {
      console.log(`Syncing ${queuedActions.length} queued actions...`);
      syncManager.startSync().then(() => {
        // Reload actions after sync
        offlineStorage.getAll<QueuedAction>('queued_actions').then(actions => {
          setQueuedActions(actions.filter(a => a.status !== 'completed'));
        });
      }).catch(err => {
        console.error('Sync failed:', err);
      });
    }
  }, [isOnline, queuedActions.length]);

  /**
   * Ajouter une action à la queue
   */
  const queueAction = <T,>(type: QueuedAction['type'], payload: T): string => {
    const id = `${type}_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
    const action: QueuedAction = {
      id,
      type,
      payload: payload as Record<string, any>,
      timestamp: Date.now(),
      retries: 0,
      status: 'pending',
    };

    // Save to IndexedDB
    offlineStorage.save('queued_actions', action);

    setQueuedActions((prev) => [...prev, action]);
    return id;
  };

  /**
   * Retirer une action de la queue (après succès)
   */
  const removeAction = async (id: string) => {
    await offlineStorage.delete('queued_actions', id);
    setQueuedActions((prev) => prev.filter((action) => action.id !== id));
  };

  /**
   * Incrémenter le compteur de retry pour une action
   */
  const incrementRetry = (id: string) => {
    setQueuedActions((prev) =>
      prev.map((action) =>
        action.id === id ? { ...action, retries: action.retries + 1 } : action
      )
    );
  };

  /**
   * Retirer les actions expirées ou avec trop de retries
   */
  const cleanupFailedActions = () => {
    setQueuedActions((prev) =>
      prev.filter((action) => action.retries < MAX_RETRIES)
    );
  };

  /**
   * Retirer toutes les actions
   */
  const clearQueue = async () => {
    await offlineStorage.clear('queued_actions');
    setQueuedActions([]);
  };

  return {
    queueAction,
    removeAction,
    incrementRetry,
    cleanupFailedActions,
    clearQueue,
    queuedActions,
    pendingCount: queuedActions.length,
    hasPendingActions: queuedActions.length > 0,
  };
}

