package com.yeejoin.equipmanage.thread;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.yeejoin.equipmanage.common.entity.Car;
import com.yeejoin.equipmanage.common.entity.WlCarMileage;
import com.yeejoin.equipmanage.common.utils.CoordinateUtil;
import com.yeejoin.equipmanage.fegin.IotFeign;
import com.yeejoin.equipmanage.service.ICarService;
import com.yeejoin.equipmanage.service.impl.CarServiceImpl;
import com.yeejoin.equipmanage.service.impl.WlCarMileageServiceImpl;
import com.yeejoin.equipmanage.utils.CarUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;
import org.typroject.tyboot.core.restful.utils.ResponseModel;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
@Component
public class ThreadCarMileageTreatment extends Thread {
    Logger logger = LoggerFactory.getLogger(ThreadCarMileageTreatment.class);
    private final WlCarMileageServiceImpl wlCarMileageServiceImpl;
    private final ICarService iCarService;
    private final IotFeign iotFeign;
    @Value("${mileage.clippingtime}")
    private Long clipping_time;

    public ThreadCarMileageTreatment(WlCarMileageServiceImpl wlCarMileageServiceImpl, ICarService iCarService, IotFeign iotFeign) {
        this.wlCarMileageServiceImpl = wlCarMileageServiceImpl;
        this.iCarService = iCarService;
        this.iotFeign = iotFeign;
    }

    @Override
    public void run() {
        logger.info("----------------------------------------------------开始处理未结束里程---------------------------------");
        HashMap<String, String> hashMap = new HashMap<>();
        //toDo
        WlCarMileage last = null;
        JSONObject lastObj = null;
        Car car =null;
        List<WlCarMileage> wlCarMileageList = wlCarMileageServiceImpl.list(new QueryWrapper<WlCarMileage>().isNull("end_time"));
        for (int i = 0; i < wlCarMileageList.size(); i++) {
           car =  iCarService.getOne(new QueryWrapper<Car>().eq("iot_code", wlCarMileageList.get(i).getIotCode()));
            String coordinateSting = String.valueOf(car.getLongitude()) + String.valueOf(car.getLatitude());
            hashMap.put(car.getIotCode(), coordinateSting);
        }
        logger.info("----------------获取到的未处理的车辆坐标信息：："+JSONObject.toJSONString(hashMap));
        try {
            Thread.sleep(clipping_time);
            for (int i = 0; i < wlCarMileageList.size(); i++) {
                WlCarMileage wlCarMileage =wlCarMileageList.get(i);
                car = iCarService.getOne(new QueryWrapper<Car>().eq("iot_code", wlCarMileage.getIotCode()));
                String coordinateSting = String.valueOf(car.getLongitude()) + String.valueOf(car.getLatitude());
                //增加对于无效坐标的兼容处理，由于无效坐标的存储精度不一样  可能会导致0的位数发生差异从而到时无法判断生效
                if (coordinateSting.equals(hashMap.get(car.getIotCode()))||(handlerUnActiveCoodinate(coordinateSting).equals(handlerUnActiveCoodinate(hashMap.get(car.getIotCode()))))) {
                    String iotCode = car.getIotCode();
                    String measurement = iotCode.substring(0,8);
                    String deviceName = iotCode.replace(measurement, "");
                    last = wlCarMileageServiceImpl
                            .getOne(new LambdaQueryWrapper<WlCarMileage>().eq(WlCarMileage::getIotCode, iotCode)
                                    .isNull(WlCarMileage::getEndLongitude).isNull(WlCarMileage::getEndLatitude)
                                    .orderByDesc(WlCarMileage::getStartTime).last("limit 1"));
                    ResponseModel<List<Object>> result = iotFeign.getLiveData(measurement, deviceName,
                            last.getStartTime(), new Date(new Date().getTime() + 2000));
                    List<Object> list = result.getResult();
                    if (list != null && list.size() > 0) {
                        // 过滤空坐标
                        List<Object> filterList = new ArrayList<Object>();
                        for (int j = 0; j < list.size(); j++) {
                            JSONObject Obj = JSONObject.parseObject(JSONObject.toJSONString(list.get(j)));
                            if (Obj.get("FireCar_Longitude") != null && Obj.get("FireCar_Latitude") != null
                                    && Obj.getDoubleValue("FireCar_Longitude") != 0
                                    && Obj.getDoubleValue("FireCar_Latitude") != 0) {
                                filterList.add(list.get(j));
                                // 获取第一个不为空的坐标
                                lastObj = Obj;
                            }
                        }
                        logger.info("----------------------------------------lastobj----------------------"+lastObj.toJSONString());
                        if (lastObj == null) {
                            lastObj = new JSONObject();
                            lastObj.put("FireCar_Longitude", last.getStartLongitude());
                            lastObj.put("FireCar_Latitude", last.getEndLatitude());
                            lastObj.put("time", 0);
                            lastObj.put("FireCar_Speed", 0);
                        }
                        double endLongitude = lastObj.getDoubleValue("FireCar_Longitude");
                        double endLatitude = lastObj.getDoubleValue("FireCar_Latitude");
                        Date endTime = new Date();
                        long takeTime = (endTime.getTime() / 1000 * 1000) - (last.getStartTime().getTime() / 1000 * 1000);
                        if(takeTime<0){
                            takeTime = 0-takeTime;
                        }
                        last.setTakeTime(takeTime);
                        last.setEndLongitude(endLongitude);
                        last.setEndLatitude(endLatitude);
                        last.setEndTime(endTime);
                        last.setEndName(CarUtils.getAddress(endLongitude, endLatitude));
                        //原来的写法不够健壮，如果上报的数据为double写法则会直接报凑错
                        try {
                            Double.valueOf(lastObj.getDoubleValue("FireCar_Speed")).intValue();
                            if (ObjectUtils.isEmpty(lastObj.containsKey("FireCar_Speed"))) {
                                last.setEndSpeed(0);
                            } else {
                                last.setEndSpeed(Double.valueOf(lastObj.getString("FireCar_Speed")).intValue());
                            }
                        } catch (Exception exception) {
                            last.setEndSpeed(0);
                        }
                        double travel = 0.0;
                        // 获取里程
                        for (int k = 0; k < filterList.size() - 1; k++) {
                            JSONObject start = JSONObject.parseObject(JSONObject.toJSONString(filterList.get(k)));
                            JSONObject end = JSONObject.parseObject(JSONObject.toJSONString(filterList.get(k + 1)));
                            travel += CoordinateUtil.distance(start.getDoubleValue("FireCar_Latitude"),
                                    start.getDoubleValue("FireCar_Longitude"), end.getDoubleValue("FireCar_Latitude"),
                                    end.getDoubleValue("FireCar_Longitude"));
                        }
                        Double travle =new BigDecimal(travel / 1000).setScale(1, BigDecimal.ROUND_HALF_UP).doubleValue();
                        logger.info("---------------------本次里程：："+travle+"---------------------------------------");
                        last.setTravel(travle);
                        logger.info("----------------------------------------last----------------------"+lastObj.toJSONString());
                        wlCarMileageServiceImpl.updateById(last);
                    }
                }
            }
        } catch (Exception exception) {
            logger.info(exception.getMessage());
            wlCarMileageServiceImpl.updateById(last);
        }
    }
    public String handlerUnActiveCoodinate(String coodeinateString){
        return coodeinateString.replace("0","").replace(".","");
    }
}

