package com.ho.flow.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.ho.business.constant.DeviceTypeConstant;
import com.ho.business.entity.*;
import com.ho.business.vo.req.DeviceReqVO;
import com.ho.business.vo.req.MonitorQuery;
import com.ho.business.vo.req.StationPageReqVO;
import com.ho.business.vo.req.device.DeviceTypeQuery;
import com.ho.business.vo.resp.DeviceRespVO;
import com.ho.common.tools.constant.CommonConstant;
import com.ho.common.tools.constant.RedisKeyConstant;
import com.ho.common.tools.entity.SimpleUser;
import com.ho.common.tools.entity.UserDetailRespVO;
import com.ho.common.tools.exception.BaseResponseCode;
import com.ho.common.tools.exception.BusinessException;
import com.ho.common.tools.exception.DataResult;
import com.ho.common.tools.service.RedisService;
import com.ho.common.tools.util.PageResult;
import com.ho.common.tools.util.PageUtils;
import com.ho.common.tools.util.TranslateUtils;
import com.ho.flow.constant.FlowConstant;
import com.ho.flow.constant.WorkOrderConstant;
import com.ho.flow.entity.process.MovementDTO;
import com.ho.flow.feignclient.BusinessFeignClient;
import com.ho.flow.mapper.EventMapper;
import com.ho.flow.mapper.TranslateNameMapper;
import com.ho.flow.monitor.EventToProcessMonitor;
import com.ho.flow.service.*;
import com.ho.flow.vo.Event;
import com.ho.flow.vo.EventVo;
import com.ho.flow.vo.WorkOrderCirculation;
import com.ho.flow.vo.WorkOrderOld;
import com.ho.flow.vo.req.AlarmConfig.AlarmConfigQueryVo;
import com.ho.flow.vo.req.SendSmsConfig.SendSmsConfigQueryReq;
import com.ho.flow.vo.req.event.*;
import com.ho.flow.vo.req.workorder.DoTaskReq;
import com.ho.flow.vo.req.workorder.WorkOrderAddReqVO;
import com.ho.flow.vo.resp.event.*;
import jodd.util.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.time.DateUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author yule
 * @description 针对表【event】的数据库操作Service实现
 * @createDate 2022-08-25 16:05:20
 */
@Service
@Slf4j
public class EventServiceImpl implements EventService {

    @Autowired
    EventMapper eventMapper;

    @Autowired
    BusinessFeignClient businessFeignClient;

    @Autowired(required = false)
    WorkOrderHisService workOrderHisService;

    @Autowired(required = false)
    WorkOrderCirculationService workOrderCirculationService;

    @Autowired
    Snowflake snowflake;

    @Autowired
    private RedisService redisService;

    @Autowired
    SendSmsConfigService sendSmsConfigService;

    @Value("${station.timeDifference}")
    Integer minute;

    @Value("${station.outSideMinute}")
    Integer outSideMinute;

    @Autowired
    TranslateNameMapper translateNameMapper;

    EventToProcessMonitor monitor = new EventToProcessMonitor();

    //事件转工单
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void conversionWorkOrder(List<Long> eventIds, SimpleUser user) {
        List<Event> events = eventMapper.selectByIds(eventIds);
        List<WorkOrderOld> workOrderOlds = new ArrayList<>();
        List<WorkOrderCirculation> workOrderCirculations = new ArrayList<>();
        //判断是否能转工单
        for (Event event : events) {
            if (!event.getEventType().equals(CommonConstant.EventType.alarm)) {
                throw new BusinessException(BaseResponseCode.WORK_ORDER_NOT_CONVERSION);
            } else {
                if (event.getEventLevel().equals(CommonConstant.EventLevel.notice)) {
                    throw new BusinessException(BaseResponseCode.WORK_ORDER_NOT_CONVERSION);
                }
            }
        }
        for (Event event : events) {
            //工单对象赋值
            WorkOrderOld workOrderOld = new WorkOrderOld();
            //生成工单号
            //String workOrderId = busiTool.getNextWorkOrderId(WorkOrderConstant.IdTypeWorkOrder);
            String workOrderId = null;
            workOrderOld.setId(snowflake.nextId());
            workOrderOld.setOrderId(workOrderId);
            workOrderOld.setStationId(event.getStationId());
            workOrderOld.setGroupId(event.getGroupId());
            workOrderOld.setDeptId(event.getDeptId());
            workOrderOld.setDesc(event.getDescription());
            workOrderOld.setEventId(event.getId());
            workOrderOld.setEventLevel(event.getEventLevel());
            workOrderOld.setFromId(user.getUserId());
            workOrderOld.setWorkOrderStatus(WorkOrderConstant.WorkOrderStatus.toBeAllocate);
            workOrderOld.setWorkOrderType(WorkOrderConstant.WorkOrderType.manual);
            workOrderOlds.add(workOrderOld);
            //工单流转对象赋值
            WorkOrderCirculation workOrderCirculation = new WorkOrderCirculation();
            BeanUtils.copyProperties(workOrderOld, workOrderCirculation, "id");
            workOrderCirculation.setId(snowflake.nextId());
            workOrderCirculation.setWorkOrderAction(WorkOrderConstant.WorkOrderAction.workOrderCreate);
            workOrderCirculation.setToId(null);
            workOrderCirculations.add(workOrderCirculation);
        }
        //workOrderService.insertEventBatch(workOrders);
        //workOrderCirculationService.insertEventBatch(workOrderCirculations);
    }

