package com.ho.business.service.impl;


import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.ho.business.common.StaticData;
import com.ho.business.constant.DeviceTypeConstant;
import com.ho.business.entity.Device;
import com.ho.business.entity.IncomeTotal;
import com.ho.business.entity.Station;
import com.ho.business.service.*;
import com.ho.business.vo.req.DeviceReqVO;
import com.ho.business.vo.req.cockpit.CockpitReqVO;
import com.ho.business.vo.resp.*;
import com.ho.business.vo.resp.InverterResp.ModelInverter;
import com.ho.business.vo.resp.InverterResp.ModelNewInverter;
import com.ho.business.vo.resp.cockpit.*;
import com.ho.common.tools.constant.CommonConstant;
import com.ho.common.tools.constant.RedisKeyConstant;
import com.ho.common.tools.entity.SimpleUser;
import com.ho.common.tools.exception.BaseResponseCode;
import com.ho.common.tools.exception.BusinessException;
import com.ho.common.tools.service.RedisService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

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

/**
 * @Description 驾驶舱实现
 * Author yule
 * Date 2023/1/10 17:00
 */
@Service
@Slf4j
public class CockpitServiceImpl implements CockpitService {

    @Autowired
    StationService stationService;

    @Autowired
    RedisService redisService;

    @Autowired
    IncomeTotalService incomeTotalService;

    @Autowired
    DeviceService deviceService;

    @Autowired
    PvStationService pvStationService;

    @Autowired
    PictureService pictureService;

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

    //二氧化碳到煤的转换系数
    @Value("${energy.co2ToCole}")
    BigDecimal co2ToCole;
    //二氧化碳到树的转换系数
    @Value("${energy.co2ToTree}")
    BigDecimal co2ToTree;
    //二氧化碳到汽油的转换系数
    @Value("${energy.co2ToGasoline}")
    BigDecimal co2ToGasoline;
    //树到平方公里的转换系数
    @Value("${energy.treeToSquareKilometer}")
    BigDecimal treeToSquareKilometer;
    //碳排放因子
    @Value("${inverter.co2Factor}")
    BigDecimal co2Factor;

    @Override
    public StationSummaryRespVO getSummary(SimpleUser user) {
        if (CommonConstant.ZERO.equals(user.getGroupId())) {
            throw new BusinessException(BaseResponseCode.COCKPIT_NOT_SEE);
        }
        List<Station> stations = getStations(user);
        //获取到电站id集合
        List<Integer> stationIds = stations.stream().map(s -> {
            return s.getId();
        }).collect(Collectors.toList());

        List<Device> devices = new ArrayList<>();
        for (Integer stationId : stationIds) {
            DeviceReqVO reqVO = new DeviceReqVO();
            reqVO.setStationId(stationId);
            reqVO.setDeviceType(DeviceTypeConstant.INVERTER_PREFIX);
            List<DeviceRespVO> list = deviceService.getList(reqVO);
            devices.addAll(list);
        }
        //总装机容量
        BigDecimal totalCapacity = BigDecimal.ZERO;
        for (Station station : stations) {
            totalCapacity = totalCapacity.add(station.getCapacity());
        }
        //当前总功率 各个逆变器的有功功率之和
        BigDecimal currentPower = BigDecimal.ZERO;
        //当日发电量
        BigDecimal dailyPowerGeneration = BigDecimal.ZERO;
        //累计发电量
        BigDecimal cumulativePowerGeneration = BigDecimal.ZERO;

        for (Device device : devices) {
            String inverterRedisKey = device.getDeviceType() + ":" + device.getStationId() + ":" + device.getSrcId();
            ModelInverter modelInverter = new ModelInverter();
            if (redisService.hasKey(inverterRedisKey)) {
                Map<Object, Object> inverterMap = redisService.hgetall(inverterRedisKey);
                if (inverterMap != null) {
                    modelInverter = JSON.parseObject(JSON.toJSONString(inverterMap), ModelInverter.class);
                }
                BigDecimal acActivePower = modelInverter.getAcActivePower() == null ? BigDecimal.ZERO : modelInverter.getAcActivePower();
                currentPower = currentPower.add(acActivePower);

                BigDecimal modelDailyPowerGeneration = modelInverter.getDailyPowerGeneration() == null ? BigDecimal.ZERO : modelInverter.getDailyPowerGeneration();
                dailyPowerGeneration = dailyPowerGeneration.add(modelDailyPowerGeneration);

                //累计发电量  cumulativePowerGeneration
                BigDecimal modelInverterCumulativePowerGeneration = modelInverter.getCumulativePowerGeneration() == null ? BigDecimal.ZERO : modelInverter.getCumulativePowerGeneration();
                cumulativePowerGeneration = cumulativePowerGeneration.add(modelInverterCumulativePowerGeneration);
            }
        }
        Date today = new Date();
        String startDayTime = DateUtil.format(today, CommonConstant.DATE_YMD);
        String endDayTime = DateUtil.format(today, CommonConstant.DATE_YMD);
        //当日总收益
        BigDecimal dailyProfit = BigDecimal.ZERO;
        List<IncomeTotal> dailyList = incomeTotalService.getByStations(stationIds, startDayTime, endDayTime);
        if (dailyList.isEmpty()) {
            dailyProfit = BigDecimal.ZERO;
        } else {
            for (IncomeTotal incomeTotal : dailyList) {
                dailyProfit = dailyProfit.add(incomeTotal.getTotalFee());
            }
        }

        //本月开始时间
        String begin = DateUtil.format(DateUtil.beginOfMonth(new Date()), CommonConstant.DATE_YMD);
        String endDayTimes = DateUtil.format(today, CommonConstant.DATE_YMD);
        //月发电量
        BigDecimal monthlyPowerGeneration = BigDecimal.ZERO;
        //当月总收益
        BigDecimal monthlyProfit = BigDecimal.ZERO;
        List<IncomeTotal> monthIncomeTotalList = incomeTotalService.getByStations(stationIds, begin, endDayTimes);
        if (monthIncomeTotalList.isEmpty()) {
            monthlyPowerGeneration = BigDecimal.ZERO;
            monthlyProfit = BigDecimal.ZERO;
        } else {
            for (IncomeTotal incomeTotal : monthIncomeTotalList) {
                monthlyProfit = monthlyProfit.add(incomeTotal.getTotalFee());
                monthlyPowerGeneration = monthlyPowerGeneration.add(new BigDecimal(incomeTotal.getEle()));
            }
        }
        String startTime = DateUtil.format(DateUtil.beginOfYear(today), CommonConstant.DATE_YMD);
        String endTime = DateUtil.format(today, CommonConstant.DATE_YMD);
        //今年总收益(今年开始到昨天)
        BigDecimal yearlyProfit = BigDecimal.ZERO;
        //年发电量
        BigDecimal yearlyPowerGeneration = BigDecimal.ZERO;
        List<IncomeTotal> yearIncomeTotalList = incomeTotalService.getByStations(stationIds, startTime, endTime);
        if (yearIncomeTotalList.isEmpty()) {
            yearlyProfit = BigDecimal.ZERO;
            yearlyPowerGeneration = BigDecimal.ZERO;
        } else {
            for (IncomeTotal incomeTotal : yearIncomeTotalList) {
                yearlyProfit = yearlyProfit.add(incomeTotal.getTotalFee());
                yearlyPowerGeneration = yearlyPowerGeneration.add(new BigDecimal(incomeTotal.getEle()));
            }
        }
        //创建返回对象
        StationSummaryRespVO vo = new StationSummaryRespVO();
        vo.setCurrentPower(currentPower);
        vo.setCumulativePowerGeneration(cumulativePowerGeneration);
        vo.setDailyPowerGeneration(dailyPowerGeneration);
        vo.setDailyProfit(dailyProfit);
        vo.setMonthlyProfit(monthlyProfit);
        vo.setMonthlyPowerGeneration(monthlyPowerGeneration);
        vo.setYearlyProfit(yearlyProfit);
        vo.setYearlyPowerGeneration(yearlyPowerGeneration);
        vo.setTotalCapacity(totalCapacity);
        return vo;
    }

