package com.ho.business.service.impl;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.ho.business.constant.OperationEvaluationConstant;
import com.ho.business.entity.YcValue;
import com.ho.business.service.IncomeTotalService;
import com.ho.business.service.ReportFormService;
import com.ho.business.service.YcValueService;
import com.ho.business.vo.req.reduceemissions.ReduceEmissionsReqVO;
import com.ho.business.vo.req.report.ReportReqVO;
import com.ho.business.vo.resp.ReportFromReqVo;
import com.ho.business.vo.resp.report.CurrentMonthReportRespVO;
import com.ho.business.vo.resp.report.HistoryReportRespVO;
import com.ho.common.tools.constant.CommonConstant;
import com.ho.common.tools.util.BigDecimalUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author gyan
 * @desc: 报表
 * @DateTime: 2022/11/9 9:20
 */
@Service
public class ReportFormServiceImpl implements ReportFormService {

    @Autowired
    YcValueService ycValueService;

    @Autowired
    IncomeTotalService incomeTotalService;

    @Autowired
    BigDecimalUtil bigDecimalUtil;

    @Override
    public List<ReportFromReqVo> getReportForm(ReduceEmissionsReqVO vo) {
        List<Integer> typeList = new ArrayList();
        //日充电量
        typeList.add(OperationEvaluationConstant.EnergyStorage.charge);
        //日放电量
        typeList.add(OperationEvaluationConstant.EnergyStorage.disCharge);
        //日收益
        typeList.add(OperationEvaluationConstant.EnergyStorage.dayProfit);
        //尖日充电量
        typeList.add(OperationEvaluationConstant.EnergyStorage.tipChargeNum);
        //峰日充电量
        typeList.add(OperationEvaluationConstant.EnergyStorage.peakChargeNum);
        //平日充电量
        typeList.add(OperationEvaluationConstant.EnergyStorage.dailyChargeNum);
        //谷日充电量
        typeList.add(OperationEvaluationConstant.EnergyStorage.valleyChargeNum);
        //尖日放电量
        typeList.add(OperationEvaluationConstant.EnergyStorage.tipDischargeNum);
        //峰日放电量
        typeList.add(OperationEvaluationConstant.EnergyStorage.peakDischargeNum);
        //平日放电量
        typeList.add(OperationEvaluationConstant.EnergyStorage.dailyDischargeNUm);
        //谷日放电量
        typeList.add(OperationEvaluationConstant.EnergyStorage.valleyDischargeNum);

        //封装查询参数
        Map<String, Object> map = new HashMap<>();
        map.put("beginTime", vo.getBeginTime());
        map.put("endTime", vo.getEndTime());
        // stationId 和 stationIds 二选一
        if (vo.getStationIds() != null && !vo.getStationIds().isEmpty()) {
            map.put("stationIds", vo.getStationIds());
        } else {
            map.put("stationId", vo.getStationId());
        }
        map.put("typeList", typeList);

        List<YcValue> ycValuesList = ycValueService.getListByCondition(map);
        List<ReportFromReqVo> reportFromReqVoList = new ArrayList<>();
        //集合转换成map集合 以day进行分组
        Map<String, List<YcValue>> ycValuesMap = ycValuesList.stream().collect(Collectors.groupingBy(YcValue::getDay));
        ycValuesMap.forEach((k, y) -> {
            ReportFromReqVo reportFromReqVo = new ReportFromReqVo();
            reportFromReqVo.setDay(k);
            for (YcValue ycValue : y) {
                //总充电量
                if (OperationEvaluationConstant.EnergyStorage.charge.equals(ycValue.getType())) {
                    reportFromReqVo.setTotalChargeCapacity(ycValue.getDigital());
                    continue;
                }
                //总放电量
                if (OperationEvaluationConstant.EnergyStorage.disCharge.equals(ycValue.getType())) {
                    reportFromReqVo.setTotalDischargeCapacity(ycValue.getDigital());
                    continue;
                }
                //收益
                if (OperationEvaluationConstant.EnergyStorage.dayProfit.equals(ycValue.getType())) {
                    reportFromReqVo.setTotalProfit(ycValue.getDigital());
                    continue;
                }
                //尖日充电量
                if (OperationEvaluationConstant.EnergyStorage.tipChargeNum.equals(ycValue.getType())) {
                    reportFromReqVo.setTipCharge(ycValue.getDigital());
                    continue;
                }
                //峰日充电量
                if (OperationEvaluationConstant.EnergyStorage.peakChargeNum.equals(ycValue.getType())) {
                    reportFromReqVo.setPeakCharge(ycValue.getDigital());
                    continue;
                }
                //平日充电量
                if (OperationEvaluationConstant.EnergyStorage.dailyChargeNum.equals(ycValue.getType())) {

                    reportFromReqVo.setDailyCharge(ycValue.getDigital());
                    continue;
                }
                //谷日充电量
                if (OperationEvaluationConstant.EnergyStorage.valleyChargeNum.equals(ycValue.getType())) {

                    reportFromReqVo.setValleyCharge(ycValue.getDigital());
                    continue;
                }
                //尖日放电量
                if (OperationEvaluationConstant.EnergyStorage.tipDischargeNum.equals(ycValue.getType())) {

                    reportFromReqVo.setTipDischarge(ycValue.getDigital());
                    continue;
                }
                //峰日放电量
                if (OperationEvaluationConstant.EnergyStorage.peakDischargeNum.equals(ycValue.getType())) {
                    reportFromReqVo.setPeakDischarge(ycValue.getDigital());
                    continue;
                }
                //平日放电量
                if (OperationEvaluationConstant.EnergyStorage.dailyDischargeNUm.equals(ycValue.getType())) {

                    reportFromReqVo.setDailyDischarge(ycValue.getDigital());
                    continue;
                }
                //谷日放电量
                if (OperationEvaluationConstant.EnergyStorage.valleyDischargeNum.equals(ycValue.getType())) {
                    reportFromReqVo.setValleyDischarge(ycValue.getDigital());
                    continue;
                }
            }
            if (reportFromReqVo.getTotalChargeCapacity() == null) {
                reportFromReqVo.setTotalDischargeCapacity(BigDecimal.ZERO);
            }
            if (reportFromReqVo.getTotalDischargeCapacity() == null) {
                reportFromReqVo.setTotalDischargeCapacity(BigDecimal.ZERO);
            }
            if (reportFromReqVo.getTotalProfit() == null) {
                reportFromReqVo.setTotalProfit(BigDecimal.ZERO);
            }
            if (reportFromReqVo.getTipCharge() == null) {
                reportFromReqVo.setTipCharge(BigDecimal.ZERO);
            }
            if (reportFromReqVo.getPeakCharge() == null) {
                reportFromReqVo.setPeakCharge(BigDecimal.ZERO);
            }
            if (reportFromReqVo.getDailyCharge() == null) {
                reportFromReqVo.setDailyCharge(BigDecimal.ZERO);
            }
            if (reportFromReqVo.getValleyCharge() == null) {
                reportFromReqVo.setValleyCharge(BigDecimal.ZERO);
            }
            if (reportFromReqVo.getTipDischarge() == null) {
                reportFromReqVo.setTipDischarge(BigDecimal.ZERO);
            }
            if (reportFromReqVo.getPeakDischarge() == null) {
                reportFromReqVo.setPeakDischarge(BigDecimal.ZERO);
            }
            if (reportFromReqVo.getDailyDischarge() == null) {
                reportFromReqVo.setDailyDischarge(BigDecimal.ZERO);
            }
            if (reportFromReqVo.getValleyDischarge() == null) {
                reportFromReqVo.setValleyDischarge(BigDecimal.ZERO);
            }
            reportFromReqVoList.add(reportFromReqVo);
        });

        List<ReportFromReqVo> collect = reportFromReqVoList.stream().sorted(Comparator.comparing(ReportFromReqVo::getDay)).collect(Collectors.toList());

        return collect;
    }

