package com.yeejoin.equipmanage.listener;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
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.IWlCarMileageService;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.typroject.tyboot.component.emq.EmqKeeper;
import org.typroject.tyboot.component.emq.EmqxListener;
import org.typroject.tyboot.core.restful.utils.ResponseModel;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

@Component
public class CarIotListener extends EmqxListener {

	@Autowired
	private IWlCarMileageService iWlCarMileageService;

	@Autowired
	private ICarService iCarService;

	@Autowired
	private IotFeign iotFeign;

	private final String GUIDE_KEY = "813684495d9a3981dd2c7694916fe404";

	private final String GUIDE_URL = "https://restapi.amap.com/v3/geocode/regeo?";

	@Autowired
	private EmqKeeper emqkeeper;

	private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

	@Override
	public void processMessage(String topic, MqttMessage message) throws Exception {
		JSONObject jsonObject = JSONObject.parseObject(message.toString());
		if (jsonObject.containsKey("startUp") || jsonObject.containsKey("FireCar_Longitude")) {
			System.out.println(topic);
			System.out.println(message);
			String measurement = topic.split("/")[0];
			String deviceName = topic.split("/")[1];
			String iotCode = measurement + deviceName;
			if (jsonObject.containsKey("startUp")) {
				if (jsonObject.getBooleanValue("startUp")) {
					WlCarMileage wlCarMileage = new WlCarMileage();
					wlCarMileage.setIotCode(iotCode);
					wlCarMileage.setDate(new Date());
					// 获取开始坐标
					double startLongitude = jsonObject.getDoubleValue("FireCar_Longitude");
					double startLatitude = jsonObject.getDoubleValue("FireCar_Latitude");
					// String currentTime = "20"+jsonObject.getString("currentTime");
					wlCarMileage.setStartLongitude(startLongitude);
					wlCarMileage.setStartLatitude(startLatitude);
					// Date startTime = UTCToCST();
					Date startTime = new Date(jsonObject.getLong("time"));
					wlCarMileage.setStartTime(startTime);
					wlCarMileage.setStartName(getAddress(startLongitude, startLatitude));
					wlCarMileage.setStartSpeed(jsonObject.getIntValue("FireCar_Speed"));
					try {
						iWlCarMileageService.save(wlCarMileage);
					} catch (Exception e) {
						e.printStackTrace();
						iWlCarMileageService.save(wlCarMileage);
					}
				} else {
					// 获取结束坐标
					WlCarMileage last = iWlCarMileageService
							.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) {
						// 获取最后一个有坐标的数据
						JSONObject lastObj = null;
						// 过滤空坐标
						List<Object> filterList = new ArrayList<Object>();
						for (int i = 0; i < list.size(); i++) {
							JSONObject Obj = JSONObject.parseObject(JSONObject.toJSONString(list.get(i)));
							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(i));
								// 获取第一个不为空的坐标
								if (lastObj == null) {
									lastObj = Obj;
								}
							}
						}
						// JSONObject lastObj =
						// JSONObject.parseObject(JSONObject.toJSONString(list.get(list.size() - 1)));
						if (lastObj == null) {
							lastObj = new JSONObject();
							lastObj.put("FireCar_Longitude", 0.0);
							lastObj.put("FireCar_Latitude", 0.0);
							lastObj.put("time", 0);
							lastObj.put("FireCar_Speed", 0);
						}
						double endLongitude = lastObj.getDoubleValue("FireCar_Longitude");
						double endLatitude = lastObj.getDoubleValue("FireCar_Latitude");
						// 230215180624
						// Date endTime =UTCToCST(lastObj.getString("time"));

						Date endTime = new Date(jsonObject.getLong("time"));
						long takeTime = (endTime.getTime()/1000*1000) - (last.getStartTime().getTime()/1000*1000) ;
						last.setEndLongitude(endLongitude);
						last.setEndLatitude(endLatitude);
						last.setEndTime(endTime);
						last.setEndName(getAddress(endLongitude, endLatitude));
						last.setEndSpeed(lastObj.getIntValue("FireCar_Speed"));
						last.setTakeTime(takeTime);
						double travel = 0.0;
						// 获取里程
						for (int i = 0; i < filterList.size() - 1; i++) {
							JSONObject start = JSONObject.parseObject(JSONObject.toJSONString(filterList.get(i)));
							JSONObject end = JSONObject.parseObject(JSONObject.toJSONString(filterList.get(i + 1)));
							travel += CoordinateUtil.distance(start.getDoubleValue("FireCar_Latitude"),
									start.getDoubleValue("FireCar_Longitude"), end.getDoubleValue("FireCar_Latitude"),
									end.getDoubleValue("FireCar_Longitude"));
						}
						last.setTravel(new BigDecimal(travel/1000).setScale(1, BigDecimal.ROUND_HALF_UP).doubleValue());
						try {
							iWlCarMileageService.updateById(last);
						} catch (Exception e) {
							iWlCarMileageService.updateById(last);
						}
					}
				}
			} else if (jsonObject.containsKey("FireCar_Longitude")) {
				if (jsonObject.containsKey("FireCar_Longitude") && jsonObject.containsKey("FireCar_Latitude")) {
					// 获取开始坐标
					double startLongitude = jsonObject.getDoubleValue("FireCar_Longitude");
					double startLatitude = jsonObject.getDoubleValue("FireCar_Latitude");
					int direction = jsonObject.getIntValue("direction");

					// 地图推送消息
					Car car = iCarService.getOne(new LambdaQueryWrapper<Car>().eq(Car::getIotCode, iotCode));
					if (car != null && startLongitude != 0 && startLatitude != 0) {
						JSONArray sendArr = new JSONArray();
						JSONObject sendObj = new JSONObject();
						sendObj.put("id", String.valueOf(car.getId()));
						sendObj.put("direction", direction);
						sendObj.put("longitude", String.valueOf(startLongitude));
						sendObj.put("latitude", String.valueOf(startLatitude));
						sendObj.put("carNum", car.getCarNum());
						sendObj.put("bizOrgName", car.getBizOrgName());
						sendArr.add(sendObj);
						MqttMessage mqttMessage = new MqttMessage();
						mqttMessage.setPayload(sendArr.toJSONString().getBytes());
						car.setLongitude(startLongitude);
						car.setLatitude(startLatitude);
						iCarService.updateById(car);
						emqkeeper.getMqttClient().publish("car/location", mqttMessage);
					}
				}
			}
		}

	}

	public String getAddress(double longitude, double lantitude) {
		StringBuilder api = new StringBuilder(GUIDE_URL);
		api.append("key=").append(GUIDE_KEY).append("&location=").append(longitude).append(",").append(lantitude)
				.append("&radius=1000").append("&batch=false").append("&extensions=base").append("&roadlevel=0")
				.append("&batch=false");
		StringBuilder res = new StringBuilder();
		BufferedReader in = null;
		try {
			System.out.println(api.toString());
			URL url = new URL(api.toString());
			HttpURLConnection conn = (HttpURLConnection) url.openConnection();
			conn.setDoOutput(true);
			conn.setRequestMethod("POST");
			in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));
			String line;
			while ((line = in.readLine()) != null) {
				res.append(line).append("\n");
			}
			JSONObject object = JSONObject.parseObject(res.toString());
			System.out.println(object);
			JSONObject regeocode = object.getJSONObject("regeocode");
			String address = regeocode.getString("formatted_address");
			if ("[]".equals(address)) {
				System.out.println("===============无效坐标:" + longitude + "," + lantitude);
				address = "无效坐标";
			}
			res = new StringBuilder(address);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				if (in != null) {
					in.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return res.toString();
	}

	public Date UTCToCST(String UTCStr) throws ParseException {
		Date date = sdf.parse(UTCStr);
		System.out.println("UTC时间: " + date);
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.set(Calendar.HOUR, calendar.get(Calendar.HOUR) + 8);
		return calendar.getTime();
	}
}
