package com.aiotagro.cattletrade.job;

import com.aiotagro.cattletrade.business.entity.Delivery;
import com.aiotagro.cattletrade.business.entity.DeliveryDevice;
import com.aiotagro.cattletrade.business.entity.JbqClientLog;
import com.aiotagro.cattletrade.business.entity.WarningLog;
import com.aiotagro.cattletrade.business.mapper.DeliveryDeviceMapper;
import com.aiotagro.cattletrade.business.mapper.DeliveryMapper;
import com.aiotagro.cattletrade.business.mapper.JbqClientLogMapper;
import com.aiotagro.cattletrade.business.mapper.WarningLogMapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

/**
 * 电子围栏预警
 */
@Slf4j
@Component
public class AutoNumWarningJob {

    @Autowired
    private DeliveryMapper deliveryMapper;

    @Autowired
    private DeliveryDeviceMapper deliveryDeviceMapper;

    @Autowired
    private WarningLogMapper warningLogMapper;

    @Autowired
    private JbqClientLogMapper jbqClientLogMapper;

    /**
     * 监管端电子围栏预警
     */
    @XxlJob("numberWarningJob")
    public void executeJob() {
        log.info("数量盘点预警开始!");
        long startTime = System.currentTimeMillis();
        //当前日期
        Date date=new Date();
        //查询当前时间四个小时之前的数据
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.HOUR_OF_DAY, -4);
        Date paramDate = calendar.getTime();
        //查询所有未核验的运单数据
        List<Delivery> deliverys = deliveryMapper.selectList(new LambdaQueryWrapper<Delivery>().eq(Delivery::getStatus, 1));
        if(CollectionUtils.isNotEmpty(deliverys)){
            deliverys.forEach(delivery -> {
                //查询运单关联的设备信息
                Integer deliveryId = delivery.getId();
                List<DeliveryDevice> deliverieDevices = deliveryDeviceMapper.selectList(new LambdaQueryWrapper<DeliveryDevice>().eq(DeliveryDevice::getDeliveryId, deliveryId));
                if(CollectionUtils.isNotEmpty(deliverieDevices)){
                    //运单绑定的主机信息
                    List<String> serverDeviceIds = deliverieDevices.stream().filter(deliveryDevice -> deliveryDevice.getDeviceType() == 1).map(DeliveryDevice::getDeviceId).collect(Collectors.toList());
                    //获取所有的耳标的信息
                    List<String> earDeviceIds = deliverieDevices.stream().filter(deliveryDevice -> deliveryDevice.getDeviceType() == 2).map(DeliveryDevice::getDeviceId).collect(Collectors.toList());
                    //查询当前绑定的耳标四个小时之前的上报数据
                    List<JbqClientLog> jbqClientLogs = jbqClientLogMapper.selectList(new LambdaQueryWrapper<JbqClientLog>().gt(JbqClientLog::getCreateTime, paramDate).in(JbqClientLog::getDeviceId,earDeviceIds));
                    //对日志信息去重
                    jbqClientLogs =
                            jbqClientLogs.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(o -> o.getDeviceId() + "#" + o.getServerDeviceId()))), ArrayList::new));
                    Map<String, List<JbqClientLog>> jbqCount = jbqClientLogs.stream().collect(Collectors.groupingBy(JbqClientLog::getServerDeviceId));
                    //获取运单申报的耳标数
                    Integer declaredJbqCount = delivery.getRegisteredJbqCount();
                    AtomicReference<String> warningtype = new AtomicReference<>("");
                    AtomicReference<Integer> inventoryJbqCount = new AtomicReference<>(0);
                    if(CollectionUtils.isNotEmpty(serverDeviceIds)){
                        serverDeviceIds.forEach(serverDeviceId -> {
                            List<JbqClientLog> jbqClientLogList = jbqCount.get(serverDeviceId);
                            //判断当前运单绑定的主机是否上报数据
                            if(CollectionUtils.isNotEmpty(jbqClientLogList)){
                                if(declaredJbqCount == jbqClientLogList.size()){
                                    warningtype.set("0");
                                }else{
                                    warningtype.set("2");
                                }
                                inventoryJbqCount.set(jbqClientLogList.size());
                            }else{
                                warningtype.set("2");
                            }
                        });
                        WarningLog warningLog = new WarningLog();
                        warningLog.setDeliveryId(deliveryId);
                        warningLog.setWarningType(warningtype.get());
                        warningLog.setInventoryJbqCount(inventoryJbqCount.get());
                        warningLog.setWarningTime(date);
                        warningLogMapper.insert(warningLog);
                    }
                }
            });

        }
        //查询当前时间点的设备上报数据
        long endTime = System.currentTimeMillis();
        log.info("数量盘点预警结束!耗时(毫秒)：{}",endTime-startTime);

    }

}