    @Override
    public ConditionMonitoringRespVO getConditionMonitoring(SimpleUser user) {
        //分组id为0不能看驾驶舱
        if (CommonConstant.ZERO.equals(user.getGroupId())) {
            throw new BusinessException(BaseResponseCode.COCKPIT_NOT_SEE);
        }
        List<Station> stations = getStations(user);
        //创建返回值
        ConditionMonitoringRespVO vo = new ConditionMonitoringRespVO();
        if (stations == null || stations.isEmpty()) {
            return vo;
        }
        //获取到电站id集合
        List<Integer> stationIds = stations.stream().map(s -> {
            return s.getId();
        }).collect(Collectors.toList());

        //离线电站数
        Integer offlineStation = 0;
        //离线设备数
        Integer offlineDevice = 0;

        //遍历电站id查询每个电站下的topology数据
        // 这个站下面所有的 逆变器 都离线了，这个站离线
        for (Integer stationId : stationIds) {
            List<DeviceRespVO> intervals = deviceService.selectByStation(stationId);
            //todo 过滤掉电站,接入点,间隔
            intervals = intervals.stream().filter(s-> {
                if (CommonConstant.ZERO.equals(s.getPid()) || CommonConstant.ZERO.equals(s.getSrcId())) {
                    return false;
                }
                String deviceName = s.getDeviceName();
                return !deviceName.contains(CommonConstant.INTERVAL);
            }).collect(Collectors.toList());
            //设备总数量数量
            int size = intervals.size();
            //统计技术
            int count = 0;
            for (DeviceRespVO interval : intervals) {
                //判断设备是否在线
                boolean onLine = deviceService.isOnLine(interval);
                if (!onLine){
                    offlineDevice++;
                    count++;
                }
            }
            if (size == count){
                offlineStation++;
            }
        }
        //查询设备离线个数
  /*      List<DeviceRespVO> devices = deviceService.selectByGroup(user.getGroupId());
        for (DeviceRespVO device : devices) {
            Integer status = device.getStatus();
            //设备状态为 0 1 2 都为设备离线状态
            if (CommonConstant.DEVICE.UNKNOWN_STATUS.equals(status)
                    || CommonConstant.DEVICE.ON_CONNECTION_STATUS.equals(status)
                    || CommonConstant.DEVICE.CONNECTION_TIMED_OUT_STATUS.equals(status)) {
                offlineDevice++;
            }
        }*/
        //查询集团的设备总数
        List<DeviceRespVO> deviceRespVOS = deviceService.selectByGroup(user.getGroupId());
        //todo 过滤掉电站,接入点,间隔
        deviceRespVOS = deviceRespVOS.stream().filter(s-> {
            if (CommonConstant.ZERO.equals(s.getPid()) || CommonConstant.ZERO.equals(s.getSrcId())) {
                return false;
            }
            String deviceName = s.getDeviceName();
            return !deviceName.contains(CommonConstant.INTERVAL);
        }).collect(Collectors.toList());
        vo.setTotalStation(stations.size());
        vo.setOfflineStation(offlineStation);
        BigDecimal total = new BigDecimal(deviceRespVOS.size());
        Integer onlineDevice = total.intValue() - offlineDevice;
        vo.setOnlineDevice(onlineDevice);
        vo.setDeviceCount(deviceRespVOS.size());
        vo.setOfflineDevice(offlineDevice);
        if (deviceRespVOS.size() != 0) {
            vo.setOnlineDeviceRate(new BigDecimal(onlineDevice).divide(total, 2, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal("100")));
        } else {
            vo.setOnlineDeviceRate(BigDecimal.ZERO);
        }
        //todo 故障个数暂时设置为0
        vo.setFaultStation(0);
        return vo;
    }


