package com.pqs9200.controller.business;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.metadata.Sheet;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.njcn.enums.LogTypeEnum;
import com.njcn.pojo.advanced.EntityAdvancedData;
import com.njcn.pojo.commons.*;
import com.njcn.pojo.commons.area.*;
import com.njcn.pojo.commons.device.DeviceGeneral;
import com.njcn.pojo.commons.device.DeviceValue;
import com.njcn.pojo.commons.device.LineInfo;
import com.njcn.pojo.data.EventDetail;
import com.njcn.pojo.data.VdListQueryVO;
import com.njcn.pojo.excel.*;
import com.njcn.service.commons.IWaveService;
import com.njcn.service.configuration.DeviceService;
import com.njcn.service.data.EventDetailService;
import com.njcn.service.log.UserLogDetailService;
import com.njcn.service.user.DeptsService;
import com.njcn.shiro.cache.VCache;
import com.njcn.shiro.token.TokenManager;
import com.njcn.utils.*;
import com.pqs9200.pojo.commons.device.DevMapInfo;
import com.pqs9200.pojo.map.BaseMap;
import com.pqs9200.service.area.IAreaService;
import com.pqs9200.service.data.IEventPzService;
import com.pqs9200.service.data.IOverviewServer;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.*;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipOutputStream;


/**
 * 区域业务的controller
 */
@Controller
@RequestMapping("/area")
public class AreaController {

    // 日志记录
    private static final Logger logger = LoggerFactory.getLogger(AreaController.class);

    @Autowired
    private IAreaService areaService;

    @Autowired
    private IWaveService waveService;

    @Autowired
    private EventDetailService eventDetailService;

    @Autowired
    private IOverviewServer iOverviewServer;

    @Autowired
    private IEventPzService eventPz;

    @Autowired
    private AppConfig appConfig;

    static VCache cache;

    @Autowired
    private DeviceService deviceService;

    @Autowired
    private UserLogDetailService userLog;

    @Resource
    private DeptsService deptsService;

    @Resource
    private UserUtil userUtil;

    @Resource
    private IAreaService iAreaService;

    /**
     * 获取首页橄榄区域的展示图
     */
    @RequestMapping(value = "getGeneralData", method = RequestMethod.POST)
    @ResponseBody
    public HttpResult getGeneralData(String startTime, String endTime, HttpServletRequest request) {
        HttpResult result = PubUtils.initResult(TokenManager.getToken().getLoginName(), request, LogTypeEnum.BUSSINESS.toString(), 0);
        DatePojo datePojo;
        datePojo = PubUtils.validateDate(startTime, endTime, "getGeneralData");
        if (!datePojo.getValidity()) {
            result = PubUtils.assignmentResult(null, 500, datePojo.getMsg());
            return result;
        }
        AreaGeneral data;
        try {
            data = areaService.getGeneralDate(datePojo.getStartTime(), datePojo.getEndTime());
            if (null == data) {
                result = PubUtils.assignmentResultLog(null, 500, "数据内容为空", "查询概览区域暂降统计", "成功", result);
            } else {
                //置空，减小响应体，提高效率
                data.setLineIndexs(new ArrayList<>());
                data.setDevIndexs(new ArrayList<>());
                result = PubUtils.assignmentResultLog(data, 200, "获取数据成功", "查询概览区域暂降统计", "成功", result);
            }
        } catch (Exception e) {
            logger.error("概览区域概况获取异常：异常为：" + e);
            result = PubUtils.assignmentResultLog(null, 500, "获取数据失败", "查询概览区域暂降统计", "失败", result);
        }
        return result;
    }

    /**
     * 区域概览，获取图表数据
     *
     * @param startTime 起始时间
     * @param endTime   结束事件
     * @param area      区域名称
     */
    @RequestMapping(value = "getCityTotalTimes", method = RequestMethod.POST)
    @ResponseBody
    public HttpResult getCityTotalTimes(String area, String startTime, String endTime, HttpServletRequest request) {
        HttpResult result = PubUtils.initResult(TokenManager.getToken().getLoginName(), request, LogTypeEnum.BUSSINESS.toString(), 0);
        DatePojo datePojo;
        datePojo = PubUtils.validateDate(startTime, endTime, "getCityTotalTimes");
        if (!datePojo.getValidity()) {
            result = PubUtils.assignmentResult(null, 500, datePojo.getMsg());
            return result;
        }
        AreaGeneral data;
        try {
            data = areaService.getGeneralDate(area, datePojo.getStartTime(), datePojo.getEndTime());
            if (null == data) {
                result = PubUtils.assignmentResultLog(null, 500, "无暂降数据", "查询区域概况", "成功", result);
            } else {
                //置空，减小响应体，提高效率
                data.setLineIndexs(new ArrayList<>());
                data.setDevIndexs(new ArrayList<>());
                result = PubUtils.assignmentResultLog(data, 200, "获取暂降次数成功", "查询区域概况", "成功", result);
            }
        } catch (Exception e) {
            logger.error("获取后台数据异常，方法名为：getCityTotalTimes，异常为" + e);
            result = PubUtils.assignmentResultLog(null, 500, "获取暂降数据失败", "查询区域概况", "失败", result);
        }
        return result;
    }