    @Override
    public PageResult<EventRespVO> pageEventInfo(EventReqPageVO vo) {
        /*if (vo.getDeviceTypeList() != null && !vo.getDeviceTypeList().isEmpty()) {
            //生成typeContrastList
            List<TypeContrast> typeContrasts = dealDeviceType(vo.getDeviceTypeList());
            vo.setTypeContrasts(typeContrasts);
        }*/
        PageHelper.startPage(vo.getPageNum(), vo.getPageSize());

        //通过遍历events集合获取到stationIds和deviceIds的集合
        //List<EventRespVO> events = eventMapper.selectByInfo(vo, user.getDepts());
        //不传人员所属部门
        List<EventRespVO> events = eventMapper.selectByInfo(vo, null);
        List<Integer> stationIds = new ArrayList<>();
//        List<Integer> deviceIds = new ArrayList<>();
        List<String> deviceTypeList = new ArrayList<>();
        Map<String, String> devices = new HashMap<>();
        for (EventRespVO event : events) {
            stationIds.add(event.getStationId());
//            deviceIds.add(event.getDeviceTypeId());
            deviceTypeList.add(event.getDeviceType());
        }
        //将deviceIds集合转化为map(key = deviceId , value = deviceName)
//        if (!deviceIds.isEmpty()) {
//            DataResult<List<DeviceType>> result = businessFeignClient.getDeviceTypes(deviceIds);
//            List<DeviceType> deviceList = result.getData();
//            for (DeviceType device : deviceList) {
//                devices.put(device.getId(), device.getName());
//            }
//        }
        if (!deviceTypeList.isEmpty()) {
            DeviceTypeQuery deviceTypeQuery = new DeviceTypeQuery();
            deviceTypeQuery.setDeviceTypeList(deviceTypeList);
            List<DeviceTypeConfig> deviceTypeConfigList = businessFeignClient.getDeviceTypeConfigList(deviceTypeQuery);
            for (DeviceTypeConfig device : deviceTypeConfigList) {
                devices.put(device.getDeviceType(), device.getName());
            }
        }
//        Map<String, String> devices = new HashMap<>();
        List<Integer> stationIdList = stationIds.stream().distinct().collect(Collectors.toList());
        Map<String, Device> idDeviceNameMap = null;
        if (!stationIdList.isEmpty()) {
            DeviceReqVO deviceReqVO = new DeviceReqVO();
            deviceReqVO.setStationIds(stationIdList);
            deviceReqVO.setLang(vo.getLang());
            DataResult<List<Device>> result = businessFeignClient.selectDeviceByStationIds(deviceReqVO);
            List<Device> deviceList = result.getData();
            idDeviceNameMap = deviceList.stream().collect(Collectors.toMap(d -> d.getSrcId() + "-" + d.getStationId(), Function.identity(), (d1, d2) -> d1));
        }
        List<Long> eventIds = new ArrayList<>();
        StationPageReqVO spv = new StationPageReqVO();
        spv.setIds(stationIdList);
        spv.setLang(vo.getLang());
        DataResult<List<Station>> listDataResult = businessFeignClient.selectStationByCondition(spv);
        List<Station> stationList = listDataResult.getData();
        Map<Integer, String> stationIdNameMap = stationList.stream().collect(Collectors.toMap(Station::getId, Station::getName));
        String name = null;
        Device device = null;
        //在通过遍历将stationName和deviceName赋值
        for (EventRespVO event : events) {
            //DataResult<Station> result = businessFeignClient.selectByStationId(event.getStationId());
            //Station station = result.getData();
            name = stationIdNameMap.get(event.getStationId());
            if (name != null) {
                event.setStationName(name);
            }
            if (null != idDeviceNameMap) {
                device = idDeviceNameMap.get(event.getTargetDevice() + "-" + event.getStationId());
                if (device != null) {
                    event.setName(device.getDeviceName());
                }
            }
//            event.setDeviceName(devices.get(event.getDeviceTypeId()));
            event.setDeviceName(devices.get(event.getDeviceType()));
            Integer eventLevel = event.getEventLevel();
            //判断事件是否为告警类型
            if (eventLevel != null) {
                //判断是否为告警等级中的越限和变位
                if (eventLevel.equals(CommonConstant.EventLevel.overLimit) || eventLevel.equals(CommonConstant.EventLevel.statusChange)) {
                    eventIds.add(event.getId());
                }
                //判断是否为告警等级中的告知
                else if (eventLevel.equals(CommonConstant.EventLevel.notice)) {
                    event.setConversionStatus(CommonConstant.EventConversionStatus.doNotConversion);
                } else {
                    event.setConversionStatus(CommonConstant.EventConversionStatus.Conversion);
                }

            } else {
                event.setConversionStatus(CommonConstant.EventConversionStatus.doNotConversion);
            }
        }
        //根据告警id查询工单
        List<WorkOrderOld> workOrderOlds = new ArrayList<>();
        if (!eventIds.isEmpty()) {
            // 先注释 工单已经转移到 flow-center
            //workOrders = workOrderService.selectByEventIds(eventIds);
        }
        if (!workOrderOlds.isEmpty() && !eventIds.isEmpty()) {
            for (EventRespVO event : events) {
                if (event.getConversionStatus() == null) {
                    for (WorkOrderOld workOrderOld : workOrderOlds) {
                        //判断告警数据是否已经生成了工单
                        if (workOrderOld.getEventId().equals(event.getId())) {
                            event.setConversionStatus(CommonConstant.EventConversionStatus.Conversion);
                            break;
                        } else {
                            event.setConversionStatus(CommonConstant.EventConversionStatus.NotConversion);
                        }
                    }
                }
            }
        }
        PageResult pageResult = PageUtils.getPageResult(new PageInfo<>(events));
        return pageResult;
    }


    @Override
    public List<EventRespVO> eventInfo(EventReqPageVO vo) {
        //先判断是否传入勾选的告警id
        List<EventRespVO> events = new ArrayList<>();
        if (!vo.getIds().isEmpty()) {
            List<Event> eventList = eventMapper.selectByIds(vo.getIds());
            for (Event event : eventList) {
                EventRespVO eventRespVO = new EventRespVO();
                BeanUtils.copyProperties(event, eventRespVO);
                events.add(eventRespVO);
            }
        } else {
            events = eventMapper.selectByInfo(vo, null);
        }
        List<Integer> stationIds = new ArrayList<>();
        List<String> deviceTypeList = new ArrayList<>();
        Map<String, String> devices = new HashMap<>();
        for (EventRespVO event : events) {
            stationIds.add(event.getStationId());
            deviceTypeList.add(event.getDeviceType());
        }

        if (!deviceTypeList.isEmpty()) {
            DeviceTypeQuery deviceTypeQuery = new DeviceTypeQuery();
            deviceTypeQuery.setDeviceTypeList(deviceTypeList);
            List<DeviceTypeConfig> deviceTypeConfigList = businessFeignClient.getDeviceTypeConfigList(deviceTypeQuery);
            for (DeviceTypeConfig device : deviceTypeConfigList) {
                devices.put(device.getDeviceType(), device.getName());
            }
        }
        List<Integer> stationIdList = stationIds.stream().distinct().collect(Collectors.toList());
        Map<String, Device> idDeviceNameMap = null;
        if (!stationIdList.isEmpty()) {
            DeviceReqVO deviceReqVO = new DeviceReqVO();
            deviceReqVO.setStationIds(stationIdList);
            DataResult<List<Device>> result = businessFeignClient.selectDeviceByStationIds(deviceReqVO);
            List<Device> deviceList = result.getData();
            idDeviceNameMap = deviceList.stream().collect(Collectors.toMap(d -> d.getSrcId() + "-" + d.getStationId(), Function.identity(), (d1, d2) -> d1));
        }
        List<Long> eventIds = new ArrayList<>();
        DataResult<List<Station>> listDataResult = businessFeignClient.selectByStationIds(stationIdList);
        List<Station> stationList = listDataResult.getData();
        Map<Integer, String> stationIdNameMap = stationList.stream().collect(Collectors.toMap(Station::getId, Station::getName));
        String name = null;
        Device device = null;
        //在通过遍历将stationName和deviceName赋值
        for (EventRespVO event : events) {
            name = stationIdNameMap.get(event.getStationId());
            if (name != null) {
                event.setStationName(name);
            }
            if (null != idDeviceNameMap) {
                device = idDeviceNameMap.get(event.getTargetDevice() + "-" + event.getStationId());
                if (device != null) {
                    event.setName(device.getDeviceName());
                }
            }
            event.setDeviceName(devices.get(event.getDeviceType()));
            Integer eventLevel = event.getEventLevel();
            //判断事件是否为告警类型
            if (eventLevel != null) {
                //判断是否为告警等级中的越限和变位
                if (eventLevel.equals(CommonConstant.EventLevel.overLimit) || eventLevel.equals(CommonConstant.EventLevel.statusChange)) {
                    eventIds.add(event.getId());
                }
                //判断是否为告警等级中的告知
                else if (eventLevel.equals(CommonConstant.EventLevel.notice)) {
                    event.setConversionStatus(CommonConstant.EventConversionStatus.doNotConversion);
                } else {
                    event.setConversionStatus(CommonConstant.EventConversionStatus.Conversion);
                }

            } else {
                event.setConversionStatus(CommonConstant.EventConversionStatus.doNotConversion);
            }
        }
        //根据告警id查询工单
        List<WorkOrderOld> workOrderOlds = new ArrayList<>();
        if (!eventIds.isEmpty()) {
            // 先注释 工单已经转移到 flow-center
            //workOrders = workOrderService.selectByEventIds(eventIds);
        }
        if (!workOrderOlds.isEmpty() && !eventIds.isEmpty()) {
            for (EventRespVO event : events) {
                if (event.getConversionStatus() == null) {
                    for (WorkOrderOld workOrderOld : workOrderOlds) {
                        //判断告警数据是否已经生成了工单
                        if (workOrderOld.getEventId().equals(event.getId())) {
                            event.setConversionStatus(CommonConstant.EventConversionStatus.Conversion);
                            break;
                        } else {
                            event.setConversionStatus(CommonConstant.EventConversionStatus.NotConversion);
                        }
                    }
                }
            }
        }
        return events;
    }