    @Override
    public List<RevenueStatisticsRespVO> getRevenueStatistics(SimpleUser user) {
        //分组id为0不能看驾驶舱
        if (CommonConstant.ZERO.equals(user.getGroupId())) {
            throw new BusinessException(BaseResponseCode.COCKPIT_NOT_SEE);
        }
        String redisKey = RedisKeyConstant.REVENUE_STATISTICS + user.getGroupId();
        List<RevenueStatisticsRespVO> list = (List<RevenueStatisticsRespVO>)redisService.get(redisKey);
        return list;
    }

    @Override
    public List<TotalPowerGenerationRespVO> getTotalPowerGenerations(CockpitReqVO vo, SimpleUser user) {
        //分组id为0不能看驾驶舱
        if (CommonConstant.ZERO.equals(user.getGroupId())) {
            throw new BusinessException(BaseResponseCode.COCKPIT_NOT_SEE);
        }

        List<Station> stations = getStations(user);
        //获取到电站id集合
        List<Integer> stationIds = stations.stream().map(s -> {
            return s.getId();
        }).collect(Collectors.toList());
        //根据电站List查询
        //创建返回值对象集合
        List<TotalPowerGenerationRespVO> list = new ArrayList<>();
        //月度
        if (CommonConstant.MONTH.equals(vo.getType())) {

            //查询月度是当年的开始时间
            String startDayTime = DateUtil.format(DateUtil.beginOfYear(new Date()), CommonConstant.DATE_YMD);
            String endDayTime = DateUtil.format(new Date(), CommonConstant.DATE_YMD);
            List<IncomeTotal> eleMonthList = incomeTotalService.getByStations(stationIds, startDayTime, endDayTime);
            //把数据放入集合中
            List<StatisticsRespVO> statisticsRespVOList = new ArrayList<>();
            for (IncomeTotal incomeTotal : eleMonthList) {
                StatisticsRespVO statistics = new StatisticsRespVO();
                statistics.setDate(incomeTotal.getDataDate());
                statistics.setDigital(new BigDecimal(incomeTotal.getEle()));
                statisticsRespVOList.add(statistics);
            }

            for (int i = 0; i < 12; i++) {
                TotalPowerGenerationRespVO totalPowerGeneration = new TotalPowerGenerationRespVO();
                String date = String.valueOf(i + 1);
                if (date.length() == 1) {
                    date = 0 + date;
                }
                totalPowerGeneration.setData(date);
                //遍历查询结果,进行累加
                BigDecimal powerGeneration = BigDecimal.ZERO;
                for (StatisticsRespVO statisticsRespVO : statisticsRespVOList) {
                    //获取到月份的日期字符串
                    String month = statisticsRespVO.getDate().substring(5, 7);
                    //将相同月份的进行累加
                    if (date.equals(month)) {
                        powerGeneration = powerGeneration.add(statisticsRespVO.getDigital());
                    }
                }
                totalPowerGeneration.setPowerGeneration(powerGeneration);
                list.add(totalPowerGeneration);
            }
        }
        //年度
        else if (CommonConstant.YEAR.equals(vo.getType())) {
            //查询mysql数据库所有的数据
            List<IncomeTotal> incomeTotals = incomeTotalService.getByStations(stationIds, null, null);
            if (incomeTotals.isEmpty()) {
                return new ArrayList<>();
            }
            List<StatisticsRespVO> statisticsRespVOList = new ArrayList<>();
            for (IncomeTotal incomeTotal : incomeTotals) {
                StatisticsRespVO statisticsRespVO = new StatisticsRespVO();
                statisticsRespVO.setDate(incomeTotal.getDataDate());
                statisticsRespVO.setDigital(new BigDecimal(incomeTotal.getEle()));
                statisticsRespVOList.add(statisticsRespVO);
            }
            //根据年份就行分组
            Map<String, List<StatisticsRespVO>> yearMap = statisticsRespVOList.stream().map(s -> {
                String year = s.getDate().substring(0, 4);
                s.setDate(year);
                return s;
            }).collect(Collectors.groupingBy(StatisticsRespVO::getDate));

            //获取到map中的键值对
            Set<Map.Entry<String, List<StatisticsRespVO>>> yearSet = yearMap.entrySet();
            //遍历set,对数据进行赋值,累加
            for (Map.Entry<String, List<StatisticsRespVO>> entry : yearSet) {
                TotalPowerGenerationRespVO totalPowerGeneration = new TotalPowerGenerationRespVO();
                totalPowerGeneration.setData(entry.getKey());
                BigDecimal powerGeneration = BigDecimal.ZERO;
                List<StatisticsRespVO> value = entry.getValue();
                for (StatisticsRespVO statisticsRespVO : value) {
                    powerGeneration = powerGeneration.add(statisticsRespVO.getDigital());
                }
                totalPowerGeneration.setPowerGeneration(powerGeneration);
                list.add(totalPowerGeneration);
            }
        }
        return list;

    }

    @Override
    public List<ProportionOfPowerRespVO> getProportionOfPowerGeneration(SimpleUser user) {
        //分组id为0不能看驾驶舱
        if (CommonConstant.ZERO.equals(user.getGroupId())) {
            throw new BusinessException(BaseResponseCode.COCKPIT_NOT_SEE);
        }

        List<Station> stations = getStations(user);
        //获取到电站id集合
        /*List<Integer> stationIds = stations.stream().map(s -> {
            return s.getId();
        }).collect(Collectors.toList());*/
        //创建返回集合
        List<ProportionOfPowerRespVO> proportionList = new ArrayList<>();
        //发电量总和 Long型
        BigDecimal sumPowerGeneration = BigDecimal.ZERO;

        //原来的
        //遍历电站id查询每个电站下的topology数据
        /*for (Integer stationId : stationIds) {
            //创建查询pv表参数
            PvEnergyQuery query = new PvEnergyQuery();
            query.setStationId(stationId);
            query.setType(CommonConstant.PV_ENERGY.DAY_GENERATION);
            BigDecimal powerGeneration = pvEnergyService.selectSumByInfo(query);
            if (powerGeneration == null){
                powerGeneration = BigDecimal.ZERO;
            }
            //当日发电量
            BigDecimal dailyPowerGeneration = BigDecimal.ZERO;
            List<Topology> intervals = getIntervals(stationId);
            for (Topology topology : intervals) {
                String inverterRedisKey = RedisKeyConstant.INVERTER_HW + topology.getStationId()
                        + ":" + topology.getSrcId();
                if (redisService.hasKey(inverterRedisKey)) {
                    InverterHw inverterHw = (InverterHw) redisService.get(inverterRedisKey);
                    dailyPowerGeneration = dailyPowerGeneration.add(new BigDecimal(inverterHw.getDailyPowerGeneration()));
                }
            }
            //创建返回对象
            ProportionOfPowerRespVO proportionOfPowerRespVO = new ProportionOfPowerRespVO();
            proportionOfPowerRespVO.setStationId(stationId);
            proportionOfPowerRespVO.setPowerGeneration(powerGeneration.add(dailyPowerGeneration));
            proportionList.add(proportionOfPowerRespVO);
            sum = sum.add(proportionOfPowerRespVO.getPowerGeneration());
        }*/

        //2023-01-16 fan update 改为从逆变器的缓存数据中汇总各站的累计发电量
        for (Station station : stations) {
            // 累计发电量 cumulativePowerGeneration
            //电站维度的累计发电量
            BigDecimal stationPowerGeneration = BigDecimal.ZERO;
            ProportionOfPowerRespVO proportion = new ProportionOfPowerRespVO();
            proportion.setStationId(station.getId());
            proportion.setStationName(station.getName());
            //查站下逆变器
            List<DeviceRespVO> intervals = pvStationService.getIntervalsByStationId(station.getId());
            for (DeviceRespVO deviceRespVO : intervals) {
                String inverterRedisKey = deviceRespVO.getDeviceType() + ":" + deviceRespVO.getStationId()
                        + ":" + deviceRespVO.getSrcId();
                ModelInverter modelInverter = new ModelInverter();
                //逆变器有缓存才累加,否则认为没有数据
                if (redisService.hasKey(inverterRedisKey)) {
                    Map<Object, Object> inverterMap = redisService.hgetall(inverterRedisKey);
                    if (inverterMap != null) {
                        modelInverter = JSON.parseObject(JSON.toJSONString(inverterMap), ModelInverter.class);
                    }
                    BigDecimal cumulativePowerGeneration = modelInverter.getCumulativePowerGeneration() == null ? BigDecimal.ZERO : modelInverter.getCumulativePowerGeneration();
                    stationPowerGeneration = stationPowerGeneration.add(cumulativePowerGeneration);
                    //总发电量,持续累加
                    sumPowerGeneration = sumPowerGeneration.add(cumulativePowerGeneration);
                }
            }
            //循环完累加电站级发电量
            proportion.setPowerGeneration(stationPowerGeneration);
            proportionList.add(proportion);
            //占比后续等全部累加完毕再计算
        }
        //计算占比并给电站名称赋值 总发电量 sumPowerGeneration
        //总发电量转为Bigdecimal
        BigDecimal sumPowerBigDecimal = sumPowerGeneration;
        for (ProportionOfPowerRespVO proportionOfPowerRespVO : proportionList) {
            //不为0,才计算每个电站的占比
            if (sumPowerBigDecimal.compareTo(BigDecimal.ZERO) != 0) {
                //电站发电量
                BigDecimal stationPowerBigDecimal = proportionOfPowerRespVO.getPowerGeneration();
                BigDecimal divide = stationPowerBigDecimal.divide(sumPowerBigDecimal, 4, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal("100")).setScale(2, BigDecimal.ROUND_HALF_UP);
                ;
                proportionOfPowerRespVO.setProportion(divide);
            }
        }
        return proportionList;
    }

