package com.ruoyi.common.utils;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.common.constant.ServiceConstants;
import com.ruoyi.common.utils.http.HttpUtils;
import com.ruoyi.common.utils.map.GeoUtils;
import com.ruoyi.common.utils.map.GpsCoordinateUtils;
import com.ruoyi.common.utils.spring.SpringUtils;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;

import java.math.BigDecimal;
import java.math.RoundingMode;

/**
 * 业务工具类
 *
 * @author ruoyi
 */
@Slf4j
public class CommonUtil {

    public static final String GEO_WEB_KEY = SpringUtils.getRequiredProperty("geo.key");


    /**
     * 格式化错误消息
     * @author ruoyi
     */
    public static String format(String status) {
        String msg = "车辆";
        // 检查status是否为null，避免空指针异常
        if (status == null) {
            return "Status cannot be null.";
        }
        // 使用switch语句重构原来的if-else结构
        switch (status) {
            case ServiceConstants.VEHICLE_STATUS_NOT_LISTING:
                return msg + ServiceConstants.VEHICLE_STATUS_NOT_LISTING_STR;
            case ServiceConstants.VEHICLE_STATUS_BE_SHARING:
                return msg + ServiceConstants.VEHICLE_STATUS_TEMPORARILY_SHARING;
            case ServiceConstants.VEHICLE_STATUS_IN_USING:
                return msg + ServiceConstants.VEHICLE_STATUS_IN_USING_STR;
            case ServiceConstants.VEHICLE_STATUS_TEMPORARILY_LOCK:
                return msg + ServiceConstants.VEHICLE_STATUS_TEMPORARILY_LOCK_STR;
            default:
                // 处理未知或新增的状态
                return "未知的车辆状态: " + status;
        }
    }


//    /**
//     * 根据定位获取地址
//     * @author ruoyi
//     */
//    public static String getAddressByGeo(String location) {
//        String address = null;
//        try {
//            String url = StrUtil.format("https://restapi.amap.com/v3/geocode/regeo?key={}&location={}&&radius=1000&extensions=all", GEO_WEB_KEY, location);
//            String result = HttpUtils.sendGet(url);
//            log.info("【根据定位获取地址】请求结果result:{}",result);
//            //将json字符串转换为Object
//            JSONObject jsonObject = JSONObject.parseObject(result,JSONObject.class);
//            JSONObject regeocode1 = jsonObject.getJSONObject("regeocode");
//            address = regeocode1.getString("formatted_address");
//            log.info("【根据定位获取地址】address=:【{}】",result);
//            return address;
//        } catch (Exception e) {
//            log.error("【根据定位获取地址】转换地址报错", e);
//        }
//        return address;
//    }

    /**
     * 获取省市县
     *
     * @author ruoyi
     */
    public static String getDistrictList() {
        String list = null;
        try {
            String url = StrUtil.format("https://restapi.amap.com/v3/config/district?key={}&keywords={}&subdistrict=3", GEO_WEB_KEY, "中国");
            String result = HttpUtils.sendGet(url);
//            log.info("【获取省市县】请求结果result:{}",result);
            //将json字符串转换为Object
            JSONObject jsonObject = JSONObject.parseObject(result,JSONObject.class);
            JSONArray districts = jsonObject.getJSONArray("districts");
            JSONObject jsonArray = (JSONObject)districts.get(0);
            JSONArray districts1 = jsonArray.getJSONArray("districts");
            list = districts1.toString();
//            log.info("【获取省市县】result=:【{}】",list);
            return list;
        } catch (Exception e) {
            log.error("【获取省市县】失败", e);
        }
        return list;
    }

    /**
     * 根据电压计算续航里程
     *
     * @param voltage 电压
     * @param fullVoltage 满电电压
     * @param lowVoltage 亏电电压
     * @param fullEndurance 满电续航里程
     * @author qzz
     */
    public static Integer getRemainingMileage(String voltage,Double fullVoltage,Double lowVoltage,Integer fullEndurance) {
        // 满电电压减去亏电电压 乘以 满电续航里程 除以 满电电压
        log.info(" 电压--voltage:{},满电电压--fullVoltage:{},亏电电压--lowVoltage:{},满电续航--fullEndurance:{}",voltage,fullVoltage,lowVoltage,fullEndurance);
        BigDecimal vol = new BigDecimal(voltage);
        BigDecimal current = new BigDecimal(fullVoltage).subtract(vol);
        BigDecimal full = new BigDecimal(fullVoltage).subtract(new BigDecimal(lowVoltage));
        BigDecimal divide = full.subtract(current).divide(full,2, RoundingMode.HALF_UP);//当前电量百分百
        log.info("当前电量百分百：{}%",divide.multiply(new BigDecimal(100)));
        BigDecimal multiply = divide.multiply(new BigDecimal(fullEndurance));
        // 剩余续航里程小于0 最小为0
        if(multiply.compareTo(new BigDecimal(0)) < 0){
            multiply = new BigDecimal(0);
        }
        // 剩余续航里程大于满电续航里程 最大为满电续航里程
        if(multiply.compareTo(new BigDecimal(fullEndurance)) > 0){
            multiply = new BigDecimal(fullEndurance);
        }
        log.info("当前剩余续航里程：{}km",multiply);
        return multiply.intValue();
    }

