package com.tofly.water.service.impl;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.haiqiu.tools.excel.utils.ExcelUtils;
import com.tofly.common.constant.CalendarHelper;
import com.tofly.scada.common.FlowConstant;
import com.tofly.scada.entity.Allocation;
import com.tofly.scada.entity.Scada;
import com.tofly.scada.entity.ScadaReport;
import com.tofly.scada.entity.TfScadaReportList;
import com.tofly.scada.entity.dto.DeviceQuery;
import com.tofly.scada.entity.dto.ScadaQuery;
import com.tofly.scada.entity.vo.DeviceArchiveManageVo;
import com.tofly.scada.entity.vo.ScadaVo;
import com.tofly.scada.entity.vo.StatisticsScadaVo;
import com.tofly.scada.service.*;
import com.tofly.spire.entity.IndexAllocation;
import com.tofly.spire.service.IndexAllocationService;
import com.tofly.water.entity.BasePump;
import com.tofly.water.entity.BasePumpGroup;
import com.tofly.water.entity.dto.*;
import com.tofly.water.entity.vo.*;
import com.tofly.water.mapper.OverviewMapper;
import com.tofly.water.service.BasePumpGroupService;
import com.tofly.water.service.BasePumpService;
import com.tofly.water.service.DeviceBusinessService;
import com.tofly.water.service.OverviewService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author HaiQiu
 * @since 2022/11/22
 */
@Service("overviewService")
public class OverviewServiceImpl implements OverviewService {

    @Autowired
    private ScadaService scadaService;

    @Autowired
    private IndexAllocationService indexAllocationService;

    @Resource
    private TfScadaReportListService tfScadaReportListService;

    @Autowired
    private BasePumpService basePumpService;

    @Autowired
    private BasePumpGroupService basePumpGroupService;

    @Autowired
    private DeviceArchiveManageService deviceArchiveManageService;

    @Autowired
    private ScadaReportService reportService;

    @Autowired
    private StatisticsScadaService statisticsScadaService;

    @Autowired
    private ScadaService monitorService;


    @Autowired
    private DeviceBusinessService deviceBusinessService;

    @Autowired
    private OverviewMapper overviewMapper;

    @Autowired
    private RunLogCodes runLogCodes;


    @Override
    public Page<DeviceBusPumpsVo> whole(Page page, OverviewDto overviewDto) {
        //分页
        if (overviewDto.getIsPage() == null) {
            overviewDto.setIsPage(true);
        }
        Page<DeviceBusPumpsVo> devices = getDevices(page, overviewDto);
        if (CollectionUtils.isEmpty(devices.getRecords())) {
            return null;
        }
        Page<Object> objectPage = new Page<>();
        BeanUtils.copyProperties(page, objectPage);
        for (DeviceBusPumpsVo record : devices.getRecords()) {
            ScadaQuery scadaQuery = new ScadaQuery();
            BeanUtils.copyProperties(overviewDto, scadaQuery);
            scadaQuery.setDeviceIds(Collections.singletonList(record.getId()));
            //获取scada历史数据
            Page data = statisticsScadaService.getPageData(objectPage, scadaQuery, overviewDto.getIsPage());
            record.setScadaList(data);
        }
        return devices;
    }

    @Override
    public Page<DeviceBusPumpsVo> alert(Page page, ReportDto overviewDto) {
        //分页
        if (overviewDto.getIsPage() == null) {
            overviewDto.setIsPage(true);
        }
        Page<DeviceBusPumpsVo> devices = getDevices1(page, overviewDto);
        if (CollectionUtils.isEmpty(devices.getRecords())) {
            return null;
        }
        Page<TfScadaReportList> objectPage = new Page<>();
        BeanUtils.copyProperties(page, objectPage);
        for (DeviceBusPumpsVo record : devices.getRecords()) {
            TfScadaReportList tfScadaReportList = new TfScadaReportList();
            BeanUtils.copyProperties(overviewDto, tfScadaReportList);

            List<IndexAllocation> allocations = indexAllocationService.list(Wrappers.<IndexAllocation>lambdaQuery()
                    .in(IndexAllocation::getDeviceId, record.getId()));
            if (CollectionUtils.isEmpty(allocations)) {
                return null;
            }
            String codes = allocations.stream().filter(indexAllocation -> StringUtils.hasText(indexAllocation.getVariableCode()))
                    .map(IndexAllocation::getVariableCode).collect(Collectors.joining(","));
            tfScadaReportList.setCodes(codes);
            //获取scada历史数据
            if (overviewDto.getIsPage()) {
                Page data = tfScadaReportListService.pageList(objectPage, tfScadaReportList);
                record.setScadaList(data);
            } else {
                List<TfScadaReportList> scadaReportLists = tfScadaReportListService.allList(tfScadaReportList);
                record.setScadaList(scadaReportLists);
            }
        }
        return devices;
    }

    @Override
    public Page<DeviceBusPumpsVo> newest(Page page, NewestDto overviewDto) {
        //分页
        if (overviewDto.getIsPage() == null) {
            overviewDto.setIsPage(true);
        }
        Page<DeviceBusPumpsVo> devices = getDevices2(page, overviewDto);
        if (CollectionUtils.isEmpty(devices.getRecords())) {
            return null;
        }
        for (DeviceBusPumpsVo record : devices.getRecords()) {
            DeviceQuery deviceQuery = new DeviceQuery();
            BeanUtils.copyProperties(overviewDto, deviceQuery);
            deviceQuery.setDeviceIds(Collections.singletonList(record.getId()));
            //获取最新历史数据
            List<DeviceArchiveManageVo> appData = scadaService.getAppData(deviceQuery);
            record.setScadaList(appData);
        }
        return devices;
    }

    @Override
    public Page<StatisticsScadaVo> waterSupply(Page page, OverviewDto overviewDto) {
        ScadaQuery scadaQuery = new ScadaQuery();
        BeanUtils.copyProperties(overviewDto, scadaQuery);
        //获取scada历史数据
        Page<StatisticsScadaVo> data = statisticsScadaService.getPageData(page, scadaQuery, overviewDto.getIsPage());
        return data;
    }

    @Override
    public Page<StatisticsScadaVo> powerSupply(Page page, OverviewDto overviewDto) {
        ScadaQuery scadaQuery = new ScadaQuery();
        BeanUtils.copyProperties(overviewDto, scadaQuery);
        //获取scada历史数据
        Page<StatisticsScadaVo> data = statisticsScadaService.getPageData(page, scadaQuery, overviewDto.getIsPage());
        return data;
    }

    @Override
    public Page<MonitorPumpVo> monitor(Page page, MonitorDto overviewDto) {
        //查询全部泵站ID
        if (CollectionUtils.isEmpty(overviewDto.getPumpIds())) {
            List<BasePump> list = basePumpService.list();
            if (!CollectionUtils.isEmpty(list)) {
                List<Long> collect = list.stream().map(BasePump::getId).collect(Collectors.toList());
                overviewDto.setPumpIds(collect);
            }
        }
        return overviewMapper.pageMonitorNew(page, overviewDto, "SCADA_HISTORY");
    }

    @Override
    public Page<MonitorPumpVo> monitorNew(Page page, MonitorDto overviewDto) {
        //查询全部泵站ID
        if (CollectionUtils.isEmpty(overviewDto.getPumpIds())) {
            List<BasePump> list = basePumpService.list();
            if (!CollectionUtils.isEmpty(list)) {
                List<Long> collect = list.stream().map(BasePump::getId).collect(Collectors.toList());
                overviewDto.setPumpIds(collect);
            }
        }
        return overviewMapper.pageMonitorNew(page, overviewDto, "SCADA_HISTORY");
    }


    @Override
    public void monitorExport(Page page, MonitorDto overviewDto, boolean exportAll) {
        if (exportAll) {
            List<MonitorPumpVo> monitor = overviewMapper.monitor(overviewDto, "SCADA_HISTORY");
            if (!CollectionUtils.isEmpty(monitor)) {
                ExcelUtils.getListToExcel(MonitorPumpVo.class, monitor, "监测信息", "检测信息");
            }
        } else {
            Page<MonitorPumpVo> monitor = monitor(page, overviewDto);
            if (monitor != null && monitor.getRecords() != null) {
                ExcelUtils.getListToExcel(MonitorPumpVo.class, monitor.getRecords(), "监测信息", "检测信息");
            }
        }
    }

    @Override
    public Object monitorReal(Page page, MonitorRealDto dto) {
        return selectByWaterOrPump(page, dto, true);
    }

    @Override
    public Object historyReal(Page page, MonitorRealDto dto) {
        return selectByWaterOrPump(page, dto, false);
    }

    @Override
    public Object reportReal(Page page, MonitorRealDto dto) {
        // 查询水厂
        if (dto.getType() == 1) {
            // 查询全部水厂ID
            getWaterIds(dto);
            if (dto.getPage()) {
                return overviewMapper.reportRealWaterPage(page, dto);
            } else {
                return overviewMapper.reportWaterReal(page, dto);
            }
        } else if (dto.getType() == 2) {
            //查询全部泵站ID
            getPumpIds(dto);
            // 查询泵站
            if (dto.getPage()) {
                return overviewMapper.reportRealPage(page, dto);
            } else {
                return overviewMapper.reportReal(page, dto);
            }
        }
        return null;
    }

    private void getWaterIds(MonitorRealDto dto) {
        if (CollectionUtils.isEmpty(dto.getWaterIds())) {
            List<Long> waterIds = overviewMapper.getWaterIds();
            if (!CollectionUtils.isEmpty(waterIds)) {
                dto.setWaterIds(waterIds);
            }
        }
    }

    private void getWaterIds(StatisticsRealDto dto) {
        if (CollectionUtils.isEmpty(dto.getWaterIds())) {
            List<Long> waterIds = overviewMapper.getWaterIds();
            if (!CollectionUtils.isEmpty(waterIds)) {
                dto.setWaterIds(waterIds);
            }
        }
    }

    private void getPumpIds(MonitorRealDto dto) {
        if (CollectionUtils.isEmpty(dto.getPumpIds())) {
            List<BasePump> list = basePumpService.list();
            if (!CollectionUtils.isEmpty(list)) {
                List<Long> collect = list.stream().map(BasePump::getId).collect(Collectors.toList());
                dto.setPumpIds(collect);
            }
        }
    }

    private void getPumpIds(StatisticsRealDto dto) {
        if (CollectionUtils.isEmpty(dto.getPumpIds())) {
            List<BasePump> list = basePumpService.list();
            if (!CollectionUtils.isEmpty(list)) {
                List<Long> collect = list.stream().map(BasePump::getId).collect(Collectors.toList());
                dto.setPumpIds(collect);
            }
        }
    }

    private void getPumpGroupIds(StatisticsRealDto dto) {
        if (CollectionUtils.isEmpty(dto.getPumpGroupIds())) {
            List<BasePumpGroup> list = basePumpGroupService.list();
            if (!CollectionUtils.isEmpty(list)) {
                List<Long> collect = list.stream().map(BasePumpGroup::getId).collect(Collectors.toList());
                dto.setPumpGroupIds(collect);
            }
        }
    }

    @Override
    public Object statisticsReal(Page page, StatisticsRealDto dto) {
        //如果查询的是泵站
        if (dto.getType() == 2) {
//            if (dto.getIsPump()) {
//                //查询全部泵站ID
//                getPumpIds(dto);
//                //查询全部泵组ID
//                getPumpGroupIds(dto);
//            }
            if (dto.getPage()) {
                return overviewMapper.statisticsPumpRealPage(page, dto);
            } else {
                return overviewMapper.statisticsPumpReal(dto);
            }
        } else if (dto.getType() == 1) {
            // 查询全部水厂ID
            getWaterIds(dto);
            //如果查询的是水厂
            if (dto.getPage()) {
                return overviewMapper.statisticsPumpWaterPage(page, dto);
            } else {
                return overviewMapper.statisticsPumpWater(dto);
            }
        }
        return null;
    }


    /**
     * 查询水厂或泵站最新监控数据包含报警上下限
     *
     * @param page      分页
     * @param dto       查询参数
     * @param isMonitor 是否实时数据查询
     * @return 查询水厂或泵站最新监控数据包含报警上下限
     */

    public Object selectByWaterOrPump(Page page, MonitorRealDto dto, boolean isMonitor) {
        String tableName = "SCADA_HISTORY";
        if (isMonitor) {
            tableName = "SCADA_MONITORING";
        }
        //如果查询的是泵站
        if (dto.getType() == 2) {
            MonitorDto monitorDto = new MonitorDto();
            BeanUtils.copyProperties(dto, monitorDto);
            if (dto.getPage()) {
                return overviewMapper.pageMonitor(page, monitorDto, tableName);
            } else {
                return overviewMapper.monitor(monitorDto, tableName);
            }
        } else if (dto.getType() == 1) {
            //如果查询的是水厂
            if (dto.getPage()) {
                return overviewMapper.pageMonitorWater(page, dto, tableName);
            } else {
                return overviewMapper.monitorWater(dto, tableName);
            }
        }
        return null;
    }


    public Page<DeviceBusPumpsVo> getDevices(Page page, OverviewDto overviewDto) {
//        QueryWrapper<OverviewDto> wrapper = getWrapper(overviewDto);
        return getDeviceBusPumpsVoPage(page, overviewDto);
    }

    private Page<DeviceBusPumpsVo> getDeviceBusPumpsVoPage(Page page, OverviewDto overviewDto) {
        if (overviewDto.getIsPageOut() == null || overviewDto.getIsPageOut()) {
            Page<DeviceBusPumpsVo> devices = overviewMapper.getDevicesByPage(page, overviewDto);
            return devices;
        } else {
            List<DeviceBusPumpsVo> devices = overviewMapper.getDevices(overviewDto);
            page.setRecords(devices);
            return page;
        }
    }

    private QueryWrapper<OverviewDto> getWrapper(OverviewDto overviewDto) {
        QueryWrapper<OverviewDto> wrapper = new QueryWrapper<>();
        wrapper.in(!CollectionUtils.isEmpty(overviewDto.getDeviceIds()), "d.ID", overviewDto.getDeviceIds())
                .like(StringUtils.hasText(overviewDto.getPumpName()), "p.NAME", overviewDto.getPumpName())
                .and(q -> {
                    q.in(!CollectionUtils.isEmpty(overviewDto.getPumpOrGroupIds()), "p.ID", overviewDto.getPumpOrGroupIds())
                            .or()
                            .in(!CollectionUtils.isEmpty(overviewDto.getPumpOrGroupIds()), "pg.ID", overviewDto.getPumpOrGroupIds());
                });
        String customSqlSegment = wrapper.getCustomSqlSegment();
        if (customSqlSegment.equals("WHERE ()")) {

        }
        return wrapper;
    }


    public Page<DeviceBusPumpsVo> getDevices1(Page page, ReportDto reportDto) {
        OverviewDto overviewDto = new OverviewDto();
        BeanUtils.copyProperties(reportDto, overviewDto);
//        QueryWrapper<OverviewDto> wrapper = getWrapper1(overviewDto);
        return getDeviceBusPumpsVoPage(page, overviewDto);
    }

    private QueryWrapper<OverviewDto> getWrapper1(ReportDto overviewDto) {
        QueryWrapper<OverviewDto> wrapper = new QueryWrapper<>();
        wrapper.like(StringUtils.hasText(overviewDto.getPumpName()), "p.NAME", overviewDto.getPumpName())
                .and(q -> {
                    q.in(!CollectionUtils.isEmpty(overviewDto.getPumpOrGroupIds()), "p.ID")
                            .or()
                            .in(!CollectionUtils.isEmpty(overviewDto.getPumpOrGroupIds()), "pg.ID");
                });
        return wrapper;
    }


    public Page<DeviceBusPumpsVo> getDevices2(Page page, NewestDto newestDto) {
        OverviewDto overviewDto = new OverviewDto();
        BeanUtils.copyProperties(newestDto, overviewDto);
//        QueryWrapper<OverviewDto> wrapper = getWrapper2(overviewDto);
        return getDeviceBusPumpsVoPage(page, overviewDto);
    }

    private QueryWrapper<OverviewDto> getWrapper2(NewestDto overviewDto) {
        QueryWrapper<OverviewDto> wrapper = new QueryWrapper<>();
        wrapper.like(StringUtils.hasText(overviewDto.getPumpName()), "p.NAME", overviewDto.getPumpName())
                .and(q -> {
                    q.in(!CollectionUtils.isEmpty(overviewDto.getPumpOrGroupIds()), "p.ID")
                            .or()
                            .in(!CollectionUtils.isEmpty(overviewDto.getPumpOrGroupIds()), "pg.ID");
                });
        return wrapper;
    }

    @Override
    public Map<String, List<StatisticsPumpRealVo>> getMapResultRespone(StatisticsRealDto dto, Object o) {
        return getMapResultRespone(dto, o, null);
    }

    @Override
    public Map<String, List<StatisticsPumpRealVo>> getMapResultRespone(StatisticsRealDto dto, Object o, Integer pumpStatisticsType) {
        if (pumpStatisticsType == null) {
            List<StatisticsPumpRealVo> data = JSONObject.parseArray(JSONObject.toJSONString(o), StatisticsPumpRealVo.class);
            Map<String, List<StatisticsPumpRealVo>> collect = data.stream().filter(pumpRealVo -> pumpRealVo.getPName() != null)
                    .collect(Collectors.groupingBy(StatisticsPumpRealVo::getPName));
            for (Map.Entry<String, List<StatisticsPumpRealVo>> entry : collect.entrySet()) {
                List<StatisticsPumpRealVo> value = entry.getValue();
                if (!CollectionUtils.isEmpty(value)) {
                    StatisticsPumpRealVo realVo = value.get(value.size() - 1);
                    StatisticsPumpRealVo vo = new StatisticsPumpRealVo();
                    BeanUtils.copyProperties(realVo, vo);
                    Page<Scada> monitorPage = monitorService.page(new Page<>(1, 1), Wrappers.<Scada>lambdaQuery()
                            .eq(Scada::getCode, realVo.getCode())
                            .orderByDesc(Scada::getScadaTime));
                    if (!CollectionUtils.isEmpty(monitorPage.getRecords())) {
                        List<Scada> monitors = monitorPage.getRecords();
                        vo.setMax(monitors.get(0).getValue());
                        vo.setStartTime(monitors.get(0).getScadaTime());
                        vo.setEndTime(monitors.get(0).getScadaTime());
                        value.add(vo);
                    }

                }
            }
            return collect;
        } else if (pumpStatisticsType.equals(0)) {
            //季度统计
            List<StatisticsPumpRealVo> data = JSONObject.parseArray(JSONObject.toJSONString(o), StatisticsPumpRealVo.class);
            Map<String, List<StatisticsPumpRealVo>> collect = data.stream().filter(pumpRealVo -> pumpRealVo.getPName() != null)
                    .collect(Collectors.groupingBy(StatisticsPumpRealVo::getPName));
            List<StatisticsPumpRealVo> temps = new ArrayList<>();
            for (Map.Entry<String, List<StatisticsPumpRealVo>> entry : collect.entrySet()) {
                List<StatisticsPumpRealVo> value = entry.getValue();
                if (!CollectionUtils.isEmpty(value)) {
                    StatisticsPumpRealVo realVo = value.get(value.size() - 1);
                    StatisticsPumpRealVo vo = new StatisticsPumpRealVo();
                    BeanUtils.copyProperties(realVo, vo);
                    Page<Scada> monitorPage = monitorService.page(new Page<>(1, 1), Wrappers.<Scada>lambdaQuery()
                            .eq(Scada::getCode, realVo.getCode())
                            .orderByDesc(Scada::getScadaTime));
                    if (!CollectionUtils.isEmpty(monitorPage.getRecords())) {
                        List<Scada> monitors = monitorPage.getRecords();
                        vo.setMax(monitors.get(0).getValue());
                        vo.setStartTime(monitors.get(0).getScadaTime());
                        vo.setEndTime(monitors.get(0).getScadaTime());
                        value.add(vo);
                    }
                    temps.addAll(getDataSharding(value, 3));
                }
            }
            if (!CollectionUtils.isEmpty(temps)) {
                Map<String, List<StatisticsPumpRealVo>> map = temps.stream().filter(pumpRealVo -> pumpRealVo.getPName() != null)
                        .collect(Collectors.groupingBy(StatisticsPumpRealVo::getPName));
                return map;
            }
            return null;
        } else if (pumpStatisticsType.equals(1)) {
            //年统计
            List<StatisticsPumpRealVo> data = JSONObject.parseArray(JSONObject.toJSONString(o), StatisticsPumpRealVo.class);
            Map<String, List<StatisticsPumpRealVo>> collect = data.stream().filter(pumpRealVo -> pumpRealVo.getPName() != null)
                    .collect(Collectors.groupingBy(StatisticsPumpRealVo::getPName));
            List<StatisticsPumpRealVo> temps = new ArrayList<>();
            for (Map.Entry<String, List<StatisticsPumpRealVo>> entry : collect.entrySet()) {
                List<StatisticsPumpRealVo> value = entry.getValue();
                if (!CollectionUtils.isEmpty(value)) {
                    StatisticsPumpRealVo realVo = value.get(value.size() - 1);
                    StatisticsPumpRealVo vo = new StatisticsPumpRealVo();
                    BeanUtils.copyProperties(realVo, vo);
                    Page<Scada> monitorPage = monitorService.page(new Page<>(1, 1), Wrappers.<Scada>lambdaQuery()
                            .eq(Scada::getCode, realVo.getCode())
                            .orderByDesc(Scada::getScadaTime));
                    if (!CollectionUtils.isEmpty(monitorPage.getRecords())) {
                        List<Scada> monitors = monitorPage.getRecords();
                        vo.setMax(monitors.get(0).getValue());
                        vo.setStartTime(monitors.get(0).getScadaTime());
                        vo.setEndTime(monitors.get(0).getScadaTime());
                        value.add(vo);
                    }
                    temps.addAll(getDataSharding(value, 12));
                }
            }
            if (!CollectionUtils.isEmpty(temps)) {
                Map<String, List<StatisticsPumpRealVo>> map = temps.stream().filter(pumpRealVo -> pumpRealVo.getPName() != null)
                        .collect(Collectors.groupingBy(StatisticsPumpRealVo::getPName));
                return map;
            }
            return null;
        }
        return null;
    }

    @Override
    public Object reportCount() {
        List<ScadaReport> reports = reportService.list(Wrappers.<ScadaReport>lambdaQuery().eq(ScadaReport::getIsDel, 0));
        List<ScadaReportVo> mapList = overviewMapper.reportCount();
        if (CollectionUtils.isEmpty(reports)) {
            return null;
        }
        List<ScadaReportVo> vos = reports.stream().map(r -> {
            ScadaReportVo vo = new ScadaReportVo();
            BeanUtils.copyProperties(r, vo);
            return vo;
        }).collect(Collectors.toList());
        for (ScadaReportVo report : vos) {
            report.setQuantity("0");
            if (!CollectionUtils.isEmpty(mapList)) {
                for (ScadaReportVo map : mapList) {
                    if (map.getReportLevel().contains(report.getReportLevel())) {
                        report.setQuantity(map.getQuantity());
                    }
                }
            }
        }
        return vos;
    }

    @Override
    public Object runLog(RunLogDto runLogDto, Page page) {
        BasePumpGroup basePumpGroup = new BasePumpGroup();
        BeanUtils.copyProperties(runLogDto, basePumpGroup);
        Page<BasePumpGroup> data = basePumpGroupService.pageList(page, basePumpGroup);
        List<RunLogVo> runLogVos = new ArrayList<>();
        if (!CollectionUtils.isEmpty(data.getRecords())) {
            for (BasePumpGroup record : data.getRecords()) {
                RunLogVo runLogVo = new RunLogVo();
                BeanUtils.copyProperties(record, runLogVo);
                runLogVo.setPowerState(overviewMapper.selectValueByCode(runLogCodes.getPowerState(), record.getId()));
                runLogVo.setInletPipeDiameter(overviewMapper.selectValueByCode(runLogCodes.getInstantaneousFlow(), record.getId()));
                runLogVo.setOperatingFrequency(overviewMapper.selectValueByCode(runLogCodes.getOperatingFrequency(), record.getId()));
                runLogVo.setOperatingCurrent(overviewMapper.selectValueByCode(runLogCodes.getOperatingCurrent(), record.getId()));
                runLogVo.setWaterOutletPressure1(overviewMapper.selectValueByCode(runLogCodes.getWaterOutletPressure1(), record.getId()));
                runLogVo.setWaterOutletPressure2(overviewMapper.selectValueByCode(runLogCodes.getWaterOutletPressure2(), record.getId()));
                runLogVo.setWaterInletPressure(overviewMapper.selectValueByCode(runLogCodes.getWaterInletPressure(), record.getId()));
                runLogVo.setRunTime(overviewMapper.selectValueByCode(runLogCodes.getRunTime(), record.getId()));
                runLogVos.add(runLogVo);
            }
        }
        page.setRecords(runLogVos);
        page.setTotal(data.getTotal());
        if (runLogDto.getIsExport()) {
            ExcelUtils.getListToExcel(RunLogVo.class, runLogVos, "运行日志", "运行日志");
            return null;
        }
        return page;
    }

    @Override
    public List<Allocation> selectPumpByIndex(List<Long> ids, Integer type) {
        return overviewMapper.selectPumpByIndex(ids, type);
    }

    @Override
    public Object waterSupplyOneMonth(String waterType,String yearAndMonth,List<String> codes) {
         return overviewMapper.waterSupplyOneMonth(waterType,yearAndMonth,codes);
    }

    @Override
    public List<WaterSupplyVo> waterSupplyDay(List<String> codes){
         return overviewMapper.waterSupplyDay(codes);

    }
    @Override
    public  List<WaterSupplyVo> waterSupplyYear(List<String> codes) throws ParseException {
        Calendar calendar = Calendar.getInstance();
       int year = calendar.get(Calendar.YEAR);
        String startDate=year+"-01-01";
        SimpleDateFormat dateFormat =new SimpleDateFormat("yyyy-MM-dd");
        String endDate = dateFormat.format(new Date());
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date yearStart= sdf.parse(startDate);
        Date yearEnd=sdf.parse(endDate);
       return overviewMapper.waterSupplyYear(yearStart,yearEnd,codes);
    }

    @Override
    public List<PupmSupplyVo> pumpSupplyDay() {
        return overviewMapper.pumpSupplyDay();
    }

    @Override
    public List<PupmSupplyVo> pumpSupplyYear() {
        return overviewMapper.pumpSupplyYear();
    }

    @Override
    public Object waterSupplyWsReport(String startDate, String endDate,String waterSupplyJin,String waterSupplyChu) {
        List<String> listDate=CalendarHelper.getMonthBetweenDate(startDate,endDate,"");
          List<Map<String,Object>> list=new ArrayList<>();
        listDate.forEach(yearAndMonth->{
            Map<String,Object> map=overviewMapper.waterSupplyMonthReport(yearAndMonth,waterSupplyJin,waterSupplyChu);

          if(map==null){
              map=new HashMap<>();
              map.put("waterChuTotal",0);
              map.put("waterJinTotal",0);
          }
            map.put("month",yearAndMonth);
          list.add(map);
        });
        return list;
    }


    @Override
    public Object waterSupplyReport(String startDate, String endDate,Long waterId,String waterSupplyJin,String waterSupplyChu) {
        List<String> listDate=CalendarHelper.getDayBetweenDate(startDate,endDate,"");
        List<String> listJin=overviewMapper.getWaterAllocation(waterId, waterSupplyJin,"1");
        List<String> listChu= overviewMapper.getWaterAllocation(waterId, waterSupplyChu, "0");
        String strJin=listJin.stream().collect(Collectors.joining(","));
        String strChu=listChu.stream().collect(Collectors.joining(","));
        List<Map<String,Object>> list=new ArrayList<>();
        listDate.forEach(yearAndMonth->{
            Map<String,Object> map=overviewMapper.waterSupplyDayReport(null, null, yearAndMonth, waterId, strJin, strChu);

            if(map==null){
                map=new HashMap<>();
                map.put("waterChuTotal",0);
                map.put("waterJinTotal",0);
            }
            map.put("day",yearAndMonth);
            list.add(map);
        });
        return list;
    }

    @Override
    public Object waterSupplyDealInfo(Long waterId, List<String> codes) {
     List<WaterSupplyVo> list= overviewMapper.waterSupplyDay(codes);
        WaterSupplyVo waterSupplyVo=list.stream().filter(a->a.waterId.equals(waterId)).findFirst().orElse(null);
        Map<String,Object> map=new HashMap<>();
        map.put("waterId",waterSupplyVo.getWaterId());
        map.put("waterName",waterSupplyVo.getWaterName());
        map.put("waterSupplyDay",waterSupplyVo.getWaterSupplyDay());
        map.put("designProcessingCapacity",waterSupplyVo.getDesignProcessingCapacity());
        BigDecimal waterAllocationCount= overviewMapper.getWaterAllocationCount(waterSupplyVo.getWaterId());
        map.put("waterAllocationCount",waterAllocationCount);
        BigDecimal waterAlarmCount= overviewMapper.getWaterAlarmCount(waterSupplyVo.getWaterId());

        BigDecimal waterAlarmAllocationCount= overviewMapper.getWaterAlarmAllocationCount(waterSupplyVo.getWaterId());
        map.put("waterAlarmCount",waterAlarmCount);
        map.put("waterAlarmAllocationCount",waterAlarmAllocationCount);

        return map;


    }

    @Override
    public WaterProductionInfoVo waterProductionInfo(String waterType,String codes,String waterSupplyJin,String waterSupplyChu) {
        WaterProductionInfoVo vo=overviewMapper.getWaterProductInfo(waterType);
        List<ScadaVo> scadaVos = scadaService.selectMonitoringNew(codes);

      String nowData=CalendarHelper.getFormatDate(new Date(),"yyyyMMdd");
        String nowYear=CalendarHelper.getFormatDate(new Date(),"yyyy");

        BigDecimal waterSupplyInDay=new BigDecimal(0);
        BigDecimal waterSupplyOutDay=new BigDecimal(0);
        BigDecimal waterSupplyInYear=new BigDecimal(0);
        BigDecimal waterSupplyOutYear=new BigDecimal(0);

        for (WaterInfoVo waterInfoVo:vo.getWaterInfoVoList()) {
            Long waterId = waterInfoVo.getWaterId();
            List<String> listJin = overviewMapper.getWaterAllocation(waterId, waterSupplyJin, "1");
            List<String> listChu = overviewMapper.getWaterAllocation(waterId, waterSupplyChu, "0");
            String strJin = listJin.stream().collect(Collectors.joining(","));
            String strChu = listChu.stream().collect(Collectors.joining(","));
            Map<String, Object> map = overviewMapper.waterSupplyDayReport(null, null, nowData, waterId, strJin, strChu);
            if (map != null) {
                BigDecimal waterChuTotal = new BigDecimal(map.get("waterChuTotal").toString());
                BigDecimal waterJinTotal = new BigDecimal(map.get("waterJinTotal").toString());
                waterInfoVo.setWaterSupplyInDay(waterJinTotal);
                waterInfoVo.setWaterSupplyOutDay(waterChuTotal);
                waterSupplyInDay = waterSupplyInDay.add(waterJinTotal);
                waterSupplyOutDay = waterSupplyOutDay.add(waterChuTotal);

            }
            Map<String,Object> mapYear=overviewMapper.waterSupplYearReport(nowYear,waterId,strJin,strChu);
            if(mapYear!=null){
                BigDecimal waterYearChuTotal=new BigDecimal(mapYear.get("waterChuTotal").toString()) ;
                BigDecimal waterYearJinTotal=new BigDecimal(mapYear.get("waterJinTotal").toString()) ;
                waterSupplyInYear=waterSupplyInYear.add(waterYearJinTotal);
                waterSupplyOutYear= waterSupplyOutYear.add(waterYearChuTotal);
            }

            List<ScadaVo> scadaVoLists= scadaVos.stream().filter(item->item.getWaterId().equals(waterId)).collect(Collectors.toList());
            waterInfoVo.setScadaVoList(scadaVoLists);
        }
        vo.setWaterSupplyInYear(waterSupplyInYear);
        vo.setWaterSupplyOutYear(waterSupplyOutYear);
        vo.setWaterSupplyInDay(waterSupplyInDay);
        vo.setWaterSupplyOutDay(waterSupplyOutDay);
        return vo;
    }

    @Override
    public Object waterSupplyReportComm(String startDate, String endDate, Integer dateType, Long waterId, String waterSupplyJinAll, String waterSupplyChuAll) {

//        List<String> listJin=overviewMapper.getWaterAllocation(waterId,waterSupplyJinAll);
//        List<String> listChu= overviewMapper.getWaterAllocation(waterId,waterSupplyChuAll);
//        String strJin=listJin.stream().collect(Collectors.joining(","));
//        String strChu=listChu.stream().collect(Collectors.joining(","));
        String formatterStr="yyyy";
       List<String> listDates=new ArrayList<>();
        switch (dateType){
            case 0:
                formatterStr="yyyy-MM-dd HH";
                listDates=CalendarHelper.getHoursBetweenDate(startDate,endDate,formatterStr);
                break;
            case 1:
                formatterStr="yyyy-MM-dd";
              listDates=CalendarHelper.getDayBetweenDate(startDate,endDate,formatterStr);
                break;
            case 2:
                formatterStr="yyyy-MM";
                listDates=CalendarHelper.getMonthBetweenDate(startDate,endDate,formatterStr);
                break;
            case 3:
                listDates=CalendarHelper.getYearBetweenDate(startDate,endDate);
                break;

        }

        List<Map<String,Object>> list=new ArrayList<>();
        String finalFormatterStr = formatterStr;
        listDates.forEach(yearAndMonth->{
            Map<String,Object> map=overviewMapper.waterSupplyCommReport(yearAndMonth, finalFormatterStr,dateType,waterId,null,null);

            if(map==null){
                map=new HashMap<>();
                map.put("waterChuTotal",0);
                map.put("waterJinTotal",0);
            }
            map.put("dateStr",yearAndMonth);
            list.add(map);
        });
        return list;
    }


    public List<Date> getDateListByType(Date time, Integer type) {
        //整个日历调整时间

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(time == null ? new Date() : time);
        List<Date> dates = new ArrayList<>();
        try{
            if (type.equals(FlowConstant.INTEGER_ZERO)) {
                //一个小时
                calendar.set(Calendar.MINUTE, 0);
                calendar.set(Calendar.SECOND, 0);
                calendar.set(Calendar.MILLISECOND, 0);
                Date startTime = calendar.getTime();
                String start = DateUtil.format(calendar.getTime(), "yyyy-MM-dd HH:mm:ss");
                //拉长时间到59分59秒
                calendar.set(Calendar.MINUTE, 59);
                calendar.set(Calendar.SECOND, 59);
                calendar.set(Calendar.MILLISECOND, 999);
                Date endTime = calendar.getTime();
                String end = DateUtil.format(calendar.getTime(), "yyyy-MM-dd HH:mm:ss");
                dates.add(startTime);
                dates.add(endTime);
            } else if (type.equals(FlowConstant.INTEGER_ONE)) {
                //一天
                calendar.set(Calendar.HOUR_OF_DAY, 0);
                calendar.set(Calendar.MINUTE, 0);
                calendar.set(Calendar.SECOND, 0);
                calendar.set(Calendar.MILLISECOND, 0);
                Date startTime = calendar.getTime();
                String start = DateUtil.format(calendar.getTime(), "yyyy-MM-dd HH:mm:ss");
                //拉长时间到59分59秒
                calendar.set(Calendar.HOUR_OF_DAY, 23);
                calendar.set(Calendar.MINUTE, 59);
                calendar.set(Calendar.SECOND, 59);
                calendar.set(Calendar.MILLISECOND, 999);
                Date endTime = calendar.getTime();
                String end = DateUtil.format(calendar.getTime(), "yyyy-MM-dd HH:mm:ss");
                dates.add(startTime);
                dates.add(endTime);
            } else if (type.equals(FlowConstant.INTEGER_TWO)) {
                //一个月
                calendar.set(Calendar.DATE, 1);
                calendar.set(Calendar.HOUR_OF_DAY, 0);
                calendar.set(Calendar.MINUTE, 0);
                calendar.set(Calendar.SECOND, 0);
                calendar.set(Calendar.MILLISECOND, 0);
                Date startTime = calendar.getTime();
                String start = DateUtil.format(calendar.getTime(), "yyyy-MM-dd HH:mm:ss");
                //倒退一个月最后一天时间
                calendar.set(Calendar.DATE, calendar.getActualMaximum(Calendar.DATE));
                calendar.set(Calendar.HOUR_OF_DAY, 23);
                calendar.set(Calendar.MINUTE, 59);
                calendar.set(Calendar.SECOND, 59);
                calendar.set(Calendar.MILLISECOND, 999);
                Date endTime = calendar.getTime();
                dates.add(startTime);
                dates.add(endTime);

            }else if (type.equals(FlowConstant.INTEGER_THREE)) {
                //一个月
                calendar.set(Calendar.DATE, 1);
                calendar.set(Calendar.MONTH, 0);
                calendar.set(Calendar.HOUR_OF_DAY, 0);
                calendar.set(Calendar.MINUTE, 0);
                calendar.set(Calendar.SECOND, 0);
                calendar.set(Calendar.MILLISECOND, 0);
                Date startTime = calendar.getTime();
                String start = DateUtil.format(calendar.getTime(), "yyyy-MM-dd HH:mm:ss");
                //倒退一个月最后一天时间
                calendar.set(Calendar.DATE, 31);
                calendar.set(Calendar.MONTH, 11);
                calendar.set(Calendar.HOUR_OF_DAY, 23);
                calendar.set(Calendar.MINUTE, 59);
                calendar.set(Calendar.SECOND, 59);
                calendar.set(Calendar.MILLISECOND, 999);
                Date endTime = calendar.getTime();
                dates.add(startTime);
                dates.add(endTime);

            }
        }
        catch (Exception e){

        }
        return dates;
    }

    private Collection<? extends StatisticsPumpRealVo> getDataSharding(List<StatisticsPumpRealVo> value, Integer count) {
        List<List<StatisticsPumpRealVo>> lists = subListByCount(value, count);
        List<StatisticsPumpRealVo> finalList = new ArrayList<>();
        for (List<StatisticsPumpRealVo> list : lists) {
            StatisticsPumpRealVo vo = new StatisticsPumpRealVo();
            BeanUtils.copyProperties(list.get(0), vo);
            vo.setEndTime(list.get(list.size() - 1).getEndTime());
            vo.setMax(list.get(list.size() - 1).getMax());
            finalList.add(vo);
        }
        return finalList;
    }

    /**
     * 分隔数组 根据每段数量分段
     *
     * @param data  被分隔的数组
     * @param count 每段数量
     * @return
     */
    public List<List<StatisticsPumpRealVo>> subListByCount(List<StatisticsPumpRealVo> data, int count) {

        List<List<StatisticsPumpRealVo>> result = new ArrayList<>();

        int size = data.size();// 数据长度

        if (size > 0 && count > 0) {

            int segments = size / count;// 商
            /**
             * 1.整除，  即分隔为segments     段
             * 2.除不尽，即分隔为segments + 1 段
             */
            segments = size % count == 0 ? segments : segments + 1; // 段数

            List<StatisticsPumpRealVo> cutList = null;// 每段List

            for (int i = 0; i < segments; i++) {
                if (i == segments - 1) {
                    cutList = data.subList(count * i, size);
                } else {
                    cutList = data.subList(count * i, count * (i + 1));
                }
                result.add(cutList);
            }
        } else {
            result.add(data);
        }
        return result;
    }
}
