package com.ruoyi.system.utils;

import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
//import com.sun.javafx.collections.MappingChange;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

public class GetArea {
    private static final double A = 6378245.0;
    private static final double EE = 0.00669342162296594323;
    private static final double PI = 3.14159265358979324;
    private static final double X_PI = PI * 3000.0 / 180.0;


    //查询路线
    public JSONObject getluxian(String latlng1,String latlng2,String lang){

        String url = "https://maps.googleapis.com/maps/api/directions/json?"+
                "origin="+latlng1+
                "&destination="+latlng2+
                "&language="+lang+
                "&sensor=false&mode=driving"+
                "&key=AIzaSyBt-bYNprVqfpY3fPgoOj0RKbnC_g7ii1k";
        String res="";
        res = HttpUtil.get(url);
        JSONObject jsonObject =  JSON.parseObject(res);
        return jsonObject;
    }

    public JSONObject getmpluxian(String latlng1,String latlng2){

        String url = "https://api.mapbox.com/directions/v5/mapbox/cycling/"+latlng1+";"+latlng2+"?access_token=pk.eyJ1IjoiY2l0eWV4cHJlc3MxNjg4IiwiYSI6ImNsd2xpcHBtZTA1dzIyanBvenBkcGI2aW0ifQ.azi4w1LoND2oYlJFkpFchg";
        String res="";
        res = HttpUtil.get(url);
        JSONObject jsonObject =  JSON.parseObject(res);
        return jsonObject;
    }

    //获取电动车耗时
    public double getMotorbikeDuration(String latlng1, String latlng2) {
        String url = "https://api.mapbox.com/directions/v5/mapbox/driving/"+latlng1+";"+latlng2+"?access_token=pk.eyJ1IjoiY2l0eWV4cHJlc3MxNjg4IiwiYSI6ImNsd2xpcHBtZTA1dzIyanBvenBkcGI2aW0ifQ.azi4w1LoND2oYlJFkpFchg";

        String res = HttpUtil.get(url);
        JSONObject jsonObject = JSON.parseObject(res);
        double duration = jsonObject
                .getJSONArray("routes").getJSONObject(0).getDoubleValue("duration");
//        JSONArray steps = jsonObject
//                .getJSONArray("routes")
//                .getJSONObject(0)
//                .getJSONArray("legs")
//                .getJSONObject(0)
//                .getJSONArray("steps");

        double totalMotorbikeTime = duration*1.5; // 电动车总耗时（秒）
//
//        for (int i = 0; i < ((JSONArray) steps).size(); i++) {
//            JSONObject step = steps.getJSONObject(i);
//            double distance = step.getDoubleValue("distance"); // 米
//            double speedKmh = getEVSpeed(step); // 获取电动车速度
//            double timeSec = distance / (speedKmh * 1000 / 3600);
//            totalMotorbikeTime += timeSec;
////            step.put("ev_duration", timeSec); // 每段电动车耗时
//        }

//        jsonObject.put("ev_total_duration", totalMotorbikeTime); // 电动车总耗时（秒）
        return totalMotorbikeTime;
    }

    // 根据道路类型选择电动车速度
    private double getEVSpeed(JSONObject step) {
        JSONArray classes = step.getJSONArray("classes");
        if (classes != null && classes.contains("motorway")) return 50;  // 高速/国道
        if (classes != null && classes.contains("primary")) return 40;   // 主干道
        if (classes != null && classes.contains("secondary")) return 30; // 次干道
        if (classes != null && classes.contains("residential")) return 20; // 小路
        return 30; // 默认
    }


    public JSONObject getarearess(String latlng,String lang){

        String url = "https://api.map.baidu.com/reverse_geocoding/v3/?" +
                "ak=aYfBFMwOPlvztS60o6NdM9WdYbboAw1m" +
                "&output=json" +
                "&language="+lang+
                "&coordtype=wgs84ll" +
                "&extensions_poi=1"+
                "&radius=1000"+
                "&location="+latlng;
        String res="";
        res = HttpUtil.get(url);
        JSONObject jsonObject =  JSON.parseObject(res);
        return jsonObject;
    }
    //谷歌附近地址
    public JSONObject getgoogle(String latlng,String lang){

        String url = "https://maps.googleapis.com/maps/api/place/nearbysearch/json?" +
//                "key=AIzaSyCeRnQtfpeH3skSoCvC6OZbEbwlIFTXvsY" +
                "key=AIzaSyBt-bYNprVqfpY3fPgoOj0RKbnC_g7ii1k" +
                "&language="+lang+
                "&radius=10000"+
                "&location="+latlng;
        String res="";
        res = HttpUtil.get(url);
        JSONObject jsonObject =  JSON.parseObject(res);
        JSONObject org = new JSONObject();
        org.put("address",getgoogleadd(latlng,lang));
        org.put("results",jsonObject.getJSONArray("results"));
        return org;
    }
    //谷歌地址逆向
    public JSONObject getgoogleadd(String latlng,String lang){

        String url = "https://maps.googleapis.com/maps/api/geocode/json?" +
                "key=AIzaSyBt-bYNprVqfpY3fPgoOj0RKbnC_g7ii1k" +
                "&language="+lang+
                "&latlng="+latlng+
                "&location_type=ROOFTOP|RANGE_INTERPOLATED|GEOMETRIC_CENTER|APPROXIMATE";
        String res="";
        String lanss = lang=="en_US"?"Unknown address":lang=="vi"?"Địa chỉ vô danh":"无名地址";
        res = HttpUtil.get(url);
//        System.out.println("谷歌地图getgoogleadd："+res);
        JSONObject jsonObject =  JSON.parseObject(res);
        JSONObject org = new JSONObject();
        JSONObject obj = (JSONObject) jsonObject.getJSONArray("results").get(0);
        org.put("name",jsonObject.getJSONObject("plus_code").getString("compound_code")==null?lanss:jsonObject.getJSONObject("plus_code").getString("compound_code"));
        org.put("address",obj.getString("formatted_address"));
        return org;
    }
    public JSONObject setlatlng(String latlng,Integer from,Integer to){

        String url = "https://api.map.baidu.com/geoconv/v1/?" +
                "ak=aYfBFMwOPlvztS60o6NdM9WdYbboAw1m" +
                "&output=json" +
                "&to=" + to +
                "&coords="+latlng+
                "&from="+from;
        String res="";
        res = HttpUtil.get(url);
        JSONObject jsonObject =  JSON.parseObject(res);
        return jsonObject;
    }

    public  String convertGCJ2WGS(double lng, double lat) {
        if (outOfChina(lng, lat)) {
            return lng + "," + lat;
        } else {
            double dLat = transformLat(lng - 105.0, lat - 35.0);
            double dLng = transformLng(lng - 105.0, lat - 35.0);
            double radLat = lat / 180.0 * PI;
            double magic = Math.sin(radLat);
            magic = 1 - EE * magic * magic;
            double sqrtMagic = Math.sqrt(magic);
            dLat = (dLat * 180.0) / ((A * (1 - EE)) / (magic * sqrtMagic) * PI);
            dLng = (dLng * 180.0) / (A / sqrtMagic * Math.cos(radLat) * PI);
            double mgLat = lat + dLat;
            double mgLng = lng + dLng;

            double wgsLng = lng * 2 - mgLng;
            double wgsLat = lat * 2 - mgLat;

            return wgsLng + "," + wgsLat;
        }
    }

    private static boolean outOfChina(double lng, double lat) {
        return (lng < 72.004 || lng > 137.8347) || (lat < 0.8293 || lat > 55.8271);
    }

    private static double transformLat(double x, double y) {
        double ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * Math.sqrt(Math.abs(x));
        ret += (20.0 * Math.sin(6.0 * x * PI) + 20.0 * Math.sin(2.0 * x * PI)) * 2.0 / 3.0;
        ret += (20.0 * Math.sin(y * PI) + 40.0 * Math.sin(y / 3.0 * PI)) * 2.0 / 3.0;
        ret += (160.0 * Math.sin(y / 12.0 * PI) + 320 * Math.sin(y * PI / 30.0)) * 2.0 / 3.0;
        return ret;
    }

    /**
     * Haversine公式计算两个经纬度之间的距离
     * @param lat1 第一个点纬度
     * @param lng1 第一个点经度
     * @param lat2 第二个点纬度
     * @param lng2 第二个点经度
     * @return 距离，单位：米
     */
    public static double getDistance(double lat1, double lng1, double lat2, double lng2) {
        double radLat1 = Math.toRadians(lat1);
        double radLat2 = Math.toRadians(lat2);
        double a = radLat1 - radLat2;
        double b = Math.toRadians(lng1) - Math.toRadians(lng2);
        double distance = 2 * Math.asin(Math.sqrt(
                Math.pow(Math.sin(a / 2), 2)
                + Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2)
        ));
        distance = distance * 6378137;
        return distance;
    }

    private static double transformLng(double x, double y) {
        double ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * Math.sqrt(Math.abs(x));
        ret += (20.0 * Math.sin(6.0 * x * PI) + 20.0 * Math.sin(2.0 * x * PI)) * 2.0 / 3.0;
        ret += (20.0 * Math.sin(x * PI) + 40.0 * Math.sin(x / 3.0 * PI)) * 2.0 / 3.0;
        ret += (150.0 * Math.sin(x / 12.0 * PI) + 300.0 * Math.sin(x / 30.0 * PI)) * 2.0 / 3.0;
        return ret;
    }
}