    /**
     * 下载区域暂降事件统计表格数据
     */
    @RequestMapping(value = "downloadGeneralData", method = RequestMethod.POST)
    public void downloadGeneralData(@RequestBody CommonParamter commonParamter, HttpServletResponse response) {
        DatePojo datePojo;
        datePojo = PubUtils.validateDate(commonParamter.getStartTime(), commonParamter.getEndTime(), "downloadGeneralData");
        if (!datePojo.getValidity()) {
            return;
        }
        AreaGeneral data;
        BufferedOutputStream out = null;
        try {
            out = new BufferedOutputStream(response.getOutputStream());
            ExcelWriter writer = new ExcelWriter(out, ExcelTypeEnum.XLSX);
            data = areaService.getGeneralDate(commonParamter.getArea(), datePojo.getStartTime(), datePojo.getEndTime());
            Sheet sheet1 = new Sheet(1, 0, AreaVoltageExcelBody.class);
            sheet1.setSheetName("区域");
            writer.write(getAreaExcel(data), sheet1);
            Sheet sheet2 = new Sheet(2, 0, VoltageExcelBody.class);
            sheet2.setSheetName("电压等级");
            writer.write(getVoltageExcel(data), sheet2);
            Sheet sheet3 = new Sheet(3, 0, MonthExcelBody.class);
            sheet3.setSheetName("月份");
            writer.write(getMonthExcel(data), sheet3);
            writer.finish();
        } catch (Exception e) {
            logger.error("下载区域暂降事件列表发生异常，异常是" + e.getMessage());
        } finally {
            try {
                if (null != out) {
                    out.close();
                }
            } catch (IOException e) {
                logger.error(e.getMessage());
            }
        }

    }

    private List<AreaVoltageExcelBody> getAreaExcel(AreaGeneral areaGeneral) {
        List<AreaVoltageExcelBody> areaVoltageExcelBodies = new ArrayList<>();
        if (null != areaGeneral) {
            List<Area> area = areaGeneral.getArea();
            if (!CollectionUtils.isEmpty(area)) {
                int totalCounts = 0;
                int totalTimes = 0;
                for (Area areaTemp : area) {
                    AreaVoltageExcelBody areaVoltageExcelBody = new AreaVoltageExcelBody();
                    areaVoltageExcelBody.setArea(areaTemp.getCity());
                    areaVoltageExcelBody.setCounts(areaTemp.getAmounts());
                    areaVoltageExcelBody.setTimes(areaTemp.getTimes());
                    totalCounts = areaTemp.getAmounts() + totalCounts;
                    totalTimes = areaTemp.getTimes() + totalTimes;
                    areaVoltageExcelBodies.add(areaVoltageExcelBody);
                }
                AreaVoltageExcelBody areaVoltageExcelBody = new AreaVoltageExcelBody();
                areaVoltageExcelBody.setArea("总计");
                areaVoltageExcelBody.setCounts(totalCounts);
                areaVoltageExcelBody.setTimes(totalTimes);
                areaVoltageExcelBodies.add(areaVoltageExcelBody);
            }
        }
        return areaVoltageExcelBodies;
    }

    private List<VoltageExcelBody> getVoltageExcel(AreaGeneral areaGeneral) {
        List<VoltageExcelBody> voltageExcelBodies = new ArrayList<>();
        if (null != areaGeneral) {
            List<Voltage> voltages = areaGeneral.getVol();
            if (!CollectionUtils.isEmpty(voltages)) {
                int totalCounts = 0;
                int totalTimes = 0;
                for (Voltage volTemp : voltages) {
                    VoltageExcelBody voltageExcelBody = new VoltageExcelBody();
                    voltageExcelBody.setVoltage(volTemp.getVoltageValue());
                    voltageExcelBody.setCounts(volTemp.getAmounts());
                    voltageExcelBody.setTimes(volTemp.getTimes());
                    totalCounts = volTemp.getAmounts() + totalCounts;
                    totalTimes = volTemp.getTimes() + totalTimes;
                    voltageExcelBodies.add(voltageExcelBody);
                }
                VoltageExcelBody voltageExcelBody = new VoltageExcelBody();
                voltageExcelBody.setVoltage("总计");
                voltageExcelBody.setCounts(totalCounts);
                voltageExcelBody.setTimes(totalTimes);
                voltageExcelBodies.add(voltageExcelBody);
            }
        }
        return voltageExcelBodies;
    }

    private List<MonthExcelBody> getMonthExcel(AreaGeneral areaGeneral) {
        List<MonthExcelBody> monthExcelBodies = new ArrayList<>();
        if (null != areaGeneral) {
            List<Interval> interval = areaGeneral.getInterval();
            if (!CollectionUtils.isEmpty(interval)) {
                int totalTimes = 0;
                for (Interval interval1 : interval) {
                    MonthExcelBody monthExcelBody = new MonthExcelBody();
                    monthExcelBody.setMonth(interval1.getYear() + "-" + interval1.getMonth());
                    monthExcelBody.setTimes(interval1.getTimes());
                    totalTimes = interval1.getTimes() + totalTimes;
                    monthExcelBodies.add(monthExcelBody);
                }
                MonthExcelBody monthExcelBody = new MonthExcelBody();
                monthExcelBody.setMonth("总计");
                monthExcelBody.setTimes(totalTimes);
                monthExcelBodies.add(monthExcelBody);
            }
        }
        return monthExcelBodies;
    }

    /**
     * 区域统计，获取图表数据
     *
     * @param startTime 起始时间
     * @param endTime   结束事件
     */
    @RequestMapping(value = "getAreaStatistics", method = RequestMethod.POST)
    @ResponseBody
    public HttpResult getAreaStatistics(String area, String startTime, String endTime, HttpServletRequest request) {
        HttpResult result = PubUtils.initResult(TokenManager.getToken().getLoginName(), request, LogTypeEnum.BUSSINESS.toString(), 0);
        DatePojo datePojo;
        datePojo = PubUtils.validateDate(startTime, endTime, "getAreaStatistics");
        if (!datePojo.getValidity()) {
            result = PubUtils.assignmentResult(null, 500, datePojo.getMsg());
            return result;
        }
        // 统计时间段内的暂降原因次数、暂降类型次数
        ReasonStatisc reasonCounts;
        try {
            reasonCounts = eventDetailService.getVolStatisticsCounts(area, datePojo.getStartTime(), datePojo.getEndTime());
            if (reasonCounts.getTotalTimes() != 0) {
                result = PubUtils.assignmentResultLog(reasonCounts, 200, "查询区域统计成功", "查询区域暂降统计", "成功", result);
            } else {
                result = PubUtils.assignmentResultLog(reasonCounts, 500, "区域统计数据为空", "查询区域暂降统计", "失败", result);
            }
        } catch (Exception e) {
            logger.error("后台获取数据出错，方法名为：getAreaStatistics，异常为：" + e);
            result = PubUtils.assignmentResultLog(null, 500, "获取区域统计数据失败", "查询区域暂降统计", "失败", result);
        }
        return result;
    }


