package cn.component.message.mq;

import cn.util.core.LogKit;
import cn.util.core.TypeKit;
import com.rabbitmq.client.Channel;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import cn.facade.abs.IService;
import cn.component.RedisKit;
import cn.orm.sqltoy.plus.Wrappers;
import cn.orm.sqltoy.plus.query.LambdaQueryWrapper;
import cn.pojo.atv.AtvBoardCard;
import cn.pojo.atv.AtvBoardCardFault;
import cn.pojo.atv.AtvEquipment;
import cn.pojo.atv.AtvTrainWorkingLog;
import cn.pojo.atv.AtvWarnLog;
import cn.util.core.IsKit;

import java.io.IOException;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**ATV消息得处理者
 * 需要创建队列atv.websocket.update.handle
 **/
@Component
@RabbitListener(queues = "atv.websocket.update.handle", ackMode = "AUTO")
public class UpdateRabbitMsg extends IService
{
	@Autowired
	private RedisKit redisCache;

	@RabbitHandler
	public void handler(JSONObject jsonObject, Channel channel, Message msg) throws IOException {
		JSONArray atvWarnLogs = jsonObject.getJSONArray("atvWarnLog");
		JSONArray atvBoardCards = jsonObject.getJSONArray("atvBoardCard");
		JSONArray atvBoardCardFaults = jsonObject.getJSONArray("atvBoardCardFault");
		JSONArray atvTrainWorkingLogs = jsonObject.getJSONArray("atvTrainWorkingLog");
		JSONArray atvEquipments = jsonObject.getJSONArray("atvEquipment");

		for (Object atvWarnLog : atvWarnLogs) {
			AtvWarnLog warnLog = (AtvWarnLog) atvWarnLog;
			daoService.save(warnLog);
		}

		for (Object atvBoardCard : atvBoardCards) {
			AtvBoardCard boardCard = (AtvBoardCard) atvBoardCard;
			daoService.update(boardCard);
		}

		for (Object atvBoardCardFault : atvBoardCardFaults) {
			AtvBoardCardFault boardCardFault = (AtvBoardCardFault) atvBoardCardFault;
			daoService.saveOrUpdate(boardCardFault);
		}

		for (Object atvTrainWorkingLog : atvTrainWorkingLogs) {
			AtvTrainWorkingLog trainWorkingLog = (AtvTrainWorkingLog) atvTrainWorkingLog;
			// 报站开始标志位
			int paStartFlag = trainWorkingLog.getPaStartFlag();
			// 获取当前时间
			LocalDateTime createTime = LocalDateTime.now();
			/* 列车进站报站 */
			if(paStartFlag == 1){
				trainWorkingLog.setPreStartTime(createTime); //将开始报站时间设为该条数据的创建时间
				trainWorkingLog.setPreDuration(0); // 将报站时长设为0
			}
			/* 列车出站报站 */
			else if(paStartFlag == 2){
				Map<String, Object> paramsMap = new HashMap<>();
				paramsMap.put("trainId", trainWorkingLog.getTrainId());
				// 查找本次列车报站进站时的数据（上一条本列车进站报站数据）
				List<AtvTrainWorkingLog> lastTrainWorkingLogList = TypeKit.cast(daoService.getEntityListBySql("atv_LastTrainWorkingLogTime", paramsMap, AtvTrainWorkingLog.class));
				if (IsKit.isNotNull(lastTrainWorkingLogList)) {
					AtvTrainWorkingLog lastTrainWorkingLog = lastTrainWorkingLogList.get(0);
					System.out.println(lastTrainWorkingLog);
					// 计算报站时长
					Duration duration = Duration.between(lastTrainWorkingLog.getCreateTime(),createTime);
					trainWorkingLog.setPreDuration((int) duration.toMinutes());
					// 设置报站开始时间为该列车进站报站时间
					trainWorkingLog.setPreStartTime(lastTrainWorkingLog.getPreStartTime());
				}
				LogKit.info("报站时长为：" + trainWorkingLog.getPreDuration() + "秒");
			}
			// 不报站就不计算报站时长与报站开始时间
			daoService.saveOrUpdate(trainWorkingLog);
		}

		for (Object atvEquipment : atvEquipments) {
			AtvEquipment equipment = (AtvEquipment) atvEquipment;
			//atvEquipmentService.updateById(equipment);
			// BJTU 2022.11.9 更新失败则插入
			if (IsKit.isNotNull(equipment)) {
				mysqlAndRedis(equipment);
			}
		}

//		channel.basicAck(msg.getMessageProperties().getDeliveryTag(), false);
//		LogKit.info("atv.websocket.update.handle消息处理成功--------------------------------------------------------\n");
	}

	/**
	 * BJTU 2022.11.9
	 * 更新设备信息，更新失败则插入
	 * @param equipment 设备
	 */
	public void mysqlAndRedis(AtvEquipment equipment) 
	{
		String equipmentKey = equipment.getCarriageId() + equipment.getSn();
		if (IsKit.isNull(redisCache.hget("equipment", equipmentKey))) {
			redisCache.hset("equipment", equipmentKey, equipment);
		}
		daoService.saveOrUpdate(equipment);
		LambdaQueryWrapper<AtvEquipment> wrapper = Wrappers.lambdaWrapper(AtvEquipment.class)
	                .select(AtvEquipment::getId)
	                .eq(AtvEquipment::getAreaId,equipment.getAreaId())
	                .eq(AtvEquipment::getCountryId,equipment.getCountryId())
	                .eq(AtvEquipment::getLineId,equipment.getLineId())
	                .eq(AtvEquipment::getTrainId,equipment.getTrainId())
	                .eq(AtvEquipment::getCarriageId,equipment.getCarriageId())
	                .eq(AtvEquipment::getSn,equipment.getSn())
	                ;
		AtvEquipment entity = daoService.findOne(wrapper); 
		if (IsKit.isNotNull(entity)) {
			equipment.setId(entity.getId());
		}
		redisCache.hset("equipment", equipmentKey, equipment);
	}
}
