package com.ho.flow.controller;

import cn.hutool.core.date.DateUtil;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.ho.business.entity.Device;
import com.ho.business.entity.DeviceType;
import com.ho.business.entity.Station;
import com.ho.business.vo.req.EventColReq;
import com.ho.business.vo.req.device.DeviceListReq;
import com.ho.common.tools.annotation.LargeScreenToken;
import com.ho.common.tools.annotation.LogAnnotation;
import com.ho.common.tools.annotation.TokenIgnore;
import com.ho.common.tools.constant.CommonConstant;
import com.ho.common.tools.constant.ContextConstant;
import com.ho.common.tools.constant.DefineConstant;
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.flow.feignclient.BusinessFeignClient;
import com.ho.flow.service.EventService;
import com.ho.flow.vo.req.event.DropDownReq;
import com.ho.flow.vo.req.event.EventNumReq;
import com.ho.flow.vo.req.event.EventReqPageVO;
import com.ho.flow.vo.req.event.EventWorkOrder;
import com.ho.flow.vo.resp.event.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import jodd.util.StringUtil;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import javax.validation.constraints.NotEmpty;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description 警告管理
 * Author yule
 * Date 2022/8/26 16:58
 */
@RequestMapping(ContextConstant.FLOW_CONTEXT + "event")
@RestController
@Api(tags = "告警管理")
public class EventController {

    @Autowired
    private EventService eventService;

    @Autowired
    private RedisService redisService;

    @Autowired
    private BusinessFeignClient businessFeignClient;

    @Value("${event.currentMaxDay}")
    Integer currentMaxDay;

    @Value("${event.bigScreenEventLimit}")
    Integer bigScreenEventLimit;


    /*    @PostMapping("conversion")
        @ApiOperation(value = "转化工单接口")
        public DataResult conversion(@RequestBody List<Long> eventIds, HttpServletRequest request) {
            String token = request.getHeader(RedisKeyConstant.User.ACCESS_TOKEN);
            SimpleUser user = redisService.getSimpleUserByToken(token);
            eventService.conversionWorkOrder(eventIds, user);
            return DataResult.success();
        }*/
    @PostMapping("conversion")
    @ApiOperation(value = "转化工单接口")
    public DataResult conversion(@RequestBody @Valid EventWorkOrder eventWorkOrder, HttpServletRequest request) {
        String token = request.getHeader(RedisKeyConstant.User.ACCESS_TOKEN);
        SimpleUser simpleUser = redisService.getSimpleUserByToken(token);
        eventWorkOrder.setUserId(simpleUser.getUserId());
        eventWorkOrder.setGroupId(simpleUser.getGroupId());
        eventService.conversion(eventWorkOrder);
        return DataResult.success();
    }