    /**
     * 根据电压计算电量百分比
     *
     * @param voltage 电压
     * @param fullVoltage 满电电压
     * @param lowVoltage 亏电电压
     * @author qzz
     */
    public static Integer getElectricQuantity(String voltage,Double fullVoltage,Double lowVoltage) {
        // 满电电压减去亏电电压 乘以 满电续航里程 除以 满电电压
        BigDecimal vol = new BigDecimal(voltage);
        BigDecimal current = new BigDecimal(fullVoltage).subtract(vol);
        BigDecimal full = new BigDecimal(fullVoltage).subtract(new BigDecimal(lowVoltage));
        BigDecimal divide = full.subtract(current).divide(full,2, RoundingMode.HALF_UP);//当前电量百分百
        BigDecimal multiply = divide.multiply(new BigDecimal(100));
        if(multiply.compareTo(new BigDecimal(100)) > 0){
            multiply = new BigDecimal(100);
        }
        // 电量小于0 最小为0
        if(multiply.compareTo(new BigDecimal(0)) < 0){
            multiply = new BigDecimal(0);
        }
//        log.info("当前电量百分百：{}%",multiply);
        return multiply.intValue();
    }

    /**
     * 根据电压计算电量百分比
     *
     * 计算公示： ((高电压-低电压) * 百分比 / 100 ) + 低电压
     *
     * @param percentage  百分比
     * @param fullVoltage 满电电压
     * @param lowVoltage 亏电电压
     * @author qzz
     */
    public static Integer getElectricQuantityByPercentage(Integer percentage,Double fullVoltage,Double lowVoltage) {
        BigDecimal lowVoltageBig = new BigDecimal(lowVoltage);
        BigDecimal full = new BigDecimal(fullVoltage).subtract(lowVoltageBig);
        BigDecimal multiply1 = full.multiply(new BigDecimal(percentage));
        BigDecimal divide1 = multiply1.divide(new BigDecimal(100), 2, RoundingMode.HALF_UP);
        BigDecimal add = divide1.add(lowVoltageBig);
        log.info("根据百分比计算出的电压：{}V",add);
        return add.intValue();
    }

    /** 坐标转换 */
    @NotNull
    public static double[] coordinateConvert(String lon1, String lat1) {
        BigDecimal lon = new BigDecimal(lon1);
        BigDecimal lat = new BigDecimal(lat1);
//        log.info("WGS84经纬度（未计算）：" + lon + "---" + lat);
        // 除以100
        lon = lon.divide(new BigDecimal(100), 10, RoundingMode.HALF_UP);
        lat = lat.divide(new BigDecimal(100), 10, RoundingMode.HALF_UP);
        // 取出lon中后面的小数点
        String[] lonStr = getDecimalPart(lon);
        String[] latStr = getDecimalPart(lat);
//        log.info("WGS84经纬度（截取小数点）：" + lonStr[0] + "---" + lonStr[1] + "---"+ latStr[0]+"---"+ latStr[1]);
        // 再将结果乘以5/3
        String lon2 = "0."+ lonStr[1];
        String lat2 = "0."+ latStr[1];
        BigDecimal lons = new BigDecimal(lon2).multiply(new BigDecimal(5).divide(new BigDecimal(3), 8, RoundingMode.HALF_UP));
        BigDecimal lats = new BigDecimal(lat2).multiply(new BigDecimal(5).divide(new BigDecimal(3), 8, RoundingMode.HALF_UP));
        BigDecimal lo = new BigDecimal(lonStr[0]).add(lons);
        BigDecimal la = new BigDecimal(latStr[0]).add(lats);
//        log.info("WGS84经纬度（计算后）：" + lo + "---" + la);
        lo = lo.setScale(8, RoundingMode.HALF_UP);
        la = la.setScale(8, RoundingMode.HALF_UP);
//        log.info("WGS84经纬度（保留8为小数）：" + lo + "---" + la);
        double[] doubles = GpsCoordinateUtils.calWGS84toGCJ02(la.doubleValue(), lo.doubleValue());
        return doubles;
    }

    public static String[] getDecimalPart(BigDecimal number) {
        // 将BigDecimal转换为字符串
        String numberStr = number.toPlainString();
        // 找到小数点的位置
        int indexOfDecimal = numberStr.indexOf(".");
        // 初始化结果数组
        String[] parts = new String[2];
        // 如果有小数点
        if (indexOfDecimal >= 0) {
            parts[0] = numberStr.substring(0, indexOfDecimal); // 整数部分
            parts[1] = numberStr.substring(indexOfDecimal + 1); // 小数部分
        } else {
            // 如果没有小数点，整数部分为整个字符串，小数部分为空
            parts[0] = numberStr;
            parts[1] = "";
        }
        return parts;
    }

    public static Double getDistance(String phoneLon, String phoneLat, BigDecimal lng, BigDecimal lat) {
        double[] point1 = {Double.parseDouble(phoneLon), Double.parseDouble(phoneLat)};
        double[] point2 = {lng.doubleValue(), lat.doubleValue()};
        double distanceInMeters = GeoUtils.haversineDistance(point1, point2);
        return Math.round((distanceInMeters / 1000) * 10) / 10.0;
    }
}