    @Override
    public List<RevenueRespVO> getRevenueRanking(SimpleUser user) {
        //分组id为0不能看驾驶舱
        if (CommonConstant.ZERO.equals(user.getGroupId())) {
            throw new BusinessException(BaseResponseCode.COCKPIT_NOT_SEE);
        }

        List<Station> stations = getStations(user);
        //获取到电站id集合
        List<Integer> stationIds = stations.stream().map(s -> {
            return s.getId();
        }).collect(Collectors.toList());
        //创建返回集合
        List<RevenueRespVO> revenueRespVOList = new ArrayList<>();

        //遍历电站id查询每个电站下的topology数据
        for (Integer stationId : stationIds) {
            List<Integer> stationList = new ArrayList<>();
            stationList.add(stationId);
            List<IncomeTotal> totalFeeList = incomeTotalService.getByStations(stationList, null, null);
            BigDecimal profit = BigDecimal.ZERO;
            if (!totalFeeList.isEmpty()) {
                for (IncomeTotal incomeTotal : totalFeeList) {
                    profit = profit.add(incomeTotal.getTotalFee());
                }
            }
            Station station = stationService.selectById(stationId);
            //创建返回对象
            RevenueRespVO revenueRespVO = new RevenueRespVO();
            revenueRespVO.setStationId(stationId);
            revenueRespVO.setTotalProfit(profit);
            revenueRespVO.setStationName(station.getName());

            revenueRespVOList.add(revenueRespVO);
        }
        //根据收益排序
        revenueRespVOList = revenueRespVOList.stream().sorted((s1, s2) -> {
            return s2.getTotalProfit().subtract(s1.getTotalProfit()).intValue();
        }).collect(Collectors.toList());
        return revenueRespVOList;
    }

    @Override
    public List<StationMapRespVO> getStationMap(SimpleUser user) {
        if (CommonConstant.ZERO.equals(user.getGroupId())) {
            throw new BusinessException(BaseResponseCode.COCKPIT_NOT_SEE);
        }
        //创建返回值集合
        List<StationMapRespVO> list = new ArrayList<>();
        List<Station> stations = getStations(user);
        if (stations == null || stations.isEmpty()) {
            return list;
        }

        Map<String, List<Station>> provincesMap = stations.stream().sorted(Comparator.comparing(Station::getName)).collect(Collectors.groupingBy(s -> {
            return s.getProvince().replace(CommonConstant.ChineseProvinces.PROVINCE, "").replace(CommonConstant.ChineseProvinces.CITY, "");
        }));
        //创建返回值集合
        provincesMap.forEach((k, v) -> {
            StationMapRespVO stationMapRespVO = new StationMapRespVO();
            stationMapRespVO.setCount(v.size());
            stationMapRespVO.setStationAddr(k);
            list.add(stationMapRespVO);
        });
        return list;
    }

    @Override
    public CumulativeRespVO getCumulative(SimpleUser user) {
        if (CommonConstant.ZERO.equals(user.getGroupId())) {
            throw new BusinessException(BaseResponseCode.COCKPIT_NOT_SEE);
        }
        List<Station> stations = getStations(user);

        CumulativeRespVO respVO = new CumulativeRespVO();
        if (stations == null || stations.isEmpty()) {
            return respVO;
        }
        //获取到电站id集合
        List<Integer> stationIds = stations.stream().map(s -> {
            return s.getId();
        }).collect(Collectors.toList());

        //累计收益
        log.info("累计收益.start:" + System.currentTimeMillis());
        BigDecimal totalCumulative = incomeTotalService.getSumIncome(user.getGroupId());
        //找出最早的电站的创建时间
        Date createTime = null;
        for (Station station : stations) {
            Date stationCreateTime = station.getCreateTime();
            if (createTime == null) {
                createTime = stationCreateTime;
            } else {
                //比较两个时间大小(前 - 后)
                int compare = DateUtil.compare(createTime, stationCreateTime);
                if (compare > 0) {
                    createTime = stationCreateTime;
                }
            }
        }
        log.info("累计收益.end:" + System.currentTimeMillis());
        //安全运行天数(今天时间 - 创建时间)
        long safeOperationDays = 0;
        if (createTime == null) {
            safeOperationDays = 0;
        } else {
            safeOperationDays = DateUtil.between(createTime, new Date(), DateUnit.DAY);
        }


        //累计发电量
        BigDecimal powerGeneration = BigDecimal.ZERO;
        //从缓存中获取
        String redisKey = RedisKeyConstant.COCKPIT.PV_POWER_GENERATION + user.getGroupId();
        if (redisService.hasKey(redisKey)) {
            powerGeneration = (BigDecimal) redisService.get(redisKey);
        }
        //计算等值数据
        BigDecimal co2Reductions = powerGeneration.multiply(co2Factor);
        // co2/一棵树每年的吸收系数 = 减伐的树
        BigDecimal treeReductions = co2Reductions.divide(co2ToTree, 2, BigDecimal.ROUND_HALF_UP);
        // co2/每升汽油燃烧排放的二氧化碳 = 节约石油
        BigDecimal petroleumReductions = co2Reductions.divide(co2ToGasoline, 2, BigDecimal.ROUND_HALF_UP);


        respVO.setCumulative(totalCumulative);
        respVO.setSafeOperationDays((int) safeOperationDays);
        respVO.setPvPowerGeneration(powerGeneration);
        respVO.setCo2Reductions(co2Reductions);
        respVO.setCoalReductions(powerGeneration.multiply(co2Factor).multiply(co2ToCole));
        respVO.setTreeReductions(treeReductions);
        respVO.setPetroleumReductions(petroleumReductions);
        respVO.setForestReductions(treeReductions.divide(treeToSquareKilometer, 2, BigDecimal.ROUND_HALF_UP));
        return respVO;
    }