    @PostMapping("page")
    @ApiOperation(value = "分页查询事件接口")
    //@LogAnnotation(title = "告警管理", action = "分页查询告警信息")
    public DataResult<PageResultMap<EventRespVO>> page(@RequestBody @Valid EventReqPageVO vo, HttpServletRequest
            request) {
        vo.setLang(request.getHeader(CommonConstant.LANG));
        //如果有srcIdList ,则根据这个查询deviceType
        List<Integer> srcIdList = vo.getSrcIdList();

        //这个不传的时候,说明没有选电站或设备,那么查全部就行
//        if(srcIdList!=null && !srcIdList.isEmpty()){
//            if(vo.getStationIds()!=null && !vo.getStationIds().isEmpty()){
//                Integer stationId = vo.getStationIds().get(0);
//                List<DeviceType> deviceTypes = getDeviceTypeByStationSrcIds(stationId, srcIdList);
//                vo.setDeviceTypeList(deviceTypes);
//            }
//        }

        if (srcIdList != null && !srcIdList.isEmpty()) {
            //虚拟设备
            List<Integer> virtualSrcIdList = srcIdList.stream().filter(i -> i < 0).collect(Collectors.toList());
            //实际设备
            List<Integer> realSrcIdList = srcIdList.stream().filter(i -> i >= 0).collect(Collectors.toList());
            vo.setSrcIdList(realSrcIdList);
            if (virtualSrcIdList.size() > 0) {
                DeviceListReq deviceListReq = new DeviceListReq();
                deviceListReq.setStationId(vo.getStationIds().get(0));
                deviceListReq.setSrcIdList(srcIdList);
                List<EventColReq> queryEventParamList = businessFeignClient.getQueryEventParam(deviceListReq);
                if (queryEventParamList.size() > 0) {
                    vo.setSrcIdList(null);
                    vo.setEventColReqList(queryEventParamList);
                }
            }
        }

        //仅查询近期数据(根据配置参数)
        //计算当前天数和 max之前的天数
        Date now = new Date();
        //开始时间,currentMaxDay之前的那天
        String beginTime = DateUtil.format(DateUtil.offsetDay(now, currentMaxDay), CommonConstant.DATE_YMD)
                + CommonConstant.START_SUFFIX_TIMESTAMP;
        //今天的23:59:59
        String endTime = DateUtil.format(DateUtil.endOfDay(now), CommonConstant.DATE);
/*        vo.setStartTime(beginTime);
        vo.setEndTime(endTime);*/
        DataResult<PageResultMap<EventRespVO>> result = DataResult.success();
        String token = request.getHeader(RedisKeyConstant.User.ACCESS_TOKEN);
        SimpleUser user = redisService.getSimpleUserByToken(token);

        //得到这个人的电站集合
        List<Integer> stationIds = user.getStationIds();
        if (vo.getStationIds() == null || vo.getStationIds().isEmpty()) {
            vo.setStationIds(stationIds);
        }
        // 当用户传入电站为空，且该用户所关联的电站全部为空的时候，直接返回
        if (vo.getStationIds() == null || vo.getStationIds().isEmpty()) {
            PageResultMap<EventRespVO> pageResultMap = new PageResultMap<>();
            pageResultMap.setList(new ArrayList<EventRespVO>());
            Map<Integer, Integer> map = new HashMap<>();
            pageResultMap.setEventLevels(map);
            pageResultMap.setEventTypes(map);
            result.setData(pageResultMap);
            return result;
        }
        vo.setUserLevel(user.getUserLevel());
        //获取EventRespVO对象
        PageResult<EventRespVO> list = new PageResult<>();
        if (!(vo.getEventLevels().isEmpty() && vo.getEventTypes().isEmpty())) {
            /**************实时告警中不能出现已确认的数据********************/
            vo.setStatus(CommonConstant.ZERO);
            list = eventService.pageEventInfo(vo);
        }
        //获取告警等级和告警级别分别的数量
        EventNumRespVO eventNumRespVO = eventService.selectNum(vo, user);
        List<EventLevelNum> levelNums = eventNumRespVO.getLevelNums();
        Map<Integer, Integer> eventLevels = levelNums.stream().collect(Collectors.toMap(EventLevelNum::getEventLevel, EventLevelNum::getCount));
        //设置事件等级总数
        eventLevels.put(-1, eventNumRespVO.getSumLevels());
        List<EventTypeNum> typeNums = eventNumRespVO.getTypeNums();
        Map<Integer, Integer> eventTypes = typeNums.stream().collect(Collectors.toMap(EventTypeNum::getEventType, EventTypeNum::getCount));

        //设置事件类型总数
        eventTypes.put(-1, eventNumRespVO.getSumTypes());
        //给返回值赋值
        PageResultMap<EventRespVO> map = new PageResultMap<>();
        BeanUtils.copyProperties(list, map);
        if (!eventTypes.isEmpty()) {
            map.setEventTypes(eventTypes);
        }
        if (!eventLevels.isEmpty()) {
            map.setEventLevels(eventLevels);
        }
        result.setData(map);
        return result;
    }

    //根据srcIdList查对应设备类型
    private List<DeviceType> getDeviceTypeByStationSrcIds(Integer stationId, List<Integer> srcIdList) {
        if (srcIdList == null || srcIdList.isEmpty()) {
            return new ArrayList<>();
        }
        List<DeviceType> deviceTypeList = new ArrayList<>();
        DeviceListReq deviceListReq = new DeviceListReq();
        deviceListReq.setStationId(stationId);
        deviceListReq.setSrcIdList(srcIdList);
        //远程调用查询设备
        DataResult<List<Device>> result = businessFeignClient.selectDeviceByStationIdsAndSrcIdVirtual(deviceListReq);
        if (result.isSuccess()) {
            List<Device> data = result.getData();
            if (data != null && !data.isEmpty()) {
                for (Device datum : data) {
                    if (datum.getDeviceType() != null) {
                        DeviceType deviceType = new DeviceType();
                        deviceType.setDeviceType(datum.getDeviceType());
                        deviceTypeList.add(deviceType);
                    }
                }
            }
            return deviceTypeList;
        }
        return new ArrayList<>();
    }