    //告警列表
    @Override
    public List<EventRespVO> eventList(EventReqPageVO vo) {
        List<EventRespVO> events = eventMapper.selectByInfo(vo, null);
        if (events == null || events.isEmpty()) {
            return new ArrayList<>();
        }
        List<Integer> stationList = events.stream().distinct().map(EventRespVO::getStationId).collect(Collectors.toList());
        //站点id与站点名称
        Map<Integer, String> idNameMap = new HashMap<>();
        Station station = null;
        for (Integer i : stationList) {
            String key = RedisKeyConstant.STATION + i;
            if (redisService.hasKey(key)) {
                station = (Station) redisService.get(key);
            } else {
                DataResult<Station> result = businessFeignClient.selectByStationId(i);
                station = result.getData();
            }
            if (null != station) {
                idNameMap.put(station.getId(), station.getName());
            }
        }
        //只需要塞值电站名称
        String name = null;
        for (EventRespVO event : events) {
            //从电站缓存中拿名称
            name = idNameMap.get(event.getStationId());
            if (name != null) {
                event.setStationName(name);
            }
        }
        return events;
    }

    //不再使用了,之前的递归方式效率太低
    @Deprecated
    private List<TypeContrast> dealDeviceType(List<DeviceType> deviceTypeList) {
        List<TypeContrast> list = new ArrayList<>();
        deviceTypeList.stream().forEach(d -> {
            TypeContrast typeContrast = new TypeContrast();
            Integer layer = 0; //记录遍历的层级
            DeviceTypeComp comp = new DeviceTypeComp();
            BeanUtil.copyProperties(d, comp);
            //创建DeviceType的集合,用于保存每次递归之后的值
            List<DeviceType> deviceTypes = new ArrayList<>();
            deviceTypes.add(d);
            DeviceTypeComp recursion = getRecursion(comp, layer, deviceTypes);
            //根据层次来创建
            //有两层
            if (recursion.getLayer() != null) {
                if (recursion.getLayer().equals(1)) {
                    DeviceType deviceType0 = deviceTypes.get(0);
                    DeviceType deviceType1 = deviceTypes.get(1);
                    typeContrast.setType(deviceType0.getTypeId());
                    typeContrast.setCategory(deviceType1.getTypeId());
                }
                //有三层
                else if (recursion.getLayer().equals(2)) {
                    DeviceType deviceType0 = deviceTypes.get(0);
                    DeviceType deviceType1 = deviceTypes.get(1);
                    DeviceType deviceType2 = deviceTypes.get(2);
                    typeContrast.setSubType(deviceType0.getTypeId());
                    typeContrast.setType(deviceType1.getTypeId());
                    typeContrast.setCategory(deviceType2.getTypeId());
                }
            }
            list.add(typeContrast);
        });
        return list;
    }

    //递归查询设备类型
    private DeviceTypeComp getRecursion(DeviceTypeComp comp, int layer, List<DeviceType> deviceTypes) {
        if (CommonConstant.TOP_PARENT_ID.equals(comp.getPid())) {
            return comp;
        }
        DataResult<DeviceType> result = businessFeignClient.selectByPId(comp.getPid());
        DeviceType one = result.getData();
        deviceTypes.add(one);
        layer++;
        BeanUtil.copyProperties(one, comp);
        comp.setLayer(layer);
        getRecursion(comp, layer, deviceTypes);
        return comp;
    }

    @Override
    public int updateById(List<Long> ids, UserDetailRespVO userDetail) {

        if (ids.isEmpty()) {
            return 0;
        }
        int i = eventMapper.updateByIds(ids, userDetail);
        return i;
    }

    @Override
    public int insertEventBatch(List<Event> events) {
        if (events.isEmpty()) {
            return 0;
        }
        int i = eventMapper.insertBatch(events);
        return i;
    }

    @Override
    public int updateEventBatch(List<Event> events) {
        if (events.isEmpty()) {
            return 0;
        }
        int i = 0;
        for (Event e : events) {
            i += eventMapper.updateBatchById(e);
        }
        return i;
    }

    @Override
    public EventNumRespVO selectNum(EventReqPageVO vo, SimpleUser user) {
        //通过递归获取到typeContrast集合
        //2023-02-03 增加了device_type_id字段, 不用递归了
       /* if (vo.getDeviceTypeList() != null && !vo.getDeviceTypeList().isEmpty()) {
            //生成typeContrastList
            List<TypeContrast> typeContrasts = dealDeviceType(vo.getDeviceTypeList());

            //vo.setTypeContrasts(typeContrasts);
        }*/
        //查询告警类型的数量和总数
        List<EventTypeNum> eventTypeNums = eventMapper.selectNumByType(vo, null);
        Integer sumTypes = 0;
        if (eventTypeNums != null && !eventTypeNums.isEmpty()) {
            for (EventTypeNum eventTypeNum : eventTypeNums) {
                sumTypes += eventTypeNum.getCount();
            }
        }
        //查询告警等级的数量与总数
        List<EventLevelNum> eventLevelNums = eventMapper.selectNumByLevel(vo, null);
        Integer sumLevels = 0;
        if (eventLevelNums != null && !eventLevelNums.isEmpty()) {
            for (EventLevelNum eventLevelNum : eventLevelNums) {
                sumLevels += eventLevelNum.getCount();
            }
        }
        //给返回值类型赋值
        EventNumRespVO eventNumRespVO = new EventNumRespVO();
        eventNumRespVO.setTypeNums(eventTypeNums);
        eventNumRespVO.setLevelNums(eventLevelNums);
        eventNumRespVO.setSumTypes(sumTypes - sumLevels);
        eventNumRespVO.setSumLevels(sumLevels);
        return eventNumRespVO;
    }

    @Override
    public List<EventRespVO> getDropDownList(SimpleUser user, DropDownReq req) {
        EventReqPageVO pageVO = new EventReqPageVO();

        pageVO.setTargetDevice(req.getTargetDevice());
        List<Integer> stationIds = new ArrayList<>();
        stationIds.add(req.getStationId());
        pageVO.setStationIds(stationIds);
        //工单页面下拉告警只查询未确认的告警
        String currentStep = req.getCurrentStep();
        //节点名称为新建或者创建阶段时候，只查未确认告警
        if (currentStep == null || "".equals(currentStep) || WorkOrderConstant.TaskNodeName.node1.equals(currentStep)) {
            pageVO.setStatus(CommonConstant.ZERO);
        }
        pageVO.setLimitCount(100);
        pageVO.setLang(req.getLang());
        List<EventRespVO> eventRespVOS = eventList(pageVO);

        List<EventRespVO> list = new ArrayList<>(100);

        //根据时间倒序再次排列
        list = eventRespVOS.stream().sorted((s1, s2) -> {
            Date timeStamp = s1.getTimeStamp();
            Date timeStamp1 = s2.getTimeStamp();
            int count = (int) DateUtil.betweenDay(timeStamp, timeStamp1, true);
            return -count;
        }).collect(Collectors.toList());
        return list;
    }

    @Override
    public List<EventRespVO> dropDownBatchList(SimpleUser user, List<DropDownReq> list) {

        //创建返回值
        List<EventRespVO> eventRespVOList = new ArrayList<>();

        //遍历查询告警
        for (DropDownReq req : list) {
            List<EventRespVO> dropDownList = getDropDownList(user, req);
            eventRespVOList.addAll(dropDownList);
        }

        return eventRespVOList;
    }

    @Override
    public Event selectById(Long eventId) {
        Event event = eventMapper.selectByPrimaryKey(eventId);
        return event;
    }

    @Override
    public int eventNum(EventReqPageVO vo, SimpleUser user) {
        // 只统计未确认的告警
        int count = 0;
//        String key = RedisKeyConstant.EVENT_NUM + user.getUserId();
//        //若缓存中存在，则从缓存中去，设置1分钟有效
//        if (redisService.hasKey(key)) {
//            Object obj = redisService.get(key);
//            log.info("eventNum has key;key:{},obj:{}", key, obj);
//            if (null != obj) {
//                count = (Integer) obj;
//            } else {
//                count = eventMapper.selectCountStatusByInfo(vo);
//                redisService.set(key, count, 1, TimeUnit.MINUTES);
//            }
//        } else {
        count = eventMapper.selectCountStatusByInfo(vo);
//            redisService.set(key, count, 1, TimeUnit.MINUTES);
//        }
        return count;
    }

    @Override
    public Event selectByParams(Event event) {
        Event result = eventMapper.selectByParams(event.getStationId(), event.getTargetDevice(), event.getSignal(), null);
        return result;
    }

    @Value("${spring.activiti.flag}")
    private Integer activitiFlag;