    @Override
    public void export(ReduceEmissionsReqVO vo) {
    }

    @Override
    public List<CurrentMonthReportRespVO> getCurrentMonthReport(BigDecimal capacity, ReportReqVO vo) {
        //如果传过来的有年月，则根据传过来的年月进行查询
        DateTime beginTime = null;
        Date endTime = null;
        if (vo.getTime() != null) {
            //拼接开始时间
            String startTimestamp = vo.getTime() + CommonConstant.START_TIMESTAMP;
            beginTime = DateUtil.parse(startTimestamp, CommonConstant.DATE_YMD);
            //计算出结束时间
            endTime = DateUtil.endOfMonth(beginTime);
        } else {
            //结束时间
            endTime = new Date();
            //获取到当月的开始时间
            beginTime = DateUtil.beginOfMonth(endTime);
        }
        //根据电站查找收益累计表中的数据
        List<CurrentMonthReportRespVO> currentMonthReportRespVOList = incomeTotalService.getCurrentMonthReportByStationId(vo.getStationId(), beginTime, endTime);

        //创建一个累计对象
        CurrentMonthReportRespVO reportRespVO = new CurrentMonthReportRespVO();
        reportRespVO.setDate("总计");
        BigDecimal powerGenerationSum = BigDecimal.ZERO;
        BigDecimal incomeSum = BigDecimal.ZERO;
        BigDecimal eleSum = BigDecimal.ZERO;
        BigDecimal equivalentHoursSum = BigDecimal.ZERO;
        //计算等效小时(装机容量/发电量)
        for (CurrentMonthReportRespVO currentMonthReportRespVO : currentMonthReportRespVOList) {
            BigDecimal powerGeneration = currentMonthReportRespVO.getPowerGeneration()==null?BigDecimal.ZERO:currentMonthReportRespVO.getPowerGeneration();
            if (capacity != null) {
                if (powerGeneration.intValue() != 0) {
                    BigDecimal equivalentHours = powerGeneration.divide(capacity, 2, BigDecimal.ROUND_HALF_UP);
                    currentMonthReportRespVO.setEquivalentHours(equivalentHours);
                }
                //计算累计
                powerGenerationSum = powerGenerationSum.add(powerGeneration);
            } else {
                currentMonthReportRespVO.setEquivalentHours(BigDecimal.ZERO);
            }
            //todo 上网电量为0
            currentMonthReportRespVO.setIncome(BigDecimal.ZERO);

            //计算累计
            if (currentMonthReportRespVO.getIncome() != null) {
                incomeSum = incomeSum.add(currentMonthReportRespVO.getIncome());
            }
            if (currentMonthReportRespVO.getEle() != null) {
                eleSum = eleSum.add(currentMonthReportRespVO.getEle());
            }
            if (currentMonthReportRespVO.getEquivalentHours() != null) {
                equivalentHoursSum = equivalentHoursSum.add(currentMonthReportRespVO.getEquivalentHours());
            }
        }
        //给累计对象赋值
        reportRespVO.setPowerGeneration(powerGenerationSum);
        reportRespVO.setEquivalentHours(equivalentHoursSum);
        reportRespVO.setEle(eleSum);
        reportRespVO.setIncome(incomeSum);
        currentMonthReportRespVOList.add(reportRespVO);
        return currentMonthReportRespVOList;
    }