    @PostMapping("hispage")
    @ApiOperation(value = "分页查询事件历史接口")
    //@LogAnnotation(title = "告警管理", action = "分页查询告警历史信息")
    public DataResult<PageResultMap<EventRespVO>> hispage(@RequestBody @Valid EventReqPageVO vo, HttpServletRequest
            request) {
        vo.setLang(request.getHeader(CommonConstant.LANG));
        DataResult<PageResultMap<EventRespVO>> result = DataResult.success();
        String token = request.getHeader(RedisKeyConstant.User.ACCESS_TOKEN);
        SimpleUser user = redisService.getSimpleUserByToken(token);
        //如果有srcIdList ,则根据这个查询deviceType
        List<Integer> srcIdList = vo.getSrcIdList();

        //这个不传的时候,说明没有选电站或设备,那么查全部就行
//        if (srcIdList != null && !srcIdList.isEmpty()) {
//            if (vo.getStationIds() != null && !vo.getStationIds().isEmpty()) {
//                Integer stationId = vo.getStationIds().get(0);
//                List<DeviceType> deviceTypes = getDeviceTypeByStationSrcIds(stationId, srcIdList);
//                vo.setDeviceTypeList(deviceTypes);
//            }
//        }
        if (srcIdList != null && !srcIdList.isEmpty()) {
            //虚拟设备
            List<Integer> virtualSrcIdList = srcIdList.stream().filter(i -> i < 0).collect(Collectors.toList());
            //实际设备
            List<Integer> realSrcIdList = srcIdList.stream().filter(i -> i >= 0).collect(Collectors.toList());
            vo.setSrcIdList(realSrcIdList);
            if (virtualSrcIdList.size() > 0) {
                DeviceListReq deviceListReq = new DeviceListReq();
                deviceListReq.setStationId(vo.getStationIds().get(0));
                deviceListReq.setSrcIdList(srcIdList);
                List<EventColReq> queryEventParamList = businessFeignClient.getQueryEventParam(deviceListReq);
                if (queryEventParamList.size() > 0) {
                    vo.setSrcIdList(null);
                    vo.setEventColReqList(queryEventParamList);
                }
            }
        }
        //得到这个人的电站集合
        List<Integer> stationIds = user.getStationIds();
        //这个人没有电站就返回空集合
        if (stationIds == null || stationIds.isEmpty()) {
            PageResultMap<EventRespVO> pageResultMap = new PageResultMap<>();
            pageResultMap.setList(new ArrayList<EventRespVO>());
            Map<Integer, Integer> map = new HashMap<>();
            pageResultMap.setEventLevels(map);
            pageResultMap.setEventTypes(map);
            result.setData(pageResultMap);
            return result;
        }
        if (vo.getStationIds() == null || vo.getStationIds().isEmpty()) {
            vo.setStationIds(stationIds);
        }
        //获取EventRespVO对象
        //2023-01-10 告警数据都从实时表中查询,
        //PageResult<EventRespVO> list = eventHisService.selectByInfo(vo,user);
        //给开始时间和结束时间加后缀
        if (vo.getStartTime() != null) {
            vo.setStartTime(vo.getStartTime() + CommonConstant.START_SUFFIX_TIMESTAMP);
        }
        if (vo.getEndTime() != null) {
            vo.setEndTime(vo.getEndTime() + CommonConstant.END_SUFFIX_TIMESTAMP);
        }
        PageResult<EventRespVO> list = new PageResult<>();
        vo.setUserLevel(user.getUserLevel());
        if (!(vo.getEventLevels().isEmpty() && vo.getEventTypes().isEmpty())) {
            /**************实时告警中不能出现已确认的数据********************/
            vo.setStatus(CommonConstant.ONE);
            list = eventService.pageEventInfo(vo);
        }
        //获取告警等级和告警级别分别的数量
        //EventNumRespVO eventNumRespVO = eventHisService.selectNum(vo,user);
        EventNumRespVO eventNumRespVO = eventService.selectNum(vo, user);
        List<EventLevelNum> levelNums = eventNumRespVO.getLevelNums();
        Map<Integer, Integer> eventLevels = levelNums.stream().collect(Collectors.toMap(EventLevelNum::getEventLevel, EventLevelNum::getCount));
        //设置事件等级总数
        eventLevels.put(-1, eventNumRespVO.getSumLevels());
        List<EventTypeNum> typeNums = eventNumRespVO.getTypeNums();
        Map<Integer, Integer> eventTypes = typeNums.stream().collect(Collectors.toMap(EventTypeNum::getEventType, EventTypeNum::getCount));

        //设置事件类型总数
        eventTypes.put(-1, eventNumRespVO.getSumTypes());
        //给返回值赋值
        PageResultMap<EventRespVO> map = new PageResultMap<>();
        BeanUtils.copyProperties(list, map);
        if (!eventTypes.isEmpty()) {
            map.setEventTypes(eventTypes);
        }
        if (!eventLevels.isEmpty()) {
            map.setEventLevels(eventLevels);
        }
        result.setData(map);
        return result;
    }

    /**
     * 过时接口,已被分页查询接口合并
     *
     * @return
     */
/*    @PostMapping("num")
    @ApiOperation(value = "查询告警等级数量接口")
    @LogAnnotation(title = "告警管理",action = "查询告警等级数量接口")
    public DataResult<EventNumRespVO> getNum(@RequestBody EventReqPageVO vo){
        DataResult<EventNumRespVO> result = DataResult.success();

        result.setData(eventNumRespVO);
        return result;
    }*/
    @PutMapping("confirm")
    @ApiOperation(value = "告警清除接口")
    @LogAnnotation(title = "告警管理", action = "告警清除信息")
    //@HzPermission(PermissionConstant.EVENT_REALTIMEALARM_ALARMCLEARING)
    public DataResult confirm
    (@RequestBody @NotEmpty(message = "请先选择需要清除的数据") @Valid List<Long> ids, HttpServletRequest request) {
        DataResult result = DataResult.success();
        if (ids.isEmpty()) {
            throw new BusinessException(BaseResponseCode.EVENT_IDS_NOT_EMPTY);
        }
        String token = request.getHeader(RedisKeyConstant.User.ACCESS_TOKEN);
        UserDetailRespVO userDetail = redisService.getUserDetailByToken(token);
        eventService.updateById(ids, userDetail);
        return result;
    }

    @PostMapping("/eventList")
    @ApiOperation(value = "查询事件接口(大屏专用 ,不分页)")
    @TokenIgnore
    @LargeScreenToken
    public DataResult<EventBigScreenResp> eventList(HttpServletRequest request) {
        EventBigScreenResp eventBigScreenResp = new EventBigScreenResp();
        //仅查询近期数据(根据配置参数)
        //计算当前天数和 max之前的天数
        Date now = new Date();
        //开始时间,currentMaxDay之前的那天
        String beginTime = DateUtil.format(DateUtil.offsetDay(now, currentMaxDay), CommonConstant.DATE_YMD)
                + CommonConstant.START_SUFFIX_TIMESTAMP;
        EventReqPageVO vo = new EventReqPageVO();
        //今天的23:59:59
        String endTime = DateUtil.format(DateUtil.endOfDay(now), CommonConstant.DATE);
        vo.setStartTime(beginTime);
        vo.setEndTime(endTime);
        String token = request.getHeader(RedisKeyConstant.User.ACCESS_TOKEN);
        SimpleUser user = redisService.getSimpleUserByBigScreenToken(token);
        //得到这个人的电站集合
        DataResult<List<Station>> result = businessFeignClient.selectByGroupId(user.getGroupId());
        List<Station> stations = result.getData();
        //如果电站为空就应该为告警事件
        if (stations.isEmpty()) {
            eventBigScreenResp.setAlarmNum(0);
            eventBigScreenResp.setConfirmNum(0);
            eventBigScreenResp.setEventRespVOS(new ArrayList<>());
            return DataResult.success(eventBigScreenResp);
        }
        List<Integer> stationIds = stations.stream().map(s -> {
                    return s.getId();
                }
        ).collect(Collectors.toList());
        if (vo.getStationIds() == null || vo.getStationIds().isEmpty()) {
            vo.setStationIds(stationIds);
        }
        //限制最大条数, 防止数据过大
        vo.setLimitCount(bigScreenEventLimit);
        //查询告警数据
        List<EventRespVO> eventRespVOS = eventService.eventList(vo);
        //告警次数
        Integer alarmNum = 0;
        //确认次数
        Integer confirmNum = 0;
        //累加告警次数和确认次数
        for (EventRespVO event : eventRespVOS) {
            if (CommonConstant.EventType.alarm.equals(event.getEventType())) {
                alarmNum++;
            }
            if (CommonConstant.ONE.equals(event.getStatus())) {
                confirmNum++;
            }
        }

        eventBigScreenResp.setEventRespVOS(eventRespVOS);
        eventBigScreenResp.setAlarmNum(alarmNum);
        eventBigScreenResp.setConfirmNum(confirmNum);
        return DataResult.success(eventBigScreenResp);
    }

    @PostMapping("/dropDownList")
    @ApiOperation(value = "下拉列表告警数据")
    public DataResult<List<EventRespVO>> dropDownList(@RequestBody @Valid DropDownReq req, HttpServletRequest
            request) {
        String token = request.getHeader(RedisKeyConstant.User.ACCESS_TOKEN);
        SimpleUser user = redisService.getSimpleUserByToken(token);
        List<EventRespVO> list = eventService.getDropDownList(user, req);
        return DataResult.success(list);
    }

    @PostMapping("/dropDownBatchList")
    @ApiOperation(value = "批量下拉列表告警数据")
    public DataResult<List<EventRespVO>> dropDownBatchList(@RequestBody @Valid List<DropDownReq> list, HttpServletRequest
            request) {
        String token = request.getHeader(RedisKeyConstant.User.ACCESS_TOKEN);
        SimpleUser user = redisService.getSimpleUserByToken(token);
        String lang = request.getHeader(CommonConstant.LANG);
        list.stream().forEach(s->{
            s.setLang(lang);
        });
        List<EventRespVO> eventRespVOList = eventService.dropDownBatchList(user, list);
        return DataResult.success(eventRespVOList);
    }

    @PostMapping("eventNum")
    @ApiOperation(value = "告警数目（给页面头部那个告警铃铛调用）")
    public DataResult eventNum(@RequestBody EventNumReq eventNumReq, HttpServletRequest request) {
        DataResult result = DataResult.success();
        //仅查询近期数据(根据配置参数)
        //计算当前天数和 max之前的天数
        Date now = new Date();
        //开始时间,currentMaxDay之前的那天
        String beginTime = DateUtil.format(DateUtil.offsetDay(now, currentMaxDay), CommonConstant.DATE_YMD)
                + CommonConstant.START_SUFFIX_TIMESTAMP;
        //今天的23:59:59
        String endTime = DateUtil.format(DateUtil.endOfDay(now), CommonConstant.DATE);
        EventReqPageVO vo = new EventReqPageVO();
/*        vo.setStartTime(beginTime);
        vo.setEndTime(endTime);*/
        String token = request.getHeader(RedisKeyConstant.User.ACCESS_TOKEN);
        SimpleUser user = redisService.getSimpleUserByToken(token);
        Integer stationId = eventNumReq.getStationId();
        if (null != stationId) {
            List<Integer> stationIds = new ArrayList<>();
            stationIds.add(stationId);
            vo.setStationIds(stationIds);
        }
        //得到这个人的电站集合
        List<Integer> stationIds = user.getStationIds();
        if (vo.getStationIds() == null || vo.getStationIds().isEmpty()) {
            vo.setStationIds(stationIds);
        }
        // 当用户传入电站为空，且该用户所关联的电站全部为空的时候，直接返回
        if (vo.getStationIds() == null || vo.getStationIds().isEmpty()) {
            return result;
        }
        //默认统计是事故和异常和告警
        List<Integer> levelList = new ArrayList<>();
        levelList.add(CommonConstant.ONE);
        levelList.add(CommonConstant.TWO);
        levelList.add(CommonConstant.THREE);
        vo.setUserLevel(user.getUserLevel());
        vo.setEventLevels(levelList);
        //获取EventRespVO对象
        int num = eventService.eventNum(vo, user);
        result.setData(num);
        return result;
    }

    @PostMapping("/realTimeAlarm")
    @ApiOperation(value = "查询事件接口(12-14新大屏)")
    @TokenIgnore
    public DataResult<List<EventRespVO>> getRealTimeAlarm(HttpServletRequest request) {
        //得到这个人的电站集合
        DataResult<List<Station>> result = businessFeignClient.selectStationSNAll();
        List<Station> stations = result.getData();
        //如果电站为空就应该为告警事件
        if (stations.isEmpty()) {
            return DataResult.success(new ArrayList<>());
        }
        List<Station> list = new ArrayList<>();
        stations.stream().filter(i -> CommonConstant.ONE.equals(i.getStatus())).forEach(s -> list.add(s));
        List<Integer> stationIds = list.stream().map(s -> {
                    return s.getId();
                }
        ).collect(Collectors.toList());

        EventReqPageVO vo = new EventReqPageVO();
        if (vo.getStationIds() == null || vo.getStationIds().isEmpty()) {
            vo.setStationIds(stationIds);
        }
        //查询告警数据
        vo.setStatus(CommonConstant.ZERO);
        List<EventRespVO> eventRespVOS = eventService.eventList(vo);
        //根据告警产生时间倒叙
        eventRespVOS.stream().sorted(Comparator.comparing(EventRespVO::getTimeStamp).reversed()).limit(30).collect(Collectors.toList());
        Map<Integer, String> stationStatusMap = stations.stream()
                .collect(Collectors.toMap(Station::getId, Station::getName));
        for (EventRespVO eventRespVO : eventRespVOS) {
            if (stationStatusMap.containsKey(eventRespVO.getStationId())) {
                eventRespVO.setStationName(stationStatusMap.get(eventRespVO.getStationId()));
            }
        }
        return DataResult.success(eventRespVOS);
    }