    @Override
    public void accessPointEvent() {
        //当前时间
        Date date = new Date();
        //查询所有电站
        DataResult<List<Station>> result = businessFeignClient.selectStationSNAll();
        if (result.isSuccess()) {
            List<Station> stationList = result.getData();
            List<Event> events = new ArrayList<>();
            String name = null;
            if (!stationList.isEmpty()) {
                SendSmsConfigQueryReq vo = null;
                JSONObject jsonObject = null;
                for (Station station : stationList) {
//                    todo:测试专用
//                    if(station.getId()!=332){
//                        continue;
//                    }
                    List<String> snList = station.getSnList();
                    if (snList != null) {
                        int len = snList.size();
                        for (String sn : snList) {
                            //根据sn查询告警数据的时间排序后的最后一条
                            name = CommonConstant.STATION;
                            name = len > 1?(name+ StrUtil.BRACKET_START + sn + StrUtil.BRACKET_END):name;
                            Event event = eventMapper.selectByParams(null, null, sn, null);
                            //查询缓存中的心跳
                            String redisKey = RedisKeyConstant.HEARTBEAT + sn;
                            Boolean flag = redisService.hasKey(redisKey);
                            //如果缓存存在
                            if (flag) {
                                Map<Object, Object> map = redisService.hgetall(redisKey);
                                Date updateTime = (Date) map.get("updateTime");
                                //判断更新时间是否在五分钟之类
                                long between = DateUtil.between(updateTime, new Date(), DateUnit.MINUTE);
                                //超出五分钟则是当前接入点离线
                                if (between > minute) {
                                    //如果告警事件不存在,则产生告警数据
                                    vo = new SendSmsConfigQueryReq();
                                    vo.setStationId(station.getId());
                                    vo.setSmsType(CommonConstant.ONE);
                                    vo.setAlarmLevel(String.valueOf(CommonConstant.THREE));
                                    jsonObject = new JSONObject();
                                    jsonObject.put(CommonConstant.SMS.SITE_NAME, station.getName());
                                    jsonObject.put(CommonConstant.SMS.CONTENT, name + CommonConstant.Heartbeat.STATION_FAIL);
                                    vo.setParam(jsonObject);
                                    if (event == null) {
                                        Event snEvent = setEventAttr(updateTime, station, sn);
                                        //设置为告警数据
                                        snEvent.setIsRecovery(0);
                                        snEvent.setDescription(name + CommonConstant.Heartbeat.STATION_FAIL);
                                        TranslateName translate = getNameLanguage(snEvent.getDescription());
                                        snEvent.setDescriptionEn(translate.getNameEn());
                                        snEvent.setDescriptionFra(translate.getNameFra());
                                        snEvent.setDescriptionSpa(translate.getNameSpa());
                                        snEvent.setDescriptionDe(translate.getNameDe());
                                        snEvent.setDescriptionPl(translate.getNamePl());
                                        snEvent.setDescriptionAra(translate.getNameAra());
                                        events.add(snEvent);
                                        sendSmsConfigService.sendSms(vo);
                                    } else { //如果告警事件存在且该数据的告警已恢复,则产生告警数据
                                        if (CommonConstant.ONE.equals(event.getIsRecovery())) {
                                            Event snEvent = setEventAttr(updateTime, station, sn);
                                            //设置为告警数据
                                            snEvent.setIsRecovery(0);
                                            snEvent.setDescription(name + CommonConstant.Heartbeat.STATION_FAIL);
                                            TranslateName translate = getNameLanguage(snEvent.getDescription());
                                            snEvent.setDescriptionEn(translate.getNameEn());
                                            snEvent.setDescriptionFra(translate.getNameFra());
                                            snEvent.setDescriptionSpa(translate.getNameSpa());
                                            snEvent.setDescriptionDe(translate.getNameDe());
                                            snEvent.setDescriptionPl(translate.getNamePl());
                                            snEvent.setDescriptionAra(translate.getNameAra());
                                            events.add(snEvent);
                                            sendSmsConfigService.sendSms(vo);
                                        }
                                    }
                                    /** todo: 如果电站离线产生的告警则转工单 */
                                    MovementDTO movementDTO = new MovementDTO();
                                    movementDTO.setEvents(events);
                                    //告警自动转工单标识
                                    if (activitiFlag == 1) {
                                        monitor.setEvents(movementDTO);
                                    }
                                } else { //五分钟之类则是当前接入点离线恢复
                                    if (event != null) {
                                        if (CommonConstant.ZERO.equals(event.getIsRecovery())) {
                                            Event snEvent = setEventAttr(updateTime, station, sn);
                                            //设置为告警数据恢复
                                            snEvent.setIsRecovery(1);
                                            snEvent.setBeforeEventId(event.getId());
                                            //电站通道恢复默认自动确认
                                            snEvent.setStatus(CommonConstant.ONE);
                                            snEvent.setConfirmTime(new Date());
                                            snEvent.setConfirmMan(FlowConstant.DEFAULT_CONFIRM_MAN);
                                            snEvent.setDescription(name + CommonConstant.Heartbeat.STATION_FAIL + "恢复");
                                            TranslateName translate = getNameLanguage(snEvent.getDescription());
                                            snEvent.setDescriptionEn(translate.getNameEn());
                                            snEvent.setDescriptionFra(translate.getNameFra());
                                            snEvent.setDescriptionSpa(translate.getNameSpa());
                                            snEvent.setDescriptionDe(translate.getNameDe());
                                            snEvent.setDescriptionPl(translate.getNamePl());
                                            snEvent.setDescriptionAra(translate.getNameAra());
                                            events.add(snEvent);
                                            //确认前一条告警数据
                                            Event beforeEvent = new Event();
                                            beforeEvent.setId(event.getId());
                                            beforeEvent.setStatus(CommonConstant.ONE);
                                            beforeEvent.setConfirmMan(FlowConstant.DEFAULT_CONFIRM_MAN);
                                            beforeEvent.setConfirmTime(updateTime);
                                            eventMapper.updateByPrimaryKeySelective(beforeEvent);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
            //批量新增接入点告警数据
            if (!events.isEmpty()) {
                eventMapper.insertBatch(events);
            }
        }

    }

    /**
     * 判断外接电表状态（是否产生告警数据）定时任务
     */
    @Override
    public void outsideEleEvent() {
        //当前时间
        Date date = new Date();
        DataResult<List<DeviceRespVO>> result = businessFeignClient.selectDeviceByDeviceType(DeviceTypeConstant.OUTSIDE_ELE);
        if (result.isSuccess()) {
            List<DeviceRespVO> deviceList = result.getData();
            List<Event> events = new ArrayList<>();
            String redisKey = null;
            for (DeviceRespVO device : deviceList) {
                redisKey = device.getDeviceType() + ":" + device.getStationId() + ":" + device.getSrcId();
                Boolean flag = redisService.hasKey(redisKey);
                //如果缓存存在
                if (flag) {
                    Event event = eventMapper.selectByParams(device.getStationId(), device.getSrcId(), DeviceTypeConstant.OUTSIDE_ELE, null);
                    Map<Object, Object> map = redisService.hgetall(redisKey);
                    Date updateTime = (Date) map.get("updateTime");
                    //判断更新时间是否在二十五分钟之类
                    long between = DateUtil.between(updateTime, new Date(), DateUnit.MINUTE);
                    if (between > outSideMinute) {
                        //如果告警事件不存在,则产生告警数据
                        if (event == null) {
                            Event snEvent = setEventEleAttr(updateTime, device);
                            //设置为告警数据
                            snEvent.setIsRecovery(0);
                            events.add(snEvent);
                        } else { //如果告警事件存在且该数据的告警已恢复,则产生告警数据
                            if (CommonConstant.ONE.equals(event.getIsRecovery())) {
                                Event snEvent = setEventEleAttr(updateTime, device);
                                //设置为告警数据
                                snEvent.setIsRecovery(0);
                                events.add(snEvent);
                                //确认前一条告警数据
                                Event beforeEvent = new Event();
                                beforeEvent.setId(event.getId());
                                beforeEvent.setStatus(CommonConstant.ONE);
                                beforeEvent.setConfirmMan(FlowConstant.DEFAULT_CONFIRM_MAN);
                                beforeEvent.setConfirmTime(date);
                                eventMapper.updateByPrimaryKeySelective(beforeEvent);
                            }
                        }
                    } else { //外接电表离线恢复
                        if (event != null) {
                            if (CommonConstant.ZERO.equals(event.getIsRecovery())) {
                                Event snEvent = setEventEleAttr(updateTime, device);
                                //设置为告警数据恢复
                                snEvent.setIsRecovery(1);
                                snEvent.setBeforeEventId(event.getId());
                                snEvent.setStatus(CommonConstant.ONE);
                                snEvent.setConfirmMan(FlowConstant.DEFAULT_CONFIRM_MAN);
                                snEvent.setConfirmTime(updateTime);
                                snEvent.setDescription(CommonConstant.OutsideEle.SUCCESS);
                                TranslateName translate = getNameLanguage(snEvent.getDescription());
                                snEvent.setDescriptionEn(translate.getNameEn());
                                snEvent.setDescriptionFra(translate.getNameFra());
                                snEvent.setDescriptionSpa(translate.getNameSpa());
                                snEvent.setDescriptionDe(translate.getNameDe());
                                snEvent.setDescriptionPl(translate.getNamePl());
                                snEvent.setDescriptionAra(translate.getNameAra());
                                events.add(snEvent);
                                //确认前一条告警数据
                                Event beforeEvent = new Event();
                                beforeEvent.setId(event.getId());
                                beforeEvent.setStatus(CommonConstant.ONE);
                                beforeEvent.setConfirmMan(FlowConstant.DEFAULT_CONFIRM_MAN);
                                beforeEvent.setConfirmTime(updateTime);
                                eventMapper.updateByPrimaryKeySelective(beforeEvent);
                            }
                        }
                    }
                }

            }
            //批量新增接入点告警数据
            if (!events.isEmpty()) {
                eventMapper.insertBatch(events);
            }
        }
    }

    @Override
    public void regularlySendNotifications(MonitorQuery monitorQuery) {
        //当前时间
        Date date = new Date();
        Date startDate = DateUtils.addMinutes(date, -10);
        //查询所有电站
        DataResult<List<Station>> result = businessFeignClient.selectStationSNAll();
        if (result.isSuccess()) {
            List<Station> stationList = result.getData();
            List<Event> events = new ArrayList<>();
            if (!stationList.isEmpty()) {
                List<Integer> eventLevelList = new ArrayList<>();
                eventLevelList.add(CommonConstant.THREE);
                AlarmConfigQueryVo alarmConfigQueryVo = new AlarmConfigQueryVo();
                alarmConfigQueryVo.setSignal(FlowConstant.POLYMERIZATION);//合并后的告警
                alarmConfigQueryVo.setEventLevelList(eventLevelList);//高级等级为3
                alarmConfigQueryVo.setIsRecovery(CommonConstant.ZERO);//未恢复的
                //查询当前时间10分钟内的
                alarmConfigQueryVo.setStartTime(DateUtil.format(startDate, CommonConstant.DATE));
                alarmConfigQueryVo.setEndTime(DateUtil.format(date, CommonConstant.DATE));
                for (Station station : stationList) {
                    String key = RedisKeyConstant.STATION + station.getId();
                    alarmConfigQueryVo.setStationId(station.getId());
                    events = eventMapper.selectByTargetDevice(alarmConfigQueryVo);
                    if (!events.isEmpty()) {
                        Date sendSmsTime = null;
                        Station s = null;
                        if (redisService.hasKey(key)) {
                            s = (Station) redisService.get(key);
                            sendSmsTime = s.getSendSmsTime();
                        }
                        s = (s == null ? station : s);
                        if (null == sendSmsTime) {
                            sendSms(events, station);
                            //更新发送时间
                            s.setSendSmsTime(date);
                            redisService.set(key, s);
                            // 把告警数据放进队列
//                            MovementDTO movementDTO = new MovementDTO();
//                            movementDTO.setEvents(events);
//                            monitor.setEvents(movementDTO);
                        } else {
                            //告警条数大于采样间隔数目 或者 距离发送时间大于设定间时间间隔
                            if (events.size() > monitorQuery.getSampleNum() || DateUtil.between(date, sendSmsTime, DateUnit.MINUTE) - monitorQuery.getSampleTime() >= 0) {
                                sendSms(events, station);
                                //更新发送时间
                                s.setSendSmsTime(date);
                                redisService.set(key, s);
                                // 把告警数据放进队列
//                                MovementDTO movementDTO = new MovementDTO();
//                                movementDTO.setEvents(events);
//                                monitor.setEvents(movementDTO);
                            }
                        }
                    }
                }
            }
        }
    }

    /**
     * 根据告警发送短信
     *
     * @param events
     * @param station
     */
    private void sendSms(List<Event> events, Station station) {
        log.info("sendSms 电站：{}发生告警(等级为告警级别)短信", station.getName());
        SendSmsConfigQueryReq vo = null;
        JSONObject jsonObject = null;
        int len = events.size() > CommonConstant.THREE ? CommonConstant.THREE : events.size();
        StringBuffer str = new StringBuffer();
        for (int i = 0; i < len; i++) {
            str.append(events.get(i).getDescription()).append(",");
        }
        vo = new SendSmsConfigQueryReq();
        vo.setStationId(station.getId());
        vo.setSmsType(CommonConstant.ONE);
        vo.setAlarmLevel(String.valueOf(CommonConstant.THREE));
        jsonObject = new JSONObject();
        jsonObject.put(CommonConstant.SMS.SITE_NAME, station.getName());
        jsonObject.put(CommonConstant.SMS.CONTENT, str.toString().substring(0, str.length() - 1));
        vo.setParam(jsonObject);
        sendSmsConfigService.sendSms(vo);
    }

    @Autowired
    ProcessFlowService processFlowService;

    @Override
    public void conversion(EventWorkOrder eventWorkOrder) {
        //先通过id查询告警数据
        List<Event> events = eventMapper.selectByIds(eventWorkOrder.getEventIds());
        Map<Integer, List<Event>> stationMap = events.stream().collect(Collectors.groupingBy(Event::getStationId));
        if (stationMap.size() > 1) {
            throw new BusinessException(BaseResponseCode.ONLY_ONE_STATION);
        }
        //根据电站id对设备的srcId进行分组(k = 电站id,v = 设备srcId集合)
        Map<Integer, List<Integer>> map = events.stream().collect(Collectors.groupingBy(Event::getStationId, Collectors.mapping(Event::getTargetDevice, Collectors.toList())));
        //远程调用查询设备
        DataResult<List<DeviceRespVO>> result = businessFeignClient.selectDeviceByStationIdsAndSrcId(map);
        if (!result.isSuccess()) {
            throw new BusinessException(BaseResponseCode.CONVERSION_ERROR);
        }
        //修改选择的告警备注为已转工单
        eventMapper.setRemarkByIds(eventWorkOrder.getEventIds());
        List<DeviceRespVO> deviceRespVOS = result.getData();
        //电站id集合
        List<Integer> stationIds = map.keySet().stream().collect(Collectors.toList());
        //设备id集合
        List<Integer> deviceIds = deviceRespVOS.stream().map(DeviceRespVO::getId).collect(Collectors.toList());
        //告警id集合
        List<Long> eventIds = eventWorkOrder.getEventIds();
        //创建工单对象
        WorkOrderAddReqVO addReqVO = new WorkOrderAddReqVO();
        BeanUtils.copyProperties(eventWorkOrder, addReqVO);
        addReqVO.setStationIds(stationIds);
        addReqVO.setDeviceIds(deviceIds);
        addReqVO.setEventIds(eventIds);
        addReqVO.setOrderType(WorkOrderConstant.OrderType.troubleCheck);
        //创建工单
        String processInstanceId = processFlowService.saveOrderAndStartProcess(addReqVO);
        //流转工单
        DoTaskReq doTaskReq = new DoTaskReq();
        //设置租户id
        doTaskReq.setTenantId(String.valueOf(eventWorkOrder.getGroupId()));
        //设置发送者的id
        doTaskReq.setSenderId(eventWorkOrder.getUserId());
        //完成任务的责任人必须和自己相同,否则需要给出提示
        doTaskReq.setAssigneeUser(eventWorkOrder.getUserId());
        //设置候选人
        doTaskReq.setCandidateUserList(eventWorkOrder.getCandidateUserList());
        //设置流程id
        doTaskReq.setProcessInstId(processInstanceId);
        processFlowService.doCompleteTask(doTaskReq);

    }

    @Override
    public List<Event> selectByIds(List<Long> eventIds) {
        List<Event> events = eventMapper.selectByIds(eventIds);
        return events;
    }

    /**
     * 创建接入点的告警数据并赋值
     *
     * @param date
     * @param station
     * @param sn
     * @return
     */
    private Event setEventAttr(Date date, Station station, String sn) {
        Event snEvent = new Event();
        long id = snowflake.nextId();
        snEvent.setId(id);
        snEvent.setGroupId(station.getGroupId());
        snEvent.setStationId(station.getId());
        snEvent.setEventType(CommonConstant.EventType.alarm);
        snEvent.setEventLevel(CommonConstant.EventLevel.overLimit);
        //改为当前时间 2024-02-21 fan update
        snEvent.setTimeStamp(new Date());
        snEvent.setDeviceType(DeviceTypeConstant.ACCESSPOINT);
        snEvent.setTargetDevice(CommonConstant.ZERO);
        //接入点的信号值填写为sn
        snEvent.setSignal(sn);
        snEvent.setStatus(CommonConstant.STATUS);
        snEvent.setDescription(sn + CommonConstant.Heartbeat.SN_FAIL);
        TranslateName translate = getNameLanguage(snEvent.getDescription());
        snEvent.setDescriptionEn(translate.getNameEn());
        snEvent.setDescriptionFra(translate.getNameFra());
        snEvent.setDescriptionSpa(translate.getNameSpa());
        snEvent.setDescriptionDe(translate.getNameDe());
        snEvent.setDescriptionPl(translate.getNamePl());
        snEvent.setDescriptionAra(translate.getNameAra());
        snEvent.setConfirmStatus(CommonConstant.STATUS);
        snEvent.setCreateTime(date);
        return snEvent;
    }

    /**
     * 创建外接电表的告警数据并赋值
     *
     * @param date
     * @param device
     * @return
     */
    private Event setEventEleAttr(Date date, Device device) {
        Event snEvent = new Event();
        long id = snowflake.nextId();
        snEvent.setId(id);
        snEvent.setGroupId(device.getGroupId());
        snEvent.setStationId(device.getStationId());
        snEvent.setEventType(CommonConstant.EventType.alarm);
        snEvent.setEventLevel(CommonConstant.EventLevel.overLimit);
        snEvent.setTimeStamp(date);
        snEvent.setDeviceType(device.getDeviceType());
        snEvent.setTargetDevice(device.getSrcId());
        //接入点的信号值填写为sn
        snEvent.setSignal(DeviceTypeConstant.OUTSIDE_ELE);
        snEvent.setStatus(CommonConstant.STATUS);
        snEvent.setDescription(CommonConstant.OutsideEle.FAIL);
        TranslateName translate = getNameLanguage(snEvent.getDescription());
        snEvent.setDescriptionEn(translate.getNameEn());
        snEvent.setDescriptionFra(translate.getNameFra());
        snEvent.setDescriptionSpa(translate.getNameSpa());
        snEvent.setDescriptionDe(translate.getNameDe());
        snEvent.setDescriptionPl(translate.getNamePl());
        snEvent.setDescriptionAra(translate.getNameAra());
        snEvent.setConfirmStatus(CommonConstant.STATUS);
        snEvent.setCreateTime(date);
        return snEvent;
    }

    @Override
    public List<EventDemo> getFaultDuration(EventDemoReqVo vo) {
        List<EventDemo> demoList = new ArrayList<>();
        //根据电站id 和 开始结束时间进行查询
        AlarmConfigQueryVo alarmConfigQueryVo = new AlarmConfigQueryVo();
/*        alarmConfigQueryVo.setStartTime(vo.getBeginTime());
        alarmConfigQueryVo.setEndTime(vo.getEndTime());*/
        alarmConfigQueryVo.setDeviceType("accesspoint");
        alarmConfigQueryVo.setStationId(vo.getStationId());
        List<Event> events = eventMapper.selectByTargetDevice(alarmConfigQueryVo);
        Map<Long, List<Event>> list = events.stream().collect(Collectors.groupingBy(Event::getId));
        //拿到恢复的
        List<Event> recovered = new ArrayList<>();
        //拿到未恢复的
        List<Event> notRecovered = new ArrayList<>();
        if (CommonConstant.ONE.equals(events.size())) {
            for (Event event : events) {
                if (event.getBeforeEventId() != null) {
                    recovered.add(event);
                } else {
                    if (CommonConstant.ZERO.equals(event.getIsRecovery())) {
                        notRecovered.add(event);
                    }
                }
            }
        } else {
            for (Event event : events) {
                if (event.getBeforeEventId() != null) {
                    recovered.add(event);
                } else {
                    if (!list.containsKey(event.getId())) {
                        if (CommonConstant.ZERO.equals(event.getIsRecovery())) {
                            notRecovered.add(event);
                        }
                    }
                }
            }
        }

        //判断是否存在恢复的数据，对数据进行处理
        if (!CommonConstant.ZERO.equals(recovered.size())) {
            for (Event event : recovered) {
                EventDemo eventDemo = new EventDemo();
                boolean flag = list.containsKey(event.getBeforeEventId());
                if (flag) {
                    //等于1时，表示已经恢复
                    if (CommonConstant.ONE.equals(event.getIsRecovery())) {
                        List<Event> eventsValue = list.get(event.getBeforeEventId());
                        eventDemo.setId(event.getId());
                        eventDemo.setEndTime(DateUtil.formatDateTime(event.getTimeStamp()));
                        eventDemo.setBeginTime(DateUtil.formatDateTime(eventsValue.get(0).getTimeStamp()));
                        eventDemo.setStationId(event.getStationId());
                        demoList.add(eventDemo);
                    }
                } else {
                    Event event1 = eventMapper.selectByPrimaryKey(event.getBeforeEventId());
                    eventDemo.setId(event.getId());
                    eventDemo.setEndTime(DateUtil.formatDateTime(event.getTimeStamp()));
                    eventDemo.setBeginTime(DateUtil.formatDateTime(event1.getTimeStamp()));
                    eventDemo.setStationId(event.getStationId());
                    demoList.add(eventDemo);
                }
            }
        }
        //判断是否存在未恢复的数据，对数据进行处理
        if (!CommonConstant.ZERO.equals(notRecovered.size())) {
            //判断是否为最后未恢复数据（根据时间拿到最后一条数据）
            Event event = eventMapper.selectLastTime(alarmConfigQueryVo);
            //比较时间，拿到最早未恢复的数据
            Date end = event.getTimeStamp();
            EventDemo eventDemo = new EventDemo();
            for (Event event1 : notRecovered) {
                Date timeStamp = event1.getTimeStamp();
                boolean before = timeStamp.before(end);
                if (before) {
                    end = timeStamp;
                }
            }
            eventDemo.setId(event.getId());
            eventDemo.setEndTime(DateUtil.formatDateTime(new Date()));
            eventDemo.setBeginTime(DateUtil.formatDateTime(end));
            eventDemo.setStationId(event.getStationId());
            demoList.add(eventDemo);
        }
        return demoList;
    }

    @Override
    public List<EventDemo> getFaultDurations(EventDemoReqVo vo) {
        List<EventDemo> demoList = new ArrayList<>();
        //根据电站id 和 开始结束时间进行查询
        AlarmConfigQueryVo alarmConfigQueryVo = new AlarmConfigQueryVo();
        alarmConfigQueryVo.setStartTime(vo.getBeginTime());
        alarmConfigQueryVo.setEndTime(vo.getEndTime());
        alarmConfigQueryVo.setDeviceType("accesspoint");
        alarmConfigQueryVo.setStationId(vo.getStationId());
        //按照ts时间正序排序，减少循环次数
        List<Event> events = eventMapper.selectByTargetDeviceAsc(alarmConfigQueryVo);
        //拿到恢复的
        List<Event> recovered = new ArrayList<>();
        //拿到未恢复的
        List<Event> notRecovered = new ArrayList<>();
        for (Event event : events) {
            if (CommonConstant.ONE.equals(event.getIsRecovery())) {
                recovered.add(event);
            }
            if (CommonConstant.ZERO.equals(event.getIsRecovery())) {
                notRecovered.add(event);
            }
        }
        //将恢复的数据转换为Map集合,方便查找
        Map<Long, List<Event>> list = recovered.stream().collect(Collectors.groupingBy(Event::getBeforeEventId));
        //根据离线的去找恢复数据
        for (Event event : notRecovered) {
            boolean isRecovered = list.containsKey(event.getId());
            if (isRecovered) {
                List<Event> events1 = list.get(event.getId());
                EventDemo eventDemo = new EventDemo();
                eventDemo.setId(event.getId());
                eventDemo.setBeginTime(DateUtil.formatDateTime(event.getTimeStamp()));
                eventDemo.setEndTime(DateUtil.formatDateTime(events1.get(0).getTimeStamp()));
                eventDemo.setStationId(event.getStationId());
                demoList.add(eventDemo);
            } else {
                //根据故障找恢复
                Event event1 = eventMapper.selectByBeforeEventId(event.getId());
                EventDemo eventDemo = new EventDemo();
                eventDemo.setId(event.getId());
                eventDemo.setBeginTime(DateUtil.formatDateTime(event.getTimeStamp()));
                if (event1 != null) {
                    eventDemo.setEndTime(DateUtil.formatDateTime(event1.getTimeStamp()));
                } else {
                    eventDemo.setEndTime(vo.getEndTime());
                }
                eventDemo.setStationId(event.getStationId());
                demoList.add(eventDemo);
            }
        }
        //将恢复的数据转换为Map集合,方便查找
        Map<Long, List<Event>> notList = notRecovered.stream().collect(Collectors.groupingBy(Event::getId));
        for (Event event : recovered) {
            boolean isNotValue = notList.containsKey(event.getBeforeEventId());
            if (!isNotValue) {
                //根据恢复找故障
                Event event1 = eventMapper.selectByPrimaryKey(event.getBeforeEventId());
                EventDemo eventDemo = new EventDemo();
                eventDemo.setId(event.getId());
                eventDemo.setEndTime(DateUtil.formatDateTime(event.getTimeStamp()));
                eventDemo.setBeginTime(DateUtil.formatDateTime(event1.getTimeStamp()));
                eventDemo.setStationId(event.getStationId());
                demoList.add(eventDemo);
            }
        }
        return demoList;
    }

    @Override
    public List<EventDayNum> countEventByDay(EventReqPageVO vo) {
        List<EventDayNum> eventDayNums = eventMapper.countEventByDay(vo, null);
        return eventDayNums;
    }

    @Override
    public Map<String, Integer> eventDeviceNum(EventNumReq vo) {
        Map<String, Integer> result = new HashMap<>();
        //获取告警设备数量
        List<Integer> eventList = eventMapper.eventDeviceNum(vo);
        int eventDevice = eventList.size();
        //所有设备数
        DeviceReqVO deviceReqVO = new DeviceReqVO();
        deviceReqVO.setStationId(vo.getStationId());
        DataResult<List<Device>> deviceList = businessFeignClient.selectDeviceByStationIds(deviceReqVO);
        //真实设备
        Integer totalDevice = deviceList.getData().stream().filter(i->i.getDeviceType()!=null&&CommonConstant.THREE.equals(i.getCategory())&&CommonConstant.ZERO.equals(i.getVirtual())).collect(Collectors.toList()).size();
        Integer normalDevice = totalDevice-eventDevice;
        result.put("eventDevice",eventDevice);
        result.put("totalDevice",totalDevice);
        result.put("normalDevice",normalDevice);
        return result;
    }

    @Override
    public String getNameByLang(String name,String lang){
        TranslateName translate = getNameLanguage(name);
        switch (lang){
            case CommonConstant.langTemp.EN_US:
                return translate.getNameEn();
            case CommonConstant.langTemp.DE_DE:
                return translate.getNameDe();
            case CommonConstant.langTemp.ES_ES:
                return translate.getNameSpa();
            case CommonConstant.langTemp.AR_EG:
                return translate.getNameAra();
            case CommonConstant.langTemp.PL_PL:
                return translate.getNamePl();
            case CommonConstant.langTemp.FR_FR:
                return translate.getNameFra();
            case CommonConstant.langTemp.ZH_CN:
                return translate.getName();
        }
        return null;
    }


    @Override
    public TranslateName getNameLanguage(String name) {
        // 英语
        String nameEn = null;
        // 法语
        String nameFra = null;
        // 西班牙语
        String nameSpa = null;
        // 德语
        String nameDe = null;
        // 波兰语
        String namePl = null;
        // 阿拉伯语
        String nameAra = null;
        // 查询数据库中  预先翻译的中文字段 语言
        TranslateName vo = translateNameMapper.selectNameLang(name);
        TranslateName translate = new TranslateName();
        boolean flag = false;
        if(vo == null){
            nameEn = TranslateUtils.translate(name,CommonConstant.lang.EN);
            nameFra = TranslateUtils.translate(name,CommonConstant.lang.FRA);
            nameSpa = TranslateUtils.translate(name,CommonConstant.lang.SPA);
            nameDe = TranslateUtils.translate(name,CommonConstant.lang.DE);
            namePl = TranslateUtils.translate(name,CommonConstant.lang.PL);
            nameAra = TranslateUtils.translate(name,CommonConstant.lang.ARA);
            // 插入中文预翻译表
            translate.setName(name);
            translate.setNameEn(nameEn);
            translate.setNameFra(nameFra);
            translate.setNameSpa(nameSpa);
            translate.setNameDe(nameDe);
            translate.setNamePl(namePl);
            translate.setNameAra(nameAra);
            CompletableFuture.runAsync(()->{
                translateNameMapper.insert(translate);
            });
            return translate;
        }else{
            if(StringUtil.isEmpty(vo.getNameEn())){
                vo.setNameEn(TranslateUtils.translate(name,CommonConstant.lang.EN));
                flag = true;
            }
            if(StringUtil.isEmpty(vo.getNameFra())){
                vo.setNameFra(TranslateUtils.translate(name,CommonConstant.lang.FRA));
                flag = true;
            }
            if(StringUtil.isEmpty(vo.getNameSpa())){
                vo.setNameSpa(TranslateUtils.translate(name,CommonConstant.lang.SPA));
                flag = true;
            }
            if(StringUtil.isEmpty(vo.getNameDe())){
                vo.setNameDe(TranslateUtils.translate(name,CommonConstant.lang.DE));
                flag = true;
            }
            if(StringUtil.isEmpty(vo.getNamePl())){
                vo.setNamePl(TranslateUtils.translate(name,CommonConstant.lang.PL));
                flag = true;
            }
            if(StringUtil.isEmpty(vo.getNameAra())){
                vo.setNameAra(TranslateUtils.translate(name,CommonConstant.lang.ARA));
                flag = true;
            }
            if(flag){
                CompletableFuture.runAsync(()->{
                    translateNameMapper.updateById(vo);
                });
            }
        }
        return vo;
    }

}