    @Override
    public List<StationOperationRespVO> getStationOperation(SimpleUser user) {
        if (CommonConstant.ZERO.equals(user.getGroupId())) {
            throw new BusinessException(BaseResponseCode.COCKPIT_NOT_SEE);
        }
        List<Station> stations = getStations(user);

        //创建返回结果集
        List<StationOperationRespVO> list = new ArrayList<>();

        //遍历电站id查询每个电站下的topology数据
        for (Station station : stations) {

            // 累计发电量 cumulativePowerGeneration
            //电站维度的累计发电量
            BigDecimal stationPowerGeneration = BigDecimal.ZERO;
            ProportionOfPowerRespVO proportion = new ProportionOfPowerRespVO();
            proportion.setStationId(station.getId());
            proportion.setStationName(station.getName());
            //查站下逆变器
            List<DeviceRespVO> intervals = pvStationService.getIntervalsByStationId(station.getId());
            for (DeviceRespVO interval : intervals) {
                String inverterRedisKey = interval.getDeviceType() + ":" + interval.getStationId()
                        + ":" + interval.getSrcId();
                ModelNewInverter modelInverter = new ModelNewInverter();
                //逆变器有缓存才累加,否则认为没有数据
                if (redisService.hasKey(inverterRedisKey)) {
                    Map<Object, Object> inverterMap = redisService.hgetall(inverterRedisKey);
                    if (inverterMap != null) {
                        modelInverter = JSON.parseObject(JSON.toJSONString(inverterMap), ModelNewInverter.class);
                    }
                    //累计发电量
                    BigDecimal cumulativePowerGeneration = BigDecimal.ZERO;
                    if(modelInverter.getCumulativePowerGeneration()!=null && modelInverter.getCumulativePowerGeneration().getValue()!=null){
                        cumulativePowerGeneration = modelInverter.getCumulativePowerGeneration().getValue();
                    }
                    stationPowerGeneration = stationPowerGeneration.add(cumulativePowerGeneration);
                }
            }

            //占比后续等全部累加完毕再计算
            //创建返回对象
            StationOperationRespVO respVO = new StationOperationRespVO();
            respVO.setStationId(station.getId());
            respVO.setStationName(station.getName());
            respVO.setPowerGeneration(stationPowerGeneration);
            if (station.getCreateTime() != null) {
                long safeOperationDays = DateUtil.between(station.getCreateTime(), new Date(), DateUnit.DAY);
                respVO.setSafeOperationDays((int) safeOperationDays);
            }


            list.add(respVO);
        }

        list = list.stream().sorted((s1, s2) -> {
            int i = s2.getPowerGeneration().subtract(s1.getPowerGeneration()).multiply(new BigDecimal("100")).intValue();
            return i;
        }).collect(Collectors.toList());
        return list;
    }