    //告警数据导出
    //历史告警数据导出


    /**
     * 告警数据导出
     *
     * @param response
     */
    @PostMapping("/exportEvnData")
    @ApiOperation(value = "导出实时告警数据")
    public void exportEvnData(@RequestBody @Valid EventReqPageVO vo, HttpServletRequest request, HttpServletResponse response) {
        vo.setLang(request.getHeader(CommonConstant.LANG));
        //如果有srcIdList ,则根据这个查询deviceType
        List<Integer> srcIdList = vo.getSrcIdList();
        if (srcIdList != null && !srcIdList.isEmpty()) {
            //虚拟设备
            List<Integer> virtualSrcIdList = srcIdList.stream().filter(i -> i < 0).collect(Collectors.toList());
            //实际设备
            List<Integer> realSrcIdList = srcIdList.stream().filter(i -> i >= 0).collect(Collectors.toList());
            vo.setSrcIdList(realSrcIdList);
            if (virtualSrcIdList.size() > 0) {
                DeviceListReq deviceListReq = new DeviceListReq();
                deviceListReq.setStationId(vo.getStationIds().get(0));
                deviceListReq.setSrcIdList(srcIdList);
                List<EventColReq> queryEventParamList = businessFeignClient.getQueryEventParam(deviceListReq);
                if (queryEventParamList.size() > 0) {
                    vo.setSrcIdList(null);
                    vo.setEventColReqList(queryEventParamList);
                }
            }
        }
        //仅查询近期数据(根据配置参数)
        //计算当前天数和 max之前的天数
        Date now = new Date();
        //开始时间,currentMaxDay之前的那天
        String beginTime = DateUtil.format(DateUtil.offsetDay(now, currentMaxDay), CommonConstant.DATE_YMD)
                + CommonConstant.START_SUFFIX_TIMESTAMP;
        //今天的23:59:59
        String endTime = DateUtil.format(DateUtil.endOfDay(now), CommonConstant.DATE);
        vo.setStartTime(beginTime);
        vo.setEndTime(endTime);
        DataResult<PageResultMap<EventRespVO>> result = DataResult.success();
        String token = request.getHeader(RedisKeyConstant.User.ACCESS_TOKEN);
        SimpleUser user = redisService.getSimpleUserByToken(token);

        //得到这个人的电站集合
        List<Integer> stationIds = user.getStationIds();
        if (vo.getStationIds() == null || vo.getStationIds().isEmpty()) {
            vo.setStationIds(stationIds);
        }
        // 当用户传入电站为空，且该用户所关联的电站全部为空的时候，直接返回
        if (vo.getStationIds() == null || vo.getStationIds().isEmpty()) {
            throw new BusinessException(BaseResponseCode.STATION_DATA_NULL_IMPORT_ERROR);
            //电站为空，导出异常
        }
        vo.setUserLevel(user.getUserLevel());
        //获取EventRespVO对象
        List<EventRespVO> list = new ArrayList<>();
        if (!(vo.getEventLevels().isEmpty() && vo.getEventTypes().isEmpty())) {
            list = eventService.eventInfo(vo);
        }
        List<ExportEvnData> resultList = replaceList(list);
        //在内存操作，写到浏览器
        ExcelWriter writer = ExcelUtil.getWriter(true);
        //自定义标题别名
        writer.addHeaderAlias("stationName", DefineConstant.Event.STATION_NAME);
        writer.addHeaderAlias("deviceName", DefineConstant.Event.DEVICE_TYPE);
        writer.addHeaderAlias("name", DefineConstant.Event.DEVICE_NAME);
        writer.addHeaderAlias("status",  DefineConstant.Event.STATUS);
        writer.addHeaderAlias("eventLevel", DefineConstant.Event.EVENT_LEVEL);
        writer.addHeaderAlias("timeStamp", DefineConstant.Event.TIME_STAMP);
        writer.addHeaderAlias("description", DefineConstant.Event.DESCRIPTION);
        writer.addHeaderAlias("confirmMan", DefineConstant.Event.CONFIRM_MAN);
        writer.addHeaderAlias("confirmTime", DefineConstant.Event.CONFIRM_TIME);
        writer.addHeaderAlias("remark", DefineConstant.Event.REMARK);
        //默认配置
        writer.write(resultList, true);
        //自适应宽度
        widthUtils(writer.getSheet(), 10);
        //设置content—type
        response.setContentType("application/vnd.ms-excel");
        response.setCharacterEncoding("utf-8");
        response.addHeader("Access-Control-Expose-Headers", "Content-disposition");
        response.setHeader("Pragma", "No-cache");
        response.setHeader("Cache-Control", "no-cache");
        response.setDateHeader("Expires", 0);
        ServletOutputStream outputStream = null;
        try {
            String fileName = "实时告警数据.xlsx";
            response.setHeader("Content-disposition", "attachment;filename=" + fileName);
            outputStream = response.getOutputStream();
            //将Writer刷新到OutPut
            writer.flush(outputStream, true);
        } catch (UnsupportedEncodingException e) {
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (outputStream != null) {
                try {
                    outputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            writer.close();
        }
    }

    /**
     * 历史告警数据导出
     *
     * @param response
     */
    @PostMapping("/exportHisEvnData")
    @ApiOperation(value = "历史告警数据导出")
    public void exportHisEvnData(@RequestBody @Valid EventReqPageVO vo, HttpServletRequest request, HttpServletResponse response) {
        String token = request.getHeader(RedisKeyConstant.User.ACCESS_TOKEN);
        SimpleUser user = redisService.getSimpleUserByToken(token);
        //如果有srcIdList ,则根据这个查询deviceType
        List<Integer> srcIdList = vo.getSrcIdList();
        if (srcIdList != null && !srcIdList.isEmpty()) {
            //虚拟设备
            List<Integer> virtualSrcIdList = srcIdList.stream().filter(i -> i < 0).collect(Collectors.toList());
            //实际设备
            List<Integer> realSrcIdList = srcIdList.stream().filter(i -> i >= 0).collect(Collectors.toList());
            vo.setSrcIdList(realSrcIdList);
            if (virtualSrcIdList.size() > 0) {
                DeviceListReq deviceListReq = new DeviceListReq();
                deviceListReq.setStationId(vo.getStationIds().get(0));
                deviceListReq.setSrcIdList(srcIdList);
                List<EventColReq> queryEventParamList = businessFeignClient.getQueryEventParam(deviceListReq);
                if (queryEventParamList.size() > 0) {
                    vo.setSrcIdList(null);
                    vo.setEventColReqList(queryEventParamList);
                }
            }
        }
        //得到这个人的电站集合
        List<Integer> stationIds = user.getStationIds();
        //这个人没有电站就返回空集合
        if (stationIds == null || stationIds.isEmpty()) {
            throw new BusinessException(BaseResponseCode.STATION_DATA_NULL_IMPORT_ERROR);
            //电站为空，导出异常
        }
        if (vo.getStationIds() == null || vo.getStationIds().isEmpty()) {
            vo.setStationIds(stationIds);
        }
        if (vo.getStartTime() != null) {
            vo.setStartTime(vo.getStartTime() + CommonConstant.START_SUFFIX_TIMESTAMP);
        }
        if (vo.getEndTime() != null) {
            vo.setEndTime(vo.getEndTime() + CommonConstant.END_SUFFIX_TIMESTAMP);
        }
        List<EventRespVO> list = new ArrayList<>();
        vo.setUserLevel(user.getUserLevel());
        if (!(vo.getEventLevels().isEmpty() && vo.getEventTypes().isEmpty())) {
            list = eventService.eventInfo(vo);
        }
        List<ExportEvnData> resultList = replaceList(list);
        String fileName = "历史告警数据.xlsx";
        //在内存操作，写到浏览器
        ExcelWriter writer = ExcelUtil.getWriter(true);
        //自定义标题别名
        writer.addHeaderAlias("stationName", DefineConstant.Event.STATION_NAME);
        writer.addHeaderAlias("deviceName", DefineConstant.Event.DEVICE_TYPE);
        writer.addHeaderAlias("name", DefineConstant.Event.DEVICE_NAME);
        writer.addHeaderAlias("status",  DefineConstant.Event.STATUS);
        writer.addHeaderAlias("eventLevel", DefineConstant.Event.EVENT_LEVEL);
        writer.addHeaderAlias("timeStamp", DefineConstant.Event.TIME_STAMP);
        writer.addHeaderAlias("description", DefineConstant.Event.DESCRIPTION);
        writer.addHeaderAlias("confirmMan", DefineConstant.Event.CONFIRM_MAN);
        writer.addHeaderAlias("confirmTime", DefineConstant.Event.CONFIRM_TIME);
        writer.addHeaderAlias("remark", DefineConstant.Event.REMARK);
        //默认配置
        writer.write(resultList, true);
        //自适应宽度
        widthUtils(writer.getSheet(), 10);
        //设置content—type
        response.setContentType("application/vnd.ms-excel");
        response.setCharacterEncoding("utf-8");
        response.addHeader("Access-Control-Expose-Headers", "Content-disposition");
        response.setHeader("Pragma", "No-cache");
        response.setHeader("Cache-Control", "no-cache");
        response.setDateHeader("Expires", 0);
        ServletOutputStream outputStream = null;
        try {
            response.setHeader("Content-disposition", "attachment;filename=" + fileName);
            outputStream = response.getOutputStream();
            //将Writer刷新到OutPut
            writer.flush(outputStream, true);
        } catch (UnsupportedEncodingException e) {
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (outputStream != null) {
                try {
                    outputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            writer.close();
        }
    }

    public List<ExportEvnData> replaceList(List<EventRespVO> list) {
        List<ExportEvnData> resultList = new ArrayList<>();
        for (EventRespVO eventRespVO : list) {
            ExportEvnData exportEvnData = new ExportEvnData();
            exportEvnData.setStationName(eventRespVO.getStationName());
            exportEvnData.setDeviceName(eventRespVO.getDeviceName());
            exportEvnData.setName(eventRespVO.getName());
            if (eventRespVO.getStatus() != null) {
                if (CommonConstant.ONE.equals(eventRespVO.getStatus())) {
                    exportEvnData.setStatus(DefineConstant.Event.CONFIRMED);
                } else if (CommonConstant.ZERO.equals(eventRespVO.getStatus())) {
                    exportEvnData.setStatus(DefineConstant.Event.UNCONFIRMED);
                }
            }
            //一级（事故）2二级（故障）3三级（告警）4四级（提示）5;//五级（告知）")
            if (eventRespVO.getEventLevel() != null) {
                if (CommonConstant.ONE.equals(eventRespVO.getEventLevel())) {
                    exportEvnData.setEventLevel(DefineConstant.Event.ACCIDENT);
                } else if (CommonConstant.TWO.equals(eventRespVO.getEventLevel())) {
                    exportEvnData.setEventLevel(DefineConstant.Event.FAULT);
                } else if (CommonConstant.THREE.equals(eventRespVO.getEventLevel())) {
                    exportEvnData.setEventLevel(DefineConstant.Event.ALARM);
                } else if (CommonConstant.FOUR.equals(eventRespVO.getEventLevel())) {
                    exportEvnData.setEventLevel(DefineConstant.Event.PROMPT);
                } else if (CommonConstant.FIVE.equals(eventRespVO.getEventLevel())) {
                    exportEvnData.setEventLevel(DefineConstant.Event.INFORM);
                }
            }
            exportEvnData.setTimeStamp(eventRespVO.getTimeStamp());
            exportEvnData.setDescription(eventRespVO.getDescription());
            exportEvnData.setConfirmMan(eventRespVO.getConfirmMan());
            exportEvnData.setConfirmTime(eventRespVO.getConfirmTime());
            exportEvnData.setRemark(eventRespVO.getRemark());
            exportEvnData.setName(eventRespVO.getName());
            exportEvnData.setName(eventRespVO.getName());
            resultList.add(exportEvnData);
        }
        return resultList;
    }

    public void widthUtils(Sheet sheet, int size) {
        for (int columnNum = 0; columnNum <= size; columnNum++) {
            int columnWidth = sheet.getColumnWidth(columnNum) / 256;
            for (int rowNum = 0; rowNum <= sheet.getLastRowNum(); rowNum++) {
                Row currentRow;
                //当前行未被使用过
                if (sheet.getRow(rowNum) == null) {
                    currentRow = sheet.createRow(rowNum);
                } else {
                    currentRow = sheet.getRow(rowNum);
                }

                if (currentRow.getCell(columnNum) != null) {
                    Cell currentCell = currentRow.getCell(columnNum);
                    if (currentCell.getCellType() == CellType.STRING) {
                        int length = currentCell.getStringCellValue().getBytes().length + 5;
                        if (columnWidth < length) {
                            columnWidth = length;
                        }
                    }
                }
            }
            sheet.setColumnWidth(columnNum, columnWidth * 256 + 5);
        }
    }

    /**
     * 告警设备统计
     *
     * @param
     */
    @PostMapping("/eventDeviceNum")
    @ApiOperation(value = "告警设备统计")
    public DataResult eventDeviceNum(@RequestBody @Valid EventNumReq vo) {
        Map<String,Integer> result = new HashMap<>();
        result = eventService.eventDeviceNum(vo);
        return DataResult.success(result);

    }
}