    @Override
    public List<HistoryReportRespVO> getHistoryReport(ReportReqVO vo) {
        //创建返回值对象
        List<HistoryReportRespVO> list = new ArrayList<>();

        //获取查询日期类型()
        String dateType = vo.getDateType();
        Integer stationId = vo.getStationId();
        if (CommonConstant.DAY.equals(dateType)) {
            DateTime begin = DateUtil.beginOfDay(DateUtil.parse(vo.getBeginTime(), CommonConstant.DATE_YMD));
            DateTime end = DateUtil.endOfDay(DateUtil.parse(vo.getEndTime(), CommonConstant.DATE_YMD));
            //是否存在电站
            if (stationId != null) {
                list = incomeTotalService.getHistoryReport(stationId, null, begin, end);
            } else {
                list = incomeTotalService.getHistoryReport(null, vo.getGroupId(), begin, end);
            }
        } else if (CommonConstant.MONTH.equals(dateType)) {
            DateTime begin = DateUtil.beginOfMonth(DateUtil.parse(vo.getBeginTime(), CommonConstant.DATE_YM));
            DateTime end = DateUtil.endOfMonth(DateUtil.parse(vo.getEndTime(), CommonConstant.DATE_YM));
            //根据时间查询每天的数据
            List<HistoryReportRespVO> dayList = new ArrayList<>();
            //是否存在电站
            if (stationId != null) {
                dayList = incomeTotalService.getHistoryReport(stationId, null, begin, end);
            } else {
                dayList = incomeTotalService.getHistoryReport(null, vo.getGroupId(), begin, end);
            }
            //根据数据的日期的月份分组
            Map<String, List<HistoryReportRespVO>> monthMap = new HashMap<>();
            for (HistoryReportRespVO historyReportRespVO : dayList) {
                String dateMonth = historyReportRespVO.getDate().substring(0, 7);
                if (monthMap.get(dateMonth) == null) {
                    List<HistoryReportRespVO> monthList = new ArrayList<>();
                    monthList.add(historyReportRespVO);
                    monthMap.put(dateMonth, monthList);
                } else {
                    List<HistoryReportRespVO> monthList = monthMap.get(dateMonth);
                    monthList.add(historyReportRespVO);
                    monthMap.put(dateMonth, monthList);
                }
            }
            //遍历分组的集合进行累加计算
            List<HistoryReportRespVO> monthList = list;
            monthMap.forEach((key, value) -> {
                HistoryReportRespVO historyReportRespVO = new HistoryReportRespVO();
                historyReportRespVO.setDate(key);
                BigDecimal eleTotalFee = BigDecimal.ZERO;
                BigDecimal incomeFee = BigDecimal.ZERO;
                BigDecimal totalFee = BigDecimal.ZERO;
                BigDecimal powerGeneration = BigDecimal.ZERO;
                for (HistoryReportRespVO reportRespVO : value) {
                    incomeFee = reportRespVO.getIncomeFee() != null ? incomeFee.add(reportRespVO.getIncomeFee()) : incomeFee;

                    eleTotalFee = reportRespVO.getEleTotalFee() != null ? eleTotalFee.add(reportRespVO.getEleTotalFee()) : eleTotalFee;

                    totalFee = reportRespVO.getTotalFee() != null ? totalFee.add(reportRespVO.getTotalFee()) : totalFee;

                    powerGeneration = reportRespVO.getPowerGeneration() != null ? powerGeneration.add(reportRespVO.getPowerGeneration()) : powerGeneration;
                }
                historyReportRespVO.setTotalFee(totalFee);
                historyReportRespVO.setIncomeFee(incomeFee);
                historyReportRespVO.setEleTotalFee(eleTotalFee);
                historyReportRespVO.setPowerGeneration(powerGeneration);
                monthList.add(historyReportRespVO);
            });

        } else if (CommonConstant.YEAR.equals(dateType)) {
            DateTime begin = DateUtil.beginOfYear(DateUtil.parse(vo.getBeginTime(), CommonConstant.DATE_Y));
            DateTime end = DateUtil.endOfYear(DateUtil.parse(vo.getEndTime(), CommonConstant.DATE_Y));
            //根据时间查询每天的数据
            //根据时间查询每天的数据
            List<HistoryReportRespVO> dayList = new ArrayList<>();
            //是否存在电站
            if (stationId != null) {
                dayList = incomeTotalService.getHistoryReport(stationId, null, begin, end);
            } else {
                dayList = incomeTotalService.getHistoryReport(null, vo.getGroupId(), begin, end);
            }
            //根据数据的日期的月份分组
            Map<String, List<HistoryReportRespVO>> yearMap = new HashMap<>();
            for (HistoryReportRespVO historyReportRespVO : dayList) {
                String dateMonth = historyReportRespVO.getDate().substring(0, 4);
                if (yearMap.get(dateMonth) == null) {
                    List<HistoryReportRespVO> monthList = new ArrayList<>();
                    monthList.add(historyReportRespVO);
                    yearMap.put(dateMonth, monthList);
                } else {
                    List<HistoryReportRespVO> monthList = yearMap.get(dateMonth);
                    monthList.add(historyReportRespVO);
                    yearMap.put(dateMonth, monthList);
                }
            }
            //遍历分组的集合进行累加计算
            List<HistoryReportRespVO> yearList = list;
            yearMap.forEach((key, value) -> {
                HistoryReportRespVO historyReportRespVO = new HistoryReportRespVO();
                historyReportRespVO.setDate(key);
                BigDecimal eleTotalFee = BigDecimal.ZERO;
                BigDecimal incomeFee = BigDecimal.ZERO;
                BigDecimal totalFee = BigDecimal.ZERO;
                BigDecimal powerGeneration = BigDecimal.ZERO;
                for (HistoryReportRespVO reportRespVO : value) {
                    incomeFee = reportRespVO.getIncomeFee() != null ? incomeFee.add(reportRespVO.getIncomeFee()) : incomeFee;

                    eleTotalFee = reportRespVO.getEleTotalFee() != null ? eleTotalFee.add(reportRespVO.getEleTotalFee()) : eleTotalFee;

                    totalFee = reportRespVO.getTotalFee() != null ? totalFee.add(reportRespVO.getTotalFee()) : totalFee;

                    powerGeneration = reportRespVO.getPowerGeneration() != null ? powerGeneration.add(reportRespVO.getPowerGeneration()) : powerGeneration;
                }
                historyReportRespVO.setTotalFee(totalFee);
                historyReportRespVO.setIncomeFee(incomeFee);
                historyReportRespVO.setEleTotalFee(eleTotalFee);
                historyReportRespVO.setPowerGeneration(powerGeneration);
                yearList.add(historyReportRespVO);
            });

        }
        //计算累计对象
        //创建累计对象
        HistoryReportRespVO historyReportRespVO = new HistoryReportRespVO();
        historyReportRespVO.setDate("总计");
        BigDecimal eleTotalFeeSum = BigDecimal.ZERO;
        BigDecimal incomeFeeSum = BigDecimal.ZERO;
        BigDecimal totalFeeSum = BigDecimal.ZERO;
        BigDecimal powerGenerationSum = BigDecimal.ZERO;
        for (HistoryReportRespVO reportRespVO : list) {

            incomeFeeSum = reportRespVO.getIncomeFee() != null ? incomeFeeSum.add(reportRespVO.getIncomeFee()) : incomeFeeSum;

            eleTotalFeeSum = reportRespVO.getEleTotalFee() != null ? eleTotalFeeSum.add(reportRespVO.getEleTotalFee()) : eleTotalFeeSum;

            totalFeeSum = reportRespVO.getTotalFee() != null ? totalFeeSum.add(reportRespVO.getTotalFee()) : totalFeeSum;

            powerGenerationSum = reportRespVO.getPowerGeneration() != null ? powerGenerationSum.add(reportRespVO.getPowerGeneration()) : powerGenerationSum;
        }

        //累计对象赋值
        historyReportRespVO.setIncomeFee(incomeFeeSum);
        historyReportRespVO.setEleTotalFee(eleTotalFeeSum);
        historyReportRespVO.setTotalFee(totalFeeSum);
        historyReportRespVO.setPowerGeneration(powerGenerationSum);

        list.add(historyReportRespVO);
        return list;
    }


}