    /**
     * 下载区域统计表格数据
     */
    @RequestMapping(value = "downloadStatisticsData", method = RequestMethod.POST)
    public void downloadStatisticsData(@RequestBody CommonParamter commonParamter, HttpServletResponse response) {
        DatePojo datePojo;
        datePojo = PubUtils.validateDate(commonParamter.getStartTime(), commonParamter.getEndTime(), "downloadStatisticsData");
        if (!datePojo.getValidity()) {
            return;
        }
        ReasonStatisc data;
        BufferedOutputStream out = null;
        try {
            out = new BufferedOutputStream(response.getOutputStream());
            ExcelWriter writer = new ExcelWriter(out, ExcelTypeEnum.XLSX);
            data = eventDetailService.getVolStatisticsCounts(commonParamter.getArea(), datePojo.getStartTime(), datePojo.getEndTime());
            Sheet sheet1 = new Sheet(1, 0, ReasonExcelBody.class);
            sheet1.setSheetName("暂降原因");
            writer.write(getReasonExcel(data), sheet1);
            Sheet sheet2 = new Sheet(2, 0, TypeExcelBody.class);
            sheet2.setSheetName("暂降类型");
            writer.write(getTypeExcel(data), sheet2);
            writer.finish();
        } catch (Exception e) {
            logger.error("下载区域表格发生异常，异常是" + e.getMessage());
        } finally {
            try {
                if (null != out) {
                    out.close();
                }
            } catch (IOException e) {
                logger.error(e.getMessage());
            }
        }

    }


    private List<ReasonExcelBody> getReasonExcel(ReasonStatisc reasonStatisc) {
        List<ReasonExcelBody> reasonExcelBodies = new ArrayList<>();
        if (null != reasonStatisc) {
            List<VoltageReason> voltageReasons = reasonStatisc.getReasons();
            if (!CollectionUtils.isEmpty(voltageReasons)) {
                int totalTimes = 0;
                for (VoltageReason voltageReason : voltageReasons) {
                    ReasonExcelBody reasonExcelBody = new ReasonExcelBody();
                    reasonExcelBody.setReason(voltageReason.getReason());
                    reasonExcelBody.setTimes(voltageReason.getTimes());
                    totalTimes = voltageReason.getTimes() + totalTimes;
                    reasonExcelBodies.add(reasonExcelBody);
                }
                ReasonExcelBody reasonExcelBody = new ReasonExcelBody();
                reasonExcelBody.setReason("总计");
                reasonExcelBody.setTimes(totalTimes);
                reasonExcelBodies.add(reasonExcelBody);
            }
        }
        return reasonExcelBodies;
    }


    private List<TypeExcelBody> getTypeExcel(ReasonStatisc reasonStatisc) {
        List<TypeExcelBody> typeExcelBodies = new ArrayList<>();
        if (null != reasonStatisc) {
            List<VoltageType> voltageTypes = reasonStatisc.getTypes();
            if (!CollectionUtils.isEmpty(voltageTypes)) {
                int totalTimes = 0;
                for (VoltageType voltageType : voltageTypes) {
                    TypeExcelBody typeExcelBody = new TypeExcelBody();
                    typeExcelBody.setType(voltageType.getType());
                    typeExcelBody.setTimes(voltageType.getTimes());
                    totalTimes = voltageType.getTimes() + totalTimes;
                    typeExcelBodies.add(typeExcelBody);
                }
                TypeExcelBody typeExcelBody = new TypeExcelBody();
                typeExcelBody.setType("总计");
                typeExcelBody.setTimes(totalTimes);
                typeExcelBodies.add(typeExcelBody);
            }
        }
        return typeExcelBodies;
    }

    /**
     * 电压暂降列表，获取列表数据
     */
    @RequestMapping(value = "getVoltageDetail", method = RequestMethod.POST)
    @ResponseBody
    public HttpResult getVoltageDetail(@RequestBody VdListQueryVO vdListQueryVO, HttpServletRequest request) {
        HttpResult result = PubUtils.initResult(TokenManager.getToken().getLoginName(), request, LogTypeEnum.BUSSINESS.toString(), 0);
        DatePojo datePojo;
        datePojo = PubUtils.validateDate(vdListQueryVO.getStartTime(), vdListQueryVO.getEndTime(), "getVoltageDetail");
        if (!datePojo.getValidity()) {
            result = PubUtils.assignmentResult(null, 500, datePojo.getMsg());
            return result;
        }
        String area = vdListQueryVO.getArea();
        String type = vdListQueryVO.getType();
        BigDecimal minfuzhi = vdListQueryVO.getMinfuzhi();
        BigDecimal maxfuzhi = vdListQueryVO.getMaxfuzhi();
        BigDecimal mintime = vdListQueryVO.getMintime();
        BigDecimal maxtime = vdListQueryVO.getMaxtime();
        BigDecimal minseverity = vdListQueryVO.getMinseverity();
        BigDecimal maxseverity = vdListQueryVO.getMaxseverity();
        List eventType = vdListQueryVO.getEventType();
        List eventReason = vdListQueryVO.getEventReason();
        List triggerType = vdListQueryVO.getTriggerType();
        Integer fileflag = vdListQueryVO.getFileflag();

        // 统计时间段内的暂降原因次数、暂降类型次数
        List<EventDetail> voltageList;
        try {
            voltageList = eventDetailService.getVolList(datePojo.getStartTime(), datePojo.getEndTime(), area, type, minfuzhi, maxfuzhi, mintime, maxtime, minseverity, maxseverity, eventType, eventReason, triggerType, fileflag);
            if (null == voltageList) {
                result = PubUtils.assignmentResultLog(null, 500, "没有暂降列表的数据", "查询区域暂降列表", "成功", result);
            } else {
                result = PubUtils.assignmentResultLog(voltageList, 200, "获取暂降数据成功", "查询区域暂降列表", "成功", result);
            }
        } catch (Exception e) {
            logger.error("后台获取数据出错，方法名为：getVoltageDetail，异常为：" + e);
            result = PubUtils.assignmentResultLog(null, 500, "获取暂降数据失败", "查询区域暂降列表", "失败", result);
        }
        result.setResult(userUtil.getPro(area));
        return result;
    }


    /**
     * 暂降事件列表中波形查看 最新优化的波形数据获取方式
     *
     * @param session    会话
     * @param eventIndex 事件索引
     */
    @RequestMapping(value = "getWavedata", method = RequestMethod.POST)
    @ResponseBody
    public HttpResult getWavedata(HttpSession session, String eventIndex) {
        session.removeAttribute("eventIndex");
        HttpResult result;
        if (StringUtils.isBlank(eventIndex)) {
            result = PubUtils.assignmentResult(null, 500, "没有获取到事件的索引");
            logger.error("根据事件编号获取波形数据失败，方法名：getWaveData");
        } else {
            WaveData waveData;
            try {
                waveData = waveService.getWavedata(eventIndex, 1);
                result = PubUtils.assignmentResult(waveData, 200, "获取波形数据成功");
            } catch (Exception e) {
                logger.error("事件编号为：" + eventIndex + "，获取波形数据异常，异常为：" + e);
                result = PubUtils.assignmentResult(null, 500, "因为异常导致获取波形数据失败");
            }
        }
        return result;
    }

    /**
     * 暂降事件列表中波形查看 最新优化的波形数据获取方式
     *
     * @param indexes 需要对比的事件波形索引
     */
    @ResponseBody
    @RequestMapping(value = "getWaveDataCompare", method = RequestMethod.POST)
    public HttpResult getWaveDataCompare(String indexes) {
        HttpResult result;
        String[] indexArray;
        if (StrUtil.isBlank(indexes)) {
            return PubUtils.assignmentResult(null, 500, "请选择需要对比的波形事件");
        } else {
            indexArray = indexes.split(StrUtil.COMMA);
            if (indexArray.length < 2) {
                return PubUtils.assignmentResult(null, 500, "请至少选择2个需要对比的波形事件");
            }
        }
        List<WaveData> waveDatas;
        try {
            waveDatas = waveService.getWaveDataCompare(indexArray, 1);
            result = PubUtils.assignmentResult(waveDatas, 200, "获取波形数据成功");
        } catch (Exception e) {
            logger.error("事件编号为：" + indexes + "，获取多事件波形对比数据异常，异常为：" + e);
            result = PubUtils.assignmentResult(null, 500, "因为异常导致获取波形数据失败");
        }
        return result;
    }


    /**
     * 根据用户选择区域查询严重度分析的结果 返回结果：区域、变电站、监测点对应的暂降次数
     */
    @PostMapping("queryLevel")
    @ResponseBody
    public HttpResult queryLevel(String area, String startTime, String endTime, HttpServletRequest request) {
        HttpResult result = PubUtils.initResult(TokenManager.getToken().getLoginName(), request, LogTypeEnum.BUSSINESS.toString(), 0);
        DatePojo datePojo;
        datePojo = PubUtils.validateDate(startTime, endTime, "queryLevel");
        if (!datePojo.getValidity()) {
            result = PubUtils.assignmentResult(null, 500, datePojo.getMsg());
            return result;
        }
        Level level;
        try {
            level = areaService.queryLevel(area, datePojo.getStartTime(), datePojo.getEndTime());
            if (level == null || level.getAreaList().isEmpty()) {
                result = PubUtils.assignmentResultLog(null, 500, "获取严重度分析失败", "查询区域严重度", "成功", result);
            } else {
                result = PubUtils.assignmentResultLog(level, 200, "获取严重度分析成功", "查询区域严重度", "成功", result);
            }
        } catch (Exception e) {
            logger.error("获取严重度分析异常,异常为：" + e.toString());
            result = PubUtils.assignmentResultLog(null, 500, "获取严重度分析异常", "查询区域严重度", "失败", result);
        }
        return result;
    }


    /**
     * 下载区域严重度统计表格数据
     */
    @RequestMapping(value = "downloadLevelData", method = RequestMethod.POST)
    public void downloadLevelData(@RequestBody CommonParamter commonParamter, HttpServletResponse response) {
        DatePojo datePojo;
        datePojo = PubUtils.validateDate(commonParamter.getStartTime(), commonParamter.getEndTime(), "downloadGeneralData");
        if (!datePojo.getValidity()) {
            return;
        }
        Level data;
        BufferedOutputStream out = null;
        try {
            out = new BufferedOutputStream(response.getOutputStream());
            ExcelWriter writer = new ExcelWriter(out, ExcelTypeEnum.XLSX);
            data = areaService.queryLevel(commonParamter.getArea(), datePojo.getStartTime(), datePojo.getEndTime());
            Sheet sheet1 = new Sheet(1, 0, AreaLevelExcelBody.class);
            sheet1.setSheetName("区域");
            writer.write(getAreaLevelExcel(data), sheet1);
            Sheet sheet2 = new Sheet(2, 0, SubLevelExcelBody.class);
            sheet2.setSheetName("变电站");
            writer.write(getSubLevelExcel(data), sheet2);
            Sheet sheet3 = new Sheet(3, 0, MonitorLevelExcelBody.class);
            sheet3.setSheetName("监测点");
            writer.write(getMonitorLevelExcel(data), sheet3);
            writer.finish();
        } catch (Exception e) {
            logger.error("下载区域严重度表格发生了异常，异常是" + e.getMessage());
        } finally {
            try {
                if (null != out) {
                    out.close();
                }
            } catch (IOException e) {
                logger.error(e.getMessage());
            }
        }

    }

    private List<AreaLevelExcelBody> getAreaLevelExcel(Level level) {
        List<AreaLevelExcelBody> areaLevelExcelBodies = new ArrayList<>();
        if (null != level) {
            List<SimpleValue> areaSimple = level.getAreaList();
            if (!CollectionUtils.isEmpty(areaSimple)) {
                int totalTimes = 0;
                int totalMonitor = 0;
                for (SimpleValue simpleValue : areaSimple) {
                    AreaLevelExcelBody areaLevelExcelBody = new AreaLevelExcelBody();
                    areaLevelExcelBody.setArea(simpleValue.getName());
                    areaLevelExcelBody.setMonitors(simpleValue.getCountAll() + "");
                    areaLevelExcelBody.setCounts(simpleValue.getValue());
                    areaLevelExcelBody.setSarfi(simpleValue.getNode());
                    totalTimes = Integer.parseInt(simpleValue.getValue()) + totalTimes;
                    totalMonitor = simpleValue.getCountAll() + totalMonitor;
                    areaLevelExcelBodies.add(areaLevelExcelBody);
                }
                AreaLevelExcelBody areaLevelExcelBody = new AreaLevelExcelBody();
                areaLevelExcelBody.setArea("总计");
                areaLevelExcelBody.setMonitors(totalMonitor + "");
                areaLevelExcelBody.setCounts(totalTimes + "");
                areaLevelExcelBody.setSarfi("/");
                areaLevelExcelBodies.add(areaLevelExcelBody);
            }
        }
        return areaLevelExcelBodies;
    }

    private List<SubLevelExcelBody> getSubLevelExcel(Level level) {
        List<SubLevelExcelBody> subLevelExcelBodies = new ArrayList<>();
        if (null != level) {
            List<SimpleValue> subSimple = level.getSubList();
            if (!CollectionUtils.isEmpty(subSimple)) {
                int totalTimes = 0;
                for (SimpleValue simpleValue : subSimple) {
                    SubLevelExcelBody subLevelExcelBody = new SubLevelExcelBody();
                    subLevelExcelBody.setSub(simpleValue.getName());
                    subLevelExcelBody.setTimes(simpleValue.getValue());
                    totalTimes = Integer.parseInt(simpleValue.getValue()) + totalTimes;
                    subLevelExcelBodies.add(subLevelExcelBody);
                }
                SubLevelExcelBody subLevelExcelBody = new SubLevelExcelBody();
                subLevelExcelBody.setSub("总计");
                subLevelExcelBody.setTimes(totalTimes + "");
                subLevelExcelBodies.add(subLevelExcelBody);
            }
        }
        return subLevelExcelBodies;
    }

    private List<MonitorLevelExcelBody> getMonitorLevelExcel(Level level) {
        List<MonitorLevelExcelBody> monitorLevelExcelBodies = new ArrayList<>();
        if (null != level) {
            List<SimpleValue> monitorSimple = level.getMonitorList();
            if (!CollectionUtils.isEmpty(monitorSimple)) {
                int totalTimes = 0;
                for (SimpleValue simpleValue : monitorSimple) {
                    MonitorLevelExcelBody monitorLevelExcelBody = new MonitorLevelExcelBody();
                    monitorLevelExcelBody.setMonitor(simpleValue.getName());
                    monitorLevelExcelBody.setTimes(simpleValue.getValue());
                    monitorLevelExcelBodies.add(monitorLevelExcelBody);
                }
                for (SimpleValue simpleValue : level.getAreaList()) {
                    totalTimes = Integer.parseInt(simpleValue.getValue()) + totalTimes;
                }
                MonitorLevelExcelBody monitorLevelExcelBody = new MonitorLevelExcelBody();
                monitorLevelExcelBody.setMonitor("总计");
                monitorLevelExcelBody.setTimes(totalTimes + "");
                monitorLevelExcelBodies.add(monitorLevelExcelBody);
            }
        }
        return monitorLevelExcelBodies;
    }

    /**
     * 根据用户选择区域查询严重度分析的结果 返回结果：区域、变电站、监测点对应的暂降次数
     */
    @PostMapping(value = "getMapData")
    @ResponseBody
    public HttpResult getMapData(String startTime, String endTime, HttpServletRequest request) {
        HttpResult result = PubUtils.initResult(TokenManager.getToken().getLoginName(), request, LogTypeEnum.BUSSINESS.toString(), 0);
        DatePojo datePojo;
        datePojo = PubUtils.validateDate(startTime, endTime, "getMapData");
        if (!datePojo.getValidity()) {
            result = PubUtils.assignmentResult(null, 500, datePojo.getMsg());
            return result;
        }
        Level level;
        try {
            level = areaService.queryLevel(datePojo.getStartTime(), datePojo.getEndTime());
            if (null == level || level.getAreaList().isEmpty()) {
                result = PubUtils.assignmentResultLog(null, 500, "获取严重度分析失败", "查询概览区域严重度", "成功", result);
            } else {
                result = PubUtils.assignmentResultLog(level, 200, "获取严重度分析成功", "查询概览区域严重度", "成功", result);
            }
        } catch (Exception e) {
            logger.error("获取严重度分析异常,异常为：" + e.toString());
            result = PubUtils.assignmentResultLog(null, 500, "获取严重度分析异常", "查询概览区域严重度", "失败", result);
        }
        return result;
    }

    /**
     * 首页滚动获取未处理事件
     */
    @ResponseBody
    @RequestMapping(value = "getZjsj", method = RequestMethod.POST)
    public HttpResult getZjsj(HttpServletRequest request) {
        HttpResult result;
        List<List> deviceList = eventPz.getZjsj();
        if (deviceList.isEmpty()) {
            userLog.getLog("查询未处理暂降事件", "失败", PubUtils.getIpAddr(request), LogTypeEnum.BUSSINESS.toString(), 0);
            result = PubUtils.assignmentResult(null, 500, "获取未处理事件失败");
        } else {
            userLog.getLog("查询未处理暂降事件", "成功", PubUtils.getIpAddr(request), LogTypeEnum.BUSSINESS.toString(), 0);
            result = PubUtils.assignmentResult(deviceList, 200, "获取未处理事件成功");
        }
        return result;
    }

    /**
     * 首页获取终端异常
     */
    @ResponseBody
    @RequestMapping(value = "getrunevent", method = RequestMethod.POST)
    public HttpResult getrunevent(HttpServletRequest request) {
        HttpResult result;
        List<List> deviceList = eventDetailService.getrunevent();
        if (deviceList.isEmpty()) {
            userLog.getLog("查询终端异常事件", "失败", PubUtils.getIpAddr(request), LogTypeEnum.BUSSINESS.toString(), 0);
            result = PubUtils.assignmentResult(null, 500, "获取终端异常失败");
        } else {
            userLog.getLog("查询终端异常事件", "成功", PubUtils.getIpAddr(request), LogTypeEnum.BUSSINESS.toString(), 0);
            result = PubUtils.assignmentResult(deviceList, 200, "获取终端异常成功");
        }
        return result;
    }


    /**
     * 暂降事件列表批量下载波形，先判断波形文件存在与否
     */
    @PostMapping("downloadWave")
    @ResponseBody
    public HttpResult downloadWave(@RequestParam("index[]") List<String> index) {
        HttpResult result;
        if (CollectionUtils.isEmpty(index)) {
            result = PubUtils.assignmentResult(null, 500, "请选中需要下载的波形");
            return result;
        }
        try {
            //下载前，清空备份
            String item = "njcntemp" + File.separator + "waveTemp9200";
            FileUtil.clean(new File(appConfig.getTmppath() + item));
            Map<String, List<String>> indexList = waveService.getEventDetailIndexList(index);
            if (CollectionUtils.isEmpty(indexList)) {
                result = PubUtils.assignmentResult(null, 500, "没有波形数据");
            } else {
                result = PubUtils.assignmentResult(indexList, 200, "波形数据准备完毕");
                cache.set(TokenManager.getUserId() + TokenManager.getSysType() + "waveFiles9200", indexList);
            }
        } catch (Exception e) {
            logger.error("后台获取数据出错，方法名为：downloadWave，异常为：" + e);
            result = PubUtils.assignmentResult(null, 500, "获取暂降事件数据出错，请联系管理员");
        }
        return result;
    }


    /**
     * 下载波形文件
     */
    @RequestMapping("downWaveZip")
    public void downZIPFile(HttpServletResponse response) throws Exception {
        Map<String, List<String>> files = cache.get(TokenManager.getUserId() + TokenManager.getSysType() + "waveFiles9200");
        if (CollectionUtils.isEmpty(files)) {
            return;
        }
        String zipName = "Comtrade.zip";
        response.setContentType("APPLICATION/OCTET-STREAM");
        response.setHeader("Content-Disposition", "attachment; filename=" + zipName);
        ZipOutputStream out = new ZipOutputStream(response.getOutputStream());
        try {
            Iterator<Map.Entry<String, List<String>>> it = files.entrySet().iterator();
            String item = "njcntemp" + File.separator + "waveTemp9200";
            File comtrade = new File(appConfig.getTmppath() + item);
            FileUtil.clean(comtrade);
            while (it.hasNext()) {
                Map.Entry<String, List<String>> entry = it.next();
                List<String> filePaths = entry.getValue();
                File directoryFile = new File(appConfig.getTmppath() + item + File.separator + entry.getKey());
                for (String path : filePaths) {
                    FileUtils.copyFileToDirectory(new File(path), directoryFile);
                }
            }
            ZipUtils.doCompress(comtrade.getPath(), out);
            //压缩完毕后，清除这个文件夹下的所有的文件
            response.flushBuffer();
            FileUtil.clean(comtrade);
        } catch (Exception e) {
            logger.error("下载波形文件发生了异常，异常是" + e.getMessage());
        } finally {
            out.close();
        }
    }

    @PostMapping(value = "getDevMap")
    @ResponseBody
    public HttpResult getDevMap(HttpServletRequest request, String startTime, String endTime) {
        HttpResult result;
        DevMapInfo maps;
        maps = iOverviewServer.getDevMap();
        if (maps == null) {
            result = PubUtils.assignmentResult(null, 500, "获取监测网失败");
            userLog.getLog("查询监测网分布", "失败", PubUtils.getIpAddr(request), LogTypeEnum.BUSSINESS.toString(), 0);
        } else {
            result = PubUtils.assignmentResult(maps, 200, "获取监测网成功");
            userLog.getLog("查询监测网分布", "成功", PubUtils.getIpAddr(request), LogTypeEnum.BUSSINESS.toString(), 0);
        }
        return result;
    }