    @Override
    public GroupDataRespVo getGroupData(SimpleUser user) {
        if (CommonConstant.ZERO.equals(user.getGroupId())) {
            throw new BusinessException(BaseResponseCode.COCKPIT_NOT_SEE);
        }
        List<Station> stations = getStations(user);

        //创建返回对象
        GroupDataRespVo groupDataRespVo = new GroupDataRespVo();
        if (stations == null || stations.isEmpty()) {
            return groupDataRespVo;
        }
        //获取到电站id集合
        List<Integer> stationIds = stations.stream().map(s -> {
            return s.getId();
        }).collect(Collectors.toList());

        List<DeviceRespVO> deviceRespVOS = new ArrayList<>();
        for (Integer stationId : stationIds) {
            List<DeviceRespVO> intervals = pvStationService.getIntervalsByStationId(stationId);
            deviceRespVOS.addAll(intervals);
        }
        //总装机容量(实时)
        BigDecimal pvCapacity = BigDecimal.ZERO;
        for (Station station : stations) {
            pvCapacity = pvCapacity.add(station.getCapacity());
        }
        //当前总功率 各个逆变器的有功功率之和
        BigDecimal pvCurrentPower = BigDecimal.ZERO;
        //累计发电量
        BigDecimal pvDailyPowerGeneration = BigDecimal.ZERO;

        for (DeviceRespVO deviceRespVO : deviceRespVOS) {
            String inverterRedisKey = deviceRespVO.getDeviceType() + ":" + deviceRespVO.getStationId() + ":" + deviceRespVO.getSrcId();
            ModelNewInverter modelInverter = new ModelNewInverter();
            if (redisService.hasKey(inverterRedisKey)) {
                Map<Object, Object> inverterMap = redisService.hgetall(inverterRedisKey);
                if (inverterMap != null) {
                    modelInverter = JSON.parseObject(JSON.toJSONString(inverterMap), ModelNewInverter.class);
                }
                BigDecimal acActivePower = BigDecimal.ZERO;
                if(modelInverter.getAcActivePower()!=null && modelInverter.getAcActivePower().getValue()!=null){
                    acActivePower = modelInverter.getAcActivePower().getValue();
                }
                pvCurrentPower = pvCurrentPower.add(acActivePower);

                //累计发电量  cumulativePowerGeneration
                BigDecimal modelInverterCumulativePowerGeneration = BigDecimal.ZERO;
                if(modelInverter.getDailyPowerGeneration() !=null &&modelInverter.getDailyPowerGeneration() .getValue()!=null){
                    modelInverterCumulativePowerGeneration = modelInverter.getDailyPowerGeneration() .getValue();
                }
                pvDailyPowerGeneration = pvDailyPowerGeneration.add(modelInverterCumulativePowerGeneration);
            }
        }
        //光伏装机量为固定值
        groupDataRespVo.setPvCapacity(CommonConstant.TongHeCockpit.PvCapacity);
        // 光伏当前总功率 = 光伏装机容量(客服规定值) /实时的电站装机容量(实时值) * 逆变器的总功率之和(实时值)
        if (!BigDecimal.ZERO.equals(pvCapacity)) {
            pvCurrentPower = CommonConstant.TongHeCockpit.PvCapacity.divide(pvCapacity, 4, BigDecimal.ROUND_HALF_UP)
                    .multiply(pvCurrentPower);
            groupDataRespVo.setPvCurrentPower(pvCurrentPower);
            // 光伏当前累计发电量(Y) = 光伏装机容量(客服规定值) / 实时的电站装机容量(实时值) * 逆变器的当天发电量之和(实时值)
            pvDailyPowerGeneration = CommonConstant.TongHeCockpit.PvCapacity.divide(pvCapacity, 4, BigDecimal.ROUND_HALF_UP)
                    .multiply(pvDailyPowerGeneration);
        }
        //从缓中获取光伏累计发电量
        String pvKey = RedisKeyConstant.COCKPIT.PV_POWER_GENERATION + user.getGroupId();
        BigDecimal pvPowerGeneration = CommonConstant.TongHeCockpit.PvPowerGeneration;
        //光伏累计发电量 = 光伏当前累计发电量(Y) + 固定值(1.71GWh)
        pvPowerGeneration = pvDailyPowerGeneration.add(pvPowerGeneration);
        redisService.set(pvKey, pvPowerGeneration);
        groupDataRespVo.setPvPowerGeneration(pvPowerGeneration);


        //储能装机容量(固定值)
        groupDataRespVo.setEnergyCapacity(CommonConstant.TongHeCockpit.EnergyCapacity);
        //储能实时总功率(根据当前时间段取值)
        Map<String, String> map = StaticData.map;
        AtomicReference<String> number = new AtomicReference<>();
        //当前时间
        Date date = new Date();
        String format = DateUtil.format(date, CommonConstant.DATE_YMD);
        //遍历查询到取值范围
        for (Map.Entry<String, String> m : map.entrySet()) {
            String[] split = m.getKey().split("-");
            boolean in = DateUtil.isIn(date, DateUtil.parse(format + " " + split[0], CommonConstant.DATE), DateUtil.parse(format + " " + split[1], CommonConstant.DATE));
            if (in) {
                number.set(m.getValue());
                break;
            }
        }
        //从数值范围中随机取值
        String[] split = number.get().split("~");
        double energyCurrentPower = (Math.random() * (Double.valueOf(split[1]) - (Double.valueOf(split[0]))) + (Double.valueOf(split[0])));
        groupDataRespVo.setEnergyCurrentPower(new BigDecimal(energyCurrentPower).multiply(new BigDecimal("1000")));
        //从缓存中获取储能累计放电量
        String energyKey = RedisKeyConstant.COCKPIT.ENERGY_POWER_GENERATION + user.getGroupId();
        if (redisService.hasKey(energyKey)) {
            BigDecimal energyPowerGeneration = (BigDecimal) redisService.get(energyKey);
            groupDataRespVo.setEnergyPowerGeneration(energyPowerGeneration);
        } else {
            groupDataRespVo.setEnergyPowerGeneration(CommonConstant.TongHeCockpit.EnergyPowerGeneration);
            redisService.set(energyKey, CommonConstant.TongHeCockpit.EnergyPowerGeneration);
        }

        //充电桩装机容量为固定值
        groupDataRespVo.setChargePileCapacity(CommonConstant.TongHeCockpit.ChargePileCapacity);
        //充电桩当前总功率为1000 - 5000 的随机数
        Random random = new Random();
        int chargePileCurrentPower = 1000 + random.nextInt(4001);
        groupDataRespVo.setChargePileCurrentPower(new BigDecimal(chargePileCurrentPower));
        //从缓存中获取充电桩累计放电量
        String chargePileKey = RedisKeyConstant.COCKPIT.CHARGE_PILE_POWER_GENERATION + user.getGroupId();
        if (redisService.hasKey(chargePileKey)) {
            BigDecimal chargePileGeneration = (BigDecimal) redisService.get(chargePileKey);
            groupDataRespVo.setChargePilePowerGeneration(chargePileGeneration);
        } else {
            groupDataRespVo.setChargePilePowerGeneration(CommonConstant.TongHeCockpit.ChargePilePowerGeneration);
            redisService.set(chargePileKey, CommonConstant.TongHeCockpit.ChargePilePowerGeneration);
        }

        return groupDataRespVo;

    }

    @Override
    public CapacityProportionResp capacityProportion(SimpleUser user) {

        //光伏装机容量
        BigDecimal pvCapacity = CommonConstant.TongHeCockpit.PvCapacity;
        //储能装机容量
        BigDecimal energyCapacity = CommonConstant.TongHeCockpit.EnergyCapacity;
        //充电桩装机容量
        BigDecimal chargePileCapacity = CommonConstant.TongHeCockpit.ChargePileCapacity;

        //累计总和
        BigDecimal total = pvCapacity.add(energyCapacity).add(chargePileCapacity);
        //创建返回对象
        CapacityProportionResp capacityProportionResp = new CapacityProportionResp();
        //计算装机占比
        if (!total.equals(BigDecimal.ZERO)) {
            capacityProportionResp.setPvProportion(pvCapacity.divide(total, 4, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal("100")));
            capacityProportionResp.setEnergyProportion(energyCapacity.divide(total, 4, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal("100")));
            capacityProportionResp.setChargePileProportion(chargePileCapacity.divide(total, 4, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal("100")));
        }
        return capacityProportionResp;
    }

    @Override
    public List<StationRespVO> monitoringStation(SimpleUser user) {
        List<Station> stations = stationService.selectByGroupId(user.getGroupId());
        List<StationRespVO> list = stations.stream().map(s -> {
            StationRespVO stationRespVO = new StationRespVO();
            BeanUtils.copyProperties(s, stationRespVO);
            List<PictureRespVO> pictureRespVOS = pictureService.selectBySrcId(s.getId());
            //过滤文档
            pictureRespVOS = pictureRespVOS.stream().filter(pictureRespVO -> {
                String type = pictureRespVO.getPictureType();
                return CommonConstant.PICTURE_TYPE.contains(type);
            }).collect(Collectors.toList());
            stationRespVO.setPictureResps(pictureRespVOS);
            return stationRespVO;
        }).collect(Collectors.toList());
        return list;
    }

    @Override
    public void getRevenueStatistics() {
        //查询所有电站
        List<Station> stations = stationService.selectAll();

        Map<Integer, List<Station>> groupStation = stations.stream().collect(Collectors.groupingBy(Station::getGroupId));

        for (Map.Entry<Integer, List<Station>> map : groupStation.entrySet()) {

            //获取到电站id集合
            List<Integer> stationIds = map.getValue().stream().map(s -> {
                return s.getId();
            }).collect(Collectors.toList());

            //本月开始时间
            Date today = new Date();
            String begin = DateUtil.format(DateUtil.beginOfMonth(new Date()), CommonConstant.DATE_YMD);
            String endDayTimes = DateUtil.format(today, CommonConstant.DATE_YMD);

            List<IncomeTotal> monthIncomeTotalList = incomeTotalService.getByStations(stationIds, begin, endDayTimes);
            List<StatisticsRespVO> totalFeeList = new ArrayList<>();
            for (IncomeTotal incomeTotal : monthIncomeTotalList) {
                StatisticsRespVO statisticsRespVO = new StatisticsRespVO();
                statisticsRespVO.setDigital(incomeTotal.getTotalFee());
                statisticsRespVO.setDate(incomeTotal.getDataDate());
                totalFeeList.add(statisticsRespVO);
            }
            //上一个月
            String beginTime = DateUtil.format(DateUtil.beginOfMonth(DateUtil.lastMonth()), CommonConstant.DATE_YMD);
            String endTime = DateUtil.format(DateUtil.endOfMonth(DateUtil.lastMonth()), CommonConstant.DATE_YMD);
            List<IncomeTotal> lastMonthList = incomeTotalService.getByStations(stationIds, beginTime, endTime);
            List<StatisticsRespVO> lastTotalFeeList = new ArrayList<>();
            for (IncomeTotal incomeTotal : lastMonthList) {
                StatisticsRespVO statisticsRespVO = new StatisticsRespVO();
                statisticsRespVO.setDigital(incomeTotal.getTotalFee());
                statisticsRespVO.setDate(incomeTotal.getDataDate());
                lastTotalFeeList.add(statisticsRespVO);
            }

            //创建返回值集合
            List<RevenueStatisticsRespVO> list = new ArrayList<>();
            //添加月份日期
            for (int i = 1; i <= 31; i++) {
                RevenueStatisticsRespVO vo = new RevenueStatisticsRespVO();
                String date = String.valueOf(i);
                if (date.length() == 1) {
                    date = 0 + date;
                }
                vo.setData(date);
                BigDecimal nowProfit = BigDecimal.ZERO;
                BigDecimal beforeProfit = BigDecimal.ZERO;
                for (StatisticsRespVO statisticsRespVO : totalFeeList) {
                    String substring = statisticsRespVO.getDate().substring(8, 10);
                    if (date.equals(substring)) {
                        nowProfit = nowProfit.add(statisticsRespVO.getDigital());
                        vo.setNowProfit(nowProfit);
                    }
                }
                for (StatisticsRespVO statisticsRespVO : lastTotalFeeList) {
                    String substring = statisticsRespVO.getDate().substring(8, 10);
                    if (date.equals(substring)) {
                        beforeProfit = beforeProfit.add(statisticsRespVO.getDigital());
                        vo.setBeforeProfit(beforeProfit);
                    }
                }
                list.add(vo);
            }
            redisService.set(RedisKeyConstant.REVENUE_STATISTICS + map.getKey(), list);
        }
    }

    /**
     * 通过登录人查询到集团下所有电站
     *
     * @param user
     * @return 集团下所有电站
     */
    private List<Station> getStations(SimpleUser user) {
        if (CommonConstant.ZERO.equals(user.getGroupId())) {
            throw new BusinessException(BaseResponseCode.COCKPIT_NOT_SEE);
        }
        //根据分组id查询到该集团所有电站
        List<Station> stations = stationService.selectByGroupId(user.getGroupId());
        return stations;
    }

    private List<DeviceRespVO> getIntervals(Integer stationId) {
        DeviceReqVO deviceReqVO = new DeviceReqVO();
        deviceReqVO.setStationId(stationId);
        deviceReqVO.setDeviceType(DeviceTypeConstant.INVERTER_HW);
        List<DeviceRespVO> list = deviceService.getList(deviceReqVO);
        return list;
    }

}
