package utils

import (
	"encoding/json"
	"errors"
	"fmt"
	"github.com/paulmach/orb/geojson"
	"github.com/spf13/viper"
	"math"
	"net/http"
	"strings"
)

func Haversine(lat1, lon1, lat2, lon2 float64) float64 {
	R := 6371.0

	lat1 = lat1 * math.Pi / 180
	lon1 = lon1 * math.Pi / 180
	lat2 = lat2 * math.Pi / 180
	lon2 = lon2 * math.Pi / 180

	dlat := lat2 - lat1
	dlon := lon2 - lon1

	a := math.Sin(dlat/2)*math.Sin(dlat/2) + math.Cos(lat1)*math.Cos(lat2)*math.Sin(dlon/2)*math.Sin(dlon/2)
	c := 2 * math.Atan2(math.Sqrt(a), math.Sqrt(1-a))

	distance := R * c
	return distance
}

func CalculateDurationBetweenFeatures(feature1, feature2 *geojson.Feature) (int64, error) {
	coords1 := feature1.Point()
	coords2 := feature2.Point()
	v := viper.New()
	v.SetConfigName("config")
	v.AddConfigPath(".")
	v.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
	v.AutomaticEnv()
	_ = v.ReadInConfig()
	routingBaseUrl := v.GetString("routing.valhalla.base_url")
	url := fmt.Sprintf("%sroute?json=%s", routingBaseUrl, createJSONROUTERequest(coords1.X(), coords1.Y(), coords2.X(), coords2.Y()))
	response, err := http.Get(url)
	if err != nil {
		return 0, errors.New("routing service error")
	}
	var result map[string]interface{}
	decoder := json.NewDecoder(response.Body)
	if err := decoder.Decode(&result); err != nil {
		return 0, errors.New("routing response decoding error")
	}
	trip, ok := result["trip"].(map[string]interface{})
	if !ok {
		return 0, errors.New("routing response decoding error")
	}
	summary, ok := trip["summary"].(map[string]interface{})
	if !ok {
		return 0, errors.New("routing response decoding error")
	}
	duration, ok := summary["time"].(float64)
	if !ok {
		return 0, errors.New("routing response decoding error")
	}

	return int64(duration), nil
}
func createJSONROUTERequest(lat1, lon1, lat2, lon2 float64) string {
	request := map[string]interface{}{
		"locations": []map[string]float64{
			{"lat": lat1, "lon": lon1},
			{"lat": lat2, "lon": lon2},
		},
		"costing": "auto",
	}

	jsonRequest, _ := json.Marshal(request)
	return string(jsonRequest)
}