/**
 * Hook React pour le tracking GPS avancé
 */

import { useState, useEffect, useRef, useCallback } from 'react';
import { useAuth } from '@/contexts/AuthContext';
import TrackingService, { LocationData, TrackingSession, RouteEstimation } from '@/services/trackingService';

export interface UseTrackingOptions {
  autoStart?: boolean;
  orderId?: string;
}

export function useTracking(options: UseTrackingOptions = {}) {
  const { user } = useAuth();
  const { autoStart = false, orderId } = options;

  const [isTracking, setIsTracking] = useState(false);
  const [currentLocation, setCurrentLocation] = useState<LocationData | null>(null);
  const [session, setSession] = useState<TrackingSession | null>(null);
  const [locationHistory, setLocationHistory] = useState<LocationData[]>([]);
  const [error, setError] = useState<string | null>(null);
  const [permissionStatus, setPermissionStatus] = useState<'unknown' | 'granted' | 'denied'>('unknown');

  const trackingServiceRef = useRef<TrackingService | null>(null);

  // Initialiser le service de tracking
  useEffect(() => {
    if (!user) return;

    trackingServiceRef.current = new TrackingService(user.id, user.role);

    // Configurer les callbacks
    const service = trackingServiceRef.current;

    service.onLocationUpdate((location: LocationData) => {
      setCurrentLocation(location);
      setLocationHistory(prev => [...prev, location].slice(-100)); // Garder les 100 dernières positions
    });

    service.onTrackingStarted((sessionData: TrackingSession) => {
      setSession(sessionData);
      setIsTracking(true);
      setError(null);
    });

    service.onTrackingStopped(({ session: sessionData }) => {
      setSession(sessionData);
      setIsTracking(false);
    });

    service.onLocationError(({ message }) => {
      setError(message);
      setPermissionStatus('denied');
    });

    // Nettoyage
    return () => {
      service.cleanup();
    };
  }, [user]);

  // Auto-start si demandé
  useEffect(() => {
    if (autoStart && trackingServiceRef.current && user?.role === 'courier' && !isTracking) {
      startTracking();
    }
  }, [autoStart, user, isTracking]);

  const startTracking = useCallback(async () => {
    if (!trackingServiceRef.current) {
      setError('Service de tracking non disponible');
      return false;
    }

    try {
      setError(null);
      const success = await trackingServiceRef.current.startTracking(orderId);
      if (success) {
        setPermissionStatus('granted');
      }
      return success;
    } catch (error) {
      setError(error instanceof Error ? error.message : 'Erreur lors du démarrage du tracking');
      return false;
    }
  }, [orderId]);

  const stopTracking = useCallback(() => {
    if (trackingServiceRef.current) {
      trackingServiceRef.current.stopTracking();
    }
  }, []);

  const estimateRoute = useCallback(async (
    from: LocationData,
    to: LocationData,
    mode: 'driving' | 'walking' | 'cycling' = 'driving'
  ): Promise<RouteEstimation | null> => {
    if (!trackingServiceRef.current) {
      return null;
    }

    try {
      return await trackingServiceRef.current.estimateRoute(from, to, mode);
    } catch (error) {
      console.error('Error estimating route:', error);
      return null;
    }
  }, []);

  const addGeofence = useCallback((geofence: any) => {
    trackingServiceRef.current?.addGeofence(geofence);
  }, []);

  const removeGeofence = useCallback((geofenceId: string) => {
    trackingServiceRef.current?.removeGeofence(geofenceId);
  }, []);

  // Calculer des statistiques temps réel
  const statistics = useCallback(() => {
    if (!session || locationHistory.length < 2) {
      return null;
    }

    const now = new Date();
    const duration = (now.getTime() - session.startTime.getTime()) / 1000; // en secondes
    const speeds = locationHistory.map(l => l.speed || 0).filter(s => s > 0);
    const avgSpeed = speeds.reduce((a, b) => a + b, 0) / speeds.length || 0;
    const maxSpeed = Math.max(...speeds);

    return {
      duration,
      totalDistance: session.totalDistance,
      avgSpeed,
      maxSpeed,
      pointsCount: locationHistory.length,
      currentSpeed: currentLocation?.speed || 0
    };
  }, [session, locationHistory, currentLocation]);

  const requestPermission = useCallback(async () => {
    try {
      if (!navigator.geolocation) {
        throw new Error('Géolocalisation non supportée');
      }

      // Tenter d'obtenir la position pour déclencher la demande de permission
      await new Promise<void>((resolve, reject) => {
        navigator.geolocation.getCurrentPosition(
          () => {
            setPermissionStatus('granted');
            resolve();
          },
          (error) => {
            setPermissionStatus('denied');
            reject(new Error('Permission géolocalisation refusée'));
          },
          {
            enableHighAccuracy: true,
            timeout: 10000,
            maximumAge: 600000
          }
        );
      });

      return 'granted';
    } catch (error) {
      setError(error instanceof Error ? error.message : 'Erreur de permission');
      return 'denied';
    }
  }, []);

  return {
    // État
    isTracking,
    currentLocation,
    session,
    locationHistory,
    error,
    permissionStatus,
    statistics: statistics(),

    // Actions
    startTracking,
    stopTracking,
    estimateRoute,
    addGeofence,
    removeGeofence,
    requestPermission,

    // Utilitaires
    clearError: () => setError(null),
    isAvailable: !!trackingServiceRef.current && user?.role === 'courier',
    hasLocation: !!currentLocation
  };
}