// Serviço para cálculos reais usando Mapbox
const MAPBOX_ACCESS_TOKEN =
  "pk.eyJ1IjoiYWxlaW5jb25uZXh0IiwiYSI6ImNtOGtvdzFueDBuMGUybHBvYjd4d3kyZDQifQ.MXDcXpxKAXtQkyAwv-_1tQ"

interface RouteResponse {
  routes: Array<{
    distance: number // em metros
    duration: number // em segundos
    geometry: {
      coordinates: number[][]
    }
  }>
}

interface RealRouteData {
  totalDistance: number // em km
  totalDuration: number // em minutos
  routeCoordinates: Array<{ latitude: number; longitude: number }>
}

export class RealRouteCalculator {
  // Calcular rota real entre múltiplos pontos
  async calculateOptimizedRoute(
    startPoint: { latitude: number; longitude: number },
    deliveryPoints: Array<{ latitude: number; longitude: number; id: string }>,
  ): Promise<RealRouteData> {
    try {
      // Construir coordenadas para a API do Mapbox
      const coordinates = [
        [startPoint.longitude, startPoint.latitude],
        ...deliveryPoints.map((point) => [point.longitude, point.latitude]),
      ]

      const coordinatesString = coordinates.map((coord) => `${coord[0]},${coord[1]}`).join(";")

      // Usar Mapbox Directions API para rota otimizada
      const url =
        `https://api.mapbox.com/directions/v5/mapbox/driving/${coordinatesString}?` +
        `geometries=geojson&` +
        `overview=full&` +
        `steps=true&` +
        `access_token=${MAPBOX_ACCESS_TOKEN}`

      const response = await fetch(url)
      const data: RouteResponse = await response.json()

      if (data.routes && data.routes.length > 0) {
        const route = data.routes[0]

        return {
          totalDistance: route.distance / 1000, // converter para km
          totalDuration: route.duration / 60, // converter para minutos
          routeCoordinates: route.geometry.coordinates.map((coord) => ({
            latitude: coord[1],
            longitude: coord[0],
          })),
        }
      }

      throw new Error("Nenhuma rota encontrada")
    } catch (error) {
      console.error("Erro ao calcular rota real:", error)
      // Fallback para cálculo simples
      return this.calculateSimpleRoute(startPoint, deliveryPoints)
    }
  }

  // Calcular tempo estimado considerando trânsito
  async getTrafficAwareRoute(
    startPoint: { latitude: number; longitude: number },
    endPoint: { latitude: number; longitude: number },
  ): Promise<{ distance: number; duration: number; durationInTraffic: number }> {
    try {
      const url =
        `https://api.mapbox.com/directions/v5/mapbox/driving-traffic/` +
        `${startPoint.longitude},${startPoint.latitude};${endPoint.longitude},${endPoint.latitude}?` +
        `geometries=geojson&` +
        `overview=full&` +
        `access_token=${MAPBOX_ACCESS_TOKEN}`

      const response = await fetch(url)
      const data: RouteResponse = await response.json()

      if (data.routes && data.routes.length > 0) {
        const route = data.routes[0]

        return {
          distance: route.distance / 1000, // km
          duration: route.duration / 60, // minutos sem trânsito
          durationInTraffic: route.duration / 60, // minutos com trânsito atual
        }
      }

      throw new Error("Rota não encontrada")
    } catch (error) {
      console.error("Erro ao calcular rota com trânsito:", error)
      throw error
    }
  }

  // Fallback para cálculo simples (atual)
  private calculateSimpleRoute(
    startPoint: { latitude: number; longitude: number },
    deliveryPoints: Array<{ latitude: number; longitude: number; id: string }>,
  ): RealRouteData {
    let totalDistance = 0
    let currentPoint = startPoint

    // Calcular distância entre pontos consecutivos
    deliveryPoints.forEach((point) => {
      const distance = this.calculateHaversineDistance(
        currentPoint.latitude,
        currentPoint.longitude,
        point.latitude,
        point.longitude,
      )
      totalDistance += distance
      currentPoint = point
    })

    // Estimar tempo baseado em velocidade média urbana (30 km/h)
    const estimatedDuration = (totalDistance / 30) * 60 // minutos

    return {
      totalDistance,
      totalDuration: estimatedDuration,
      routeCoordinates: [startPoint, ...deliveryPoints],
    }
  }

  private calculateHaversineDistance(lat1: number, lon1: number, lat2: number, lon2: number): number {
    const R = 6371 // Raio da Terra em km
    const dLat = ((lat2 - lat1) * Math.PI) / 180
    const dLon = ((lon2 - lon1) * Math.PI) / 180
    const a =
      Math.sin(dLat / 2) * Math.sin(dLat / 2) +
      Math.cos((lat1 * Math.PI) / 180) * Math.cos((lat2 * Math.PI) / 180) * Math.sin(dLon / 2) * Math.sin(dLon / 2)
    const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a))
    return R * c
  }
}

export const realRouteCalculator = new RealRouteCalculator()