    @PostMapping(value = "getEventMap")
    @ResponseBody
    public HttpResult getEventMap(HttpServletRequest request, String startTime, String endTime) {
        HttpResult result;
        DatePojo datePojo;
        datePojo = PubUtils.validateDate(startTime, endTime, "getEventMap");
        if (!datePojo.getValidity()) {
            result = PubUtils.assignmentResult(null, 500, "解析前台传递的时间有误");
            return result;
        }
        List<LineInfo> eventMap;
        try {
            eventMap = areaService.getEventMaps(datePojo.getStartTime(), datePojo.getEndTime());
            if (eventMap.isEmpty()) {
                result = PubUtils.assignmentResult(null, 500, "获取热力图失败");
            } else {
                result = PubUtils.assignmentResult(eventMap, 200, "获取热力图成功");
            }
            userLog.getLog("查询暂降热力图", "成功", PubUtils.getIpAddr(request), LogTypeEnum.BUSSINESS.toString(), 0);
        } catch (Exception e) {
            result = PubUtils.assignmentResult(null, 500, "获取热力图失败");
            userLog.getLog("查询暂降热力图", "失败", PubUtils.getIpAddr(request), LogTypeEnum.BUSSINESS.toString(), 0);
        }
        return result;
    }

    @PostMapping(value = "getGdcounts")
    @ResponseBody
    public HttpResult getGdcounts(HttpServletRequest request, String startTime, String endTime) {
        HttpResult result;
        DatePojo datePojo;
        datePojo = PubUtils.validateDate(startTime, endTime, "getGdcounts");
        if (!datePojo.getValidity()) {
            result = PubUtils.assignmentResult(null, 500, "解析前台传递的时间有误");
            return result;
        }
        List<LineInfo> eventMap;
        try {
            eventMap = areaService.getGdcounts(datePojo.getStartTime(), datePojo.getEndTime());
            if (eventMap.isEmpty()) {
                result = PubUtils.assignmentResult(null, 500, "获取供电公司统计失败");
            } else {
                result = PubUtils.assignmentResult(eventMap, 200, "获取供电公司统计成功");
            }
        } catch (Exception e) {
            result = PubUtils.assignmentResult(null, 500, "获取供电公司统计失败");
        }
        return result;
    }

    @PostMapping("analysis")
    @ResponseBody
    public EntityAdvancedData analysis(HttpSession session, String eventIndex, HttpServletRequest request) {
        session.removeAttribute("maxy");
        session.removeAttribute("miny");
        try {
            userLog.getLog("波形分析", "成功", PubUtils.getIpAddr(request), LogTypeEnum.BUSSINESS.toString(), 0);
            return waveService.analysis(eventIndex);
        } catch (Exception e) {
            userLog.getLog("波形分析", "失败", PubUtils.getIpAddr(request), LogTypeEnum.BUSSINESS.toString(), 0);
            logger.error(e.toString());
            return null;
        }
    }

    /**
     * 区域统计--》终端状态
     */
    @PostMapping("deviceStatus")
    @ResponseBody
    public HttpResult getDeviceStatus(String overview, String area, HttpServletRequest request, String startTime, String endTime) {
        HttpResult result = PubUtils.initResult(TokenManager.getToken().getLoginName(), request, LogTypeEnum.BUSSINESS.toString(), 0);
        DeviceGeneral data;
        DatePojo datePojo;
        datePojo = PubUtils.validateDate(startTime, endTime, "deviceStatus");
        if (!datePojo.getValidity()) {
            result = PubUtils.assignmentResult(null, 500, datePojo.getMsg());
            return result;
        }
        try {
            data = deviceService.getDeviceData(overview, area, datePojo.getStartTime(), datePojo.getEndTime());
            if (null == data) {
                result = PubUtils.assignmentResultLog(null, 500, "获取终端运行数据失败", "查询暂降终端运行状态", "成功", result);
            } else {
                result = PubUtils.assignmentResultLog(data, 200, "获取终端运行数据成功", "查询暂降终端运行状态", "成功", result);
            }
        } catch (Exception e) {
            logger.error("获取终端运行数据异常,异常为：" + e.toString());
            result = PubUtils.assignmentResultLog(null, 500, "获取终端运行数据异常", "查询暂降终端运行状态", "失败", result);
        }
        return result;
    }

    /**
     * 区域统计--》在线率
     *
     * @param startTime 起始时间
     * @param endTime   截止时间
     */
    @PostMapping("onlineRate")
    @ResponseBody
    public HttpResult getOnlineRate(String startTime, String endTime, String overview, String area, HttpServletRequest request) {
        HttpResult result = PubUtils.initResult(TokenManager.getToken().getLoginName(), request, LogTypeEnum.BUSSINESS.toString(), 0);
        DatePojo datePojo;
        datePojo = PubUtils.validateDate(startTime, endTime, "getOnlineRate");
        if (!org.springframework.util.StringUtils.isEmpty(datePojo.getMsg())) {
            result = PubUtils.assignmentResult(null, 500, datePojo.getMsg());
            return result;
        }
        DeviceGeneral data;
        try {
            data = deviceService.getDeviceOnlineRate(datePojo.getStartTime(), datePojo.getEndTime(), overview, area);
            if (null == data) {
                result = PubUtils.assignmentResultLog(null, 500, "获取终端在线率数据为空", "查询终端在线率", "成功", result);
            } else {
                result = PubUtils.assignmentResultLog(data, 200, "获取终端在线率数据成功", "查询终端在线率", "成功", result);
            }
        } catch (Exception e) {
            logger.error("获取终端运行数据异常,异常为：" + e.toString());
            result = PubUtils.assignmentResultLog(null, 500, "获取终端在线率数据异常", "查询终端在线率", "失败", result);
        }
        return result;
    }

    /**
     * 下载终端在线率表格数据
     */
    @PostMapping("downloadOnlineRateData")
    @ResponseBody
    public void downloadOnlineRateData(@RequestBody CommonParamter commonParamter, HttpServletResponse response) {
        DatePojo datePojo;
        datePojo = PubUtils.validateDate(commonParamter.getStartTime(), commonParamter.getEndTime(), "downloadGeneralData");
        if (!datePojo.getValidity()) {
            return;
        }
        DeviceGeneral data;
        BufferedOutputStream out = null;
        try {
            out = new BufferedOutputStream(response.getOutputStream());
            ExcelWriter writer = new ExcelWriter(out, ExcelTypeEnum.XLSX);
            data = deviceService.getDeviceOnlineRate(datePojo.getStartTime(), datePojo.getEndTime(), "", commonParamter.getArea());
            Sheet sheet1 = new Sheet(1, 0, AreaOnlineRateExcelBody.class);
            sheet1.setSheetName("区域");
            writer.write(getAreaOnlineRateExcel(data), sheet1);
            Sheet sheet2 = new Sheet(2, 0, CompanyOnlineRateExcelBody.class);
            sheet2.setSheetName("厂家");
            writer.write(getCompanyOnlineRateExcel(data), sheet2);
            writer.finish();
        } catch (Exception e) {
            logger.error("下载终端在线率表格发生了异常，异常是" + e.getMessage());
        } finally {
            try {
                if (null != out) {
                    out.close();
                }
            } catch (IOException e) {
                logger.error(e.getMessage());
            }
        }
    }

    private List<AreaOnlineRateExcelBody> getAreaOnlineRateExcel(DeviceGeneral deviceGeneral) {
        List<AreaOnlineRateExcelBody> areaOnlineRateExcelBodies = new ArrayList<>();
        if (null != deviceGeneral) {
            List<DeviceValue> deviceValues = deviceGeneral.getArea();
            if (!CollectionUtils.isEmpty(deviceValues)) {
                int totalAmounts = 0;
                for (DeviceValue deviceValue : deviceValues) {
                    AreaOnlineRateExcelBody areaOnlineRateExcelBody = new AreaOnlineRateExcelBody();
                    areaOnlineRateExcelBody.setArea(deviceValue.getName());
                    areaOnlineRateExcelBody.setAmounts(deviceValue.getAmounts());
                    areaOnlineRateExcelBody.setOnline(getOnlie(deviceValue.getOnline()));
                    totalAmounts = Integer.parseInt(deviceValue.getAmounts()) + totalAmounts;
                    areaOnlineRateExcelBodies.add(areaOnlineRateExcelBody);
                }
                AreaOnlineRateExcelBody areaOnlineRateExcelBody = new AreaOnlineRateExcelBody();
                areaOnlineRateExcelBody.setArea("总计");
                areaOnlineRateExcelBody.setAmounts(totalAmounts + "");
                areaOnlineRateExcelBody.setOnline("/");
                areaOnlineRateExcelBodies.add(areaOnlineRateExcelBody);
            }
        }
        return areaOnlineRateExcelBodies;
    }

    private List<CompanyOnlineRateExcelBody> getCompanyOnlineRateExcel(DeviceGeneral deviceGeneral) {
        List<CompanyOnlineRateExcelBody> companyOnlineRateExcelBodies = new ArrayList<>();
        if (null != deviceGeneral) {
            List<DeviceValue> deviceValues = deviceGeneral.getInterval();
            if (!CollectionUtils.isEmpty(deviceValues)) {
                int totalAmounts = 0;
                for (DeviceValue deviceValue : deviceValues) {
                    CompanyOnlineRateExcelBody companyOnlineRateExcelBody = new CompanyOnlineRateExcelBody();
                    companyOnlineRateExcelBody.setCompany(deviceValue.getName());
                    companyOnlineRateExcelBody.setAmounts(deviceValue.getAmounts());
                    companyOnlineRateExcelBody.setOnline(getOnlie(deviceValue.getOnline()));
                    totalAmounts = Integer.parseInt(deviceValue.getAmounts()) + totalAmounts;
                    companyOnlineRateExcelBodies.add(companyOnlineRateExcelBody);
                }
                CompanyOnlineRateExcelBody companyOnlineRateExcelBody = new CompanyOnlineRateExcelBody();
                companyOnlineRateExcelBody.setCompany("总计");
                companyOnlineRateExcelBody.setAmounts(totalAmounts + "");
                companyOnlineRateExcelBody.setOnline("/");
                companyOnlineRateExcelBodies.add(companyOnlineRateExcelBody);
            }
        }
        return companyOnlineRateExcelBodies;
    }


    private String getOnlie(String online) {
        switch (online) {
            case "3.1415":
                return "/";
            case "3.14159":
                return "暂无数据";
            default:
                return online;
        }

    }

    /**
     * 根据当前身份或者前台区域获取父子节点地区
     */
    @PostMapping("getMapInfo")
    @ResponseBody
    public HttpResult getMapInfo(String area) {
        HttpResult httpResult;
        SimpleValue simpleValue;
        try {
            simpleValue = deptsService.getMapInfo(area);
            httpResult = PubUtils.assignmentResult(simpleValue, 200, "获取地图信息成功");
        } catch (Exception e) {
            httpResult = PubUtils.assignmentResult(null, 500, "获取地图信息失败");
            logger.error("获取地图信息异常，异常为：" + e.toString());
        }
        return httpResult;
    }

    /***
     * 获取json地图文件
     */
    @PostMapping("getBaseMapInfo")
    @ResponseBody
    public HttpResult getBaseMapInfo(HttpServletRequest request, String area) {
        HttpResult httpResult;
        String jsonStr = "";
        try {

            RestTemplate template = new RestTemplate();
            //组装路径
            String url = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + area;
            String forObject = template.getForObject(url, String.class);
            jsonStr = forObject.toString();
            BaseMap baseMap = iAreaService.getBase(jsonStr);
            httpResult = PubUtils.assignmentResult(baseMap, 200, "获取地图信息成功");
        } catch (Exception e) {
            httpResult = PubUtils.assignmentResult(null, 500, "获取地图信息失败");
            logger.error("获取地图信息异常，异常为：" + e.toString());
        }
        return httpResult;
    }
}
