import { useState, useEffect } from 'react';

// Token de acesso do Mapbox
const MAPBOX_ACCESS_TOKEN = "pk.eyJ1IjoiYWxlaW5jb25uZXh0IiwiYSI6ImNtOGtvdzFueDBuMGUybHBvYjd4d3kyZDQifQ.MXDcXpxKAXtQkyAwv-_1tQ";

interface Coordinate {
  latitude: number;
  longitude: number;
}

interface RouteResponse {
  coordinates: Coordinate[];
  distance: number;
  duration: number;
}

export const useMapboxDirections = () => {
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);

  const getRoute = async (waypoints: Coordinate[]): Promise<RouteResponse | null> => {
    if (waypoints.length < 2) {
      return null;
    }

    setLoading(true);
    setError(null);

    try {
      // Formatar waypoints para a API do Mapbox
      const coordinates = waypoints.map(point => `${point.longitude},${point.latitude}`).join(';');
      
      // URL da API de direções do Mapbox
      const url = `https://api.mapbox.com/directions/v5/mapbox/driving/${coordinates}?geometries=geojson&access_token=${MAPBOX_ACCESS_TOKEN}&overview=full&steps=true`;
      
      const response = await fetch(url);
      
      if (!response.ok) {
        throw new Error(`Erro na API: ${response.status}`);
      }
      
      const data = await response.json();
      
      if (!data.routes || data.routes.length === 0) {
        throw new Error('Nenhuma rota encontrada');
      }
      
      const route = data.routes[0];
      
      // Converter coordenadas do GeoJSON para o formato do react-native-maps
      const coordinatesArray: Coordinate[] = route.geometry.coordinates.map((coord: [number, number]) => ({
        longitude: coord[0],
        latitude: coord[1]
      }));
      
      return {
        coordinates: coordinatesArray,
        distance: route.distance / 1000, // Converter para km
        duration: route.duration / 60 // Converter para minutos
      };
      
    } catch (err) {
      const errorMessage = err instanceof Error ? err.message : 'Erro ao obter rota';
      setError(errorMessage);
      console.error('Erro ao obter rota:', err);
      return null;
    } finally {
      setLoading(false);
    }
  };

  const getOptimizedRoute = async (deliveries: any[], startPoint: Coordinate): Promise<RouteResponse | null> => {
    if (deliveries.length === 0) {
      return null;
    }

    // Criar waypoints: ponto inicial + todas as entregas
    const waypoints = [
      startPoint,
      ...deliveries.map(delivery => ({
        latitude: delivery.coordinates?.latitude || delivery.lat || 0,
        longitude: delivery.coordinates?.longitude || delivery.lng || 0
      }))
    ];

    return await getRoute(waypoints);
  };

  const getOptimizedRouteWithUpdatedDeliveries = async (deliveries: any[], startPoint: Coordinate): Promise<{ route: RouteResponse | null, updatedDeliveries: any[] }> => {
    if (deliveries.length === 0) {
      return { route: null, updatedDeliveries: [] };
    }

    // Criar waypoints: ponto inicial + todas as entregas
    const waypoints = [
      startPoint,
      ...deliveries.map(delivery => ({
        latitude: delivery.coordinates?.latitude || delivery.lat || 0,
        longitude: delivery.coordinates?.longitude || delivery.lng || 0
      }))
    ];

    const route = await getRoute(waypoints);
    
    if (route && route.coordinates.length > 0) {
      // Atualizar as entregas com as coordenadas reais da rota
      const updatedDeliveries = deliveries.map((delivery, index) => {
        // Pegar as coordenadas da rota que correspondem a esta entrega
        // A primeira coordenada é o ponto inicial, então começamos do índice 1
        const routeIndex = index + 1;
        if (route.coordinates[routeIndex]) {
          return {
            ...delivery,
            coordinates: {
              latitude: route.coordinates[routeIndex].latitude,
              longitude: route.coordinates[routeIndex].longitude
            },
            lat: route.coordinates[routeIndex].latitude,
            lng: route.coordinates[routeIndex].longitude
          };
        }
        return delivery;
      });

      return { route, updatedDeliveries };
    }

    return { route, updatedDeliveries: deliveries };
  };

  return {
    getRoute,
    getOptimizedRoute,
    getOptimizedRouteWithUpdatedDeliveries,
    loading,
    error
  };
}; 