package com.njcn.harmonic.service.upload.impl;


import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.njcn.common.pojo.enums.common.DataStateEnum;
import com.njcn.common.pojo.exception.BusinessException;
import com.njcn.harmonic.mapper.upload.PmsTemProcessReportMapper;
import com.njcn.harmonic.pojo.param.upload.PmsTemUserParam;
import com.njcn.harmonic.pojo.po.upload.PmsTemProcessApproval;
import com.njcn.harmonic.pojo.po.upload.PmsTemProcessReport;
import com.njcn.harmonic.pojo.po.upload.PmsTemProcessTrackPO;
import com.njcn.harmonic.pojo.po.upload.PmsTemUserPO;
import com.njcn.harmonic.service.upload.IPmsTemProcessReportService;
import com.njcn.harmonic.service.upload.IPmsTemProcessTrackService;
import com.njcn.harmonic.service.upload.IPmsTemUserService;
import com.njcn.harmonic.service.upload.PmsTemProcessApprovalService;
import com.njcn.user.api.DeptFeignClient;
import com.njcn.user.pojo.vo.PvTerminalTreeVO;
import com.njcn.web.enums.GWSendEnum;
import com.njcn.web.pojo.param.SendParam;
import com.njcn.web.utils.GwSendUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

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

/**
 * <p>
 * 电能质量全过程月报 服务实现类
 * </p>
 *
 * @author cdf
 * @since 2024-10-09
 */
@Service
@RequiredArgsConstructor
public class PmsTemProcessReportServiceImpl extends ServiceImpl<PmsTemProcessReportMapper, PmsTemProcessReport> implements IPmsTemProcessReportService {


    private final DeptFeignClient deptFeignClient;

    private final IPmsTemUserService iPmsTemUserService;

    private final IPmsTemProcessTrackService iPmsTemProcessTrackService;

    private final PmsTemProcessApprovalService pmsTemProcessApprovalService;


    @Override
    public Boolean upGw(List<String> ids) {
        LambdaQueryWrapper<PmsTemProcessReport> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.in(PmsTemProcessReport::getObjId,ids);
        List<PmsTemProcessReport> pmsTemProcessReportList = this.list(lambdaQueryWrapper);
        if(CollUtil.isEmpty(pmsTemProcessReportList)){
            throw new BusinessException("查询用户临时档案数据为空");
        }

        List<List<PmsTemProcessReport>> list = CollUtil.split(pmsTemProcessReportList,100);
        for(int i=0;i<list.size();i++){
            SendParam sendParam = new SendParam();
            if(i==0){
                sendParam.setIsAppend("0");
            }else if(i==list.size()-1){
                sendParam.setIsAppend("2");
            }else {
                sendParam.setIsAppend("1");
            }
            sendParam.setStats(list.get(i));
            Map<String, String> sendRes = GwSendUtil.newSend(sendParam, GWSendEnum.MONTH_REPORT_CREATE);
            List<String> TemProcessTrackPOIds = list.get(i).stream().map(PmsTemProcessReport::getObjId).collect(Collectors.toList());
            int count = GwSendUtil.returnInfoMsg(TemProcessTrackPOIds,sendRes);
            System.out.println("上送成功,上送成功返回"+count+"条");
            if(count == list.get(i).size()){
                LambdaUpdateWrapper<PmsTemProcessReport> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
                lambdaUpdateWrapper.set(PmsTemProcessReport::getUploadStatus,1).in(PmsTemProcessReport::getObjId,ids);
                this.update(lambdaUpdateWrapper);
            }
        }
        return true;
    }

    @Override
    public List<PmsTemProcessReport> getList(PmsTemUserParam.QueryPmsTemUserParam param) {

        LambdaQueryWrapper<PmsTemProcessReport> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(PmsTemProcessReport::getStatisticalDate,DateUtil.format(DateUtil.parse(param.getSearchBeginTime(), DatePattern.NORM_DATE_PATTERN),DatePattern.NORM_MONTH_PATTERN));
        return this.list(lambdaQueryWrapper);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean dayCalReport(String date) {

        DateTime dateTime = DateUtil.parse(date,DatePattern.NORM_DATE_PATTERN);
        DateTime beginTime = DateUtil.beginOfMonth(dateTime);
        DateTime endTime = DateUtil.endOfMonth(dateTime);
        String statisticalDate = DateUtil.format(dateTime,"yyyy-MM");
        List<PmsTemProcessReport> pmsTemProcessReportList = new ArrayList<>();

        List<PvTerminalTreeVO> data = deptFeignClient.allDeptList().getData();

        List<PvTerminalTreeVO> collect = data.stream().filter(temp -> Objects.equals(temp.getLevel(), 2))
                .peek(item -> {
                    item.setLevel(2);
                    item.setChildren(getChildren(item, data));
                }).collect(Collectors.toList());
        collect.forEach(province->{

            PmsTemProcessReport report = new PmsTemProcessReport();
            report.setProvinceOrg(province.getCode());
            report.setProvinceOrgName(province.getName());
            report.setCityOrg("/");
            report.setCityOrgName("/");
            report.setStatisticalLevel("3");
            report.setStatisticalType("02");
            report.setStatisticalDate(statisticalDate);


            report.setUploadStatus(DataStateEnum.DELETED.getCode());



            Integer monthCount = iPmsTemUserService.lambdaQuery()
                    .eq(PmsTemUserPO::getProvinceOrg, province.getCode())
                    .between(PmsTemUserPO::getReleaseTime, beginTime, endTime).count();
            List<PmsTemUserPO> list = iPmsTemUserService.lambdaQuery()
                    .eq(PmsTemUserPO::getProvinceOrg, province.getCode())
                    .list();
            report.setNewUserNum(monthCount);
            report.setNewUserCount(list.size());

            List<String> userIds = list.stream().map(PmsTemUserPO::getObjId).collect(Collectors.toList());
            if(CollectionUtils.isEmpty(userIds)){

                report.setReportAuditNum(0);
                report.setReportAuditCount(0);
                report.setApprovalAuditNum(0);
                report.setApprovalAuditCount(0);
                report.setApprovalProblemNum(0);
                report.setApprovalProblemCount(0);
                report.setApprovalRectificationProblemNum(0);
                report.setApprovalRectificationProblemCount(0);
                report.setTestRunUserCount(0);
                report.setTestRunOvUserNum(0);
                report.setTestRunOvUserRate(BigDecimal.valueOf(0.00));
                report.setRunUserCount(0);
                report.setRunOvUserNum(0);
                report.setRunOvUserRate(BigDecimal.valueOf(0.00));


            }else {
                //规划可研阶段
                Integer auditCount = iPmsTemProcessTrackService.lambdaQuery()
                        .in(PmsTemProcessTrackPO::getTempUserDossierId, userIds)
//                        .eq(PmsTemProcessTrackPO::getProStage,"01")
                        .between(PmsTemProcessTrackPO::getAuditTime, beginTime, endTime)
                        .count();

                Integer allAuditCount = iPmsTemProcessTrackService.lambdaQuery()
                        .in(PmsTemProcessTrackPO::getTempUserDossierId, userIds)
//                        .eq(PmsTemProcessTrackPO::getProStage,"01")
//                        .between(PmsTemProcessTrackPO::getAuditFinalTime, beginTime, endTime)
                        .isNotNull(PmsTemProcessTrackPO::getAuditTime)
                        .count();
                report.setReportAuditNum(auditCount);
                report.setReportAuditCount(allAuditCount);

                //规划验收
                Integer approvalAuditNum = iPmsTemProcessTrackService.lambdaQuery()
                        .in(PmsTemProcessTrackPO::getTempUserDossierId, userIds)
//                        .eq(PmsTemProcessTrackPO::getProStage,"01")
                        .between(PmsTemProcessTrackPO::getApprovalTime, beginTime, endTime)
                        .count();
                Integer approvalAuditCount = iPmsTemProcessTrackService.lambdaQuery()
                        .in(PmsTemProcessTrackPO::getTempUserDossierId, userIds)
//                        .eq(PmsTemProcessTrackPO::getProStage,"01")
//                        .between(PmsTemProcessTrackPO::getAuditFinalTime, beginTime, endTime)
                        .isNotNull(PmsTemProcessTrackPO::getApprovalTime)
                        .count();
                report.setApprovalAuditNum(approvalAuditNum);
                report.setApprovalAuditCount(approvalAuditCount);

                Integer approvalProblemNum = iPmsTemProcessTrackService.lambdaQuery()
                        .in(PmsTemProcessTrackPO::getTempUserDossierId, userIds)
                        .eq(PmsTemProcessTrackPO::getApprovalResult,"01")
//                        .eq(PmsTemProcessTrackPO::getProStage,"01")
                        .between(PmsTemProcessTrackPO::getApprovalTime, beginTime, endTime)
                        .count();
                Integer approvalProblemCount = iPmsTemProcessTrackService.lambdaQuery()
                        .in(PmsTemProcessTrackPO::getTempUserDossierId, userIds)
                        .eq(PmsTemProcessTrackPO::getApprovalResult,"01")
//                        .eq(PmsTemProcessTrackPO::getProStage,"01")
//                        .between(PmsTemProcessTrackPO::getAuditFinalTime, beginTime, endTime)
                        .isNotNull(PmsTemProcessTrackPO::getApprovalTime)
                        .count();
                report.setApprovalProblemNum(approvalProblemNum);
                report.setApprovalProblemCount(approvalProblemCount);

                Integer approvalRectificationProblemNum = pmsTemProcessApprovalService.lambdaQuery()
                        .in(PmsTemProcessApproval::getTempUserDossierId, userIds)
                        .eq(PmsTemProcessApproval::getRectificationStatus, "02")
//                        .eq(PmsTemProcessTrackPO::getProStage,"01")
                        .between(PmsTemProcessApproval::getRectificationTime, beginTime, endTime)
                        .count();

                Integer approvalRectificationProblemCount = pmsTemProcessApprovalService.lambdaQuery()
                        .in(PmsTemProcessApproval::getTempUserDossierId, userIds)
                        .eq(PmsTemProcessApproval::getRectificationStatus, "02")
//                        .eq(PmsTemProcessTrackPO::getProStage,"01")
//                        .between(PmsTemProcessApproval::getRectificationTime, beginTime, endTime)
                        .count();

                report.setApprovalRectificationProblemNum(approvalRectificationProblemNum);
                report.setApprovalRectificationProblemCount(approvalRectificationProblemCount);

                //试运行
                Integer testRunUserCount = iPmsTemProcessTrackService.lambdaQuery()
                        .in(PmsTemProcessTrackPO::getTempUserDossierId, userIds)
                        .eq(PmsTemProcessTrackPO::getProStage,"03")
                        .between(PmsTemProcessTrackPO::getMonitorDate, beginTime, endTime)
                        .count();
                Integer testRunOvUserNum = iPmsTemProcessTrackService.lambdaQuery()
                        .in(PmsTemProcessTrackPO::getTempUserDossierId, userIds)
                        .eq(PmsTemProcessTrackPO::getProStage,"03")
                        .eq(PmsTemProcessTrackPO::getTestIsOv,"01")
                        .between(PmsTemProcessTrackPO::getMonitorDate, beginTime, endTime)
                        .count();
                report.setTestRunUserCount(testRunUserCount);
                report.setTestRunOvUserNum(testRunOvUserNum);
                report.setTestRunOvUserRate(BigDecimal.valueOf(testRunOvUserNum==0?0.00:Double.valueOf(testRunOvUserNum*100)/testRunOvUserNum).setScale(2));

                Integer runUserCount = iPmsTemProcessTrackService.lambdaQuery()
                        .in(PmsTemProcessTrackPO::getTempUserDossierId, userIds)
                        .eq(PmsTemProcessTrackPO::getProStage,"04")
                        .between(PmsTemProcessTrackPO::getOperateDate, beginTime, endTime)
                        .count();
                Integer runOvUserNum = iPmsTemProcessTrackService.lambdaQuery()
                        .in(PmsTemProcessTrackPO::getTempUserDossierId, userIds)
                        .eq(PmsTemProcessTrackPO::getProStage,"04")
                        .isNotNull(PmsTemProcessTrackPO::getOvIndexs)
                        .between(PmsTemProcessTrackPO::getOperateDate, beginTime, endTime)
                        .count();


                report.setRunUserCount(runUserCount);
                report.setRunOvUserNum(runOvUserNum);
                report.setRunOvUserRate(BigDecimal.valueOf(runOvUserNum==0?0.00:Double.valueOf(runOvUserNum*100)/runUserCount).setScale(2));


            }
            pmsTemProcessReportList.add(report);
            province.getChildren().forEach(city->{
                PmsTemProcessReport pmsTemProcessReport = new PmsTemProcessReport();
                pmsTemProcessReport.setProvinceOrg(province.getCode());
                pmsTemProcessReport.setProvinceOrgName(province.getName());
                pmsTemProcessReport.setCityOrg(city.getCode());
                pmsTemProcessReport.setCityOrgName(city.getName());
                pmsTemProcessReport.setStatisticalLevel("4");
                pmsTemProcessReport.setStatisticalType("02");
                pmsTemProcessReport.setStatisticalDate(statisticalDate);


                pmsTemProcessReport.setUploadStatus(DataStateEnum.DELETED.getCode());



                Integer monthCount1 = iPmsTemUserService.lambdaQuery()
                        .eq(PmsTemUserPO::getProvinceOrg, province.getCode())
                        .eq(PmsTemUserPO::getCityOrg, city.getCode())
                        .between(PmsTemUserPO::getReleaseTime, beginTime, endTime).count();
                List<PmsTemUserPO> list1 = iPmsTemUserService.lambdaQuery()
                        .eq(PmsTemUserPO::getProvinceOrg, province.getCode())
                        .eq(PmsTemUserPO::getCityOrg, city.getCode()).list();
                pmsTemProcessReport.setNewUserNum(monthCount1);
                pmsTemProcessReport.setNewUserCount(list1.size());

                List<String> userIds1 = list1.stream().map(PmsTemUserPO::getObjId).collect(Collectors.toList());
                if(CollectionUtils.isEmpty(userIds1)){

                    pmsTemProcessReport.setReportAuditNum(0);
                    pmsTemProcessReport.setReportAuditCount(0);
                    pmsTemProcessReport.setApprovalAuditNum(0);
                    pmsTemProcessReport.setApprovalAuditCount(0);
                    pmsTemProcessReport.setApprovalProblemNum(0);
                    pmsTemProcessReport.setApprovalProblemCount(0);
                    pmsTemProcessReport.setApprovalRectificationProblemNum(0);
                    pmsTemProcessReport.setApprovalRectificationProblemCount(0);
                    pmsTemProcessReport.setTestRunUserCount(0);
                    pmsTemProcessReport.setTestRunOvUserNum(0);
                    pmsTemProcessReport.setTestRunOvUserRate(BigDecimal.valueOf(0.00));
                    pmsTemProcessReport.setRunUserCount(0);
                    pmsTemProcessReport.setRunOvUserNum(0);
                    pmsTemProcessReport.setRunOvUserRate(BigDecimal.valueOf(0.00));


                }else {
                    //规划可研阶段
                    Integer auditCount = iPmsTemProcessTrackService.lambdaQuery()
                            .in(PmsTemProcessTrackPO::getTempUserDossierId, userIds1)
//                        .eq(PmsTemProcessTrackPO::getProStage,"01")
                            .between(PmsTemProcessTrackPO::getAuditTime, beginTime, endTime)
                            .count();

                    Integer allAuditCount = iPmsTemProcessTrackService.lambdaQuery()
                            .in(PmsTemProcessTrackPO::getTempUserDossierId, userIds1)
//                        .eq(PmsTemProcessTrackPO::getProStage,"01")
//                        .between(PmsTemProcessTrackPO::getAuditFinalTime, beginTime, endTime)
                            .isNotNull(PmsTemProcessTrackPO::getAuditTime)
                            .count();
                    pmsTemProcessReport.setReportAuditNum(auditCount);
                    pmsTemProcessReport.setReportAuditCount(allAuditCount);

                    //规划验收
                    Integer approvalAuditNum = iPmsTemProcessTrackService.lambdaQuery()
                            .in(PmsTemProcessTrackPO::getTempUserDossierId, userIds1)
//                        .eq(PmsTemProcessTrackPO::getProStage,"01")
                            .between(PmsTemProcessTrackPO::getApprovalTime, beginTime, endTime)
                            .count();
                    Integer approvalAuditCount = iPmsTemProcessTrackService.lambdaQuery()
                            .in(PmsTemProcessTrackPO::getTempUserDossierId, userIds1)
//                        .eq(PmsTemProcessTrackPO::getProStage,"01")
//                        .between(PmsTemProcessTrackPO::getAuditFinalTime, beginTime, endTime)
                            .isNotNull(PmsTemProcessTrackPO::getApprovalTime)
                            .count();
                    pmsTemProcessReport.setApprovalAuditNum(approvalAuditNum);
                    pmsTemProcessReport.setApprovalAuditCount(approvalAuditCount);

                    Integer approvalProblemNum = iPmsTemProcessTrackService.lambdaQuery()
                            .in(PmsTemProcessTrackPO::getTempUserDossierId, userIds1)
                            .eq(PmsTemProcessTrackPO::getApprovalResult,"01")
//                        .eq(PmsTemProcessTrackPO::getProStage,"01")
                            .between(PmsTemProcessTrackPO::getApprovalTime, beginTime, endTime)
                            .count();
                    Integer approvalProblemCount = iPmsTemProcessTrackService.lambdaQuery()
                            .in(PmsTemProcessTrackPO::getTempUserDossierId, userIds1)
                            .eq(PmsTemProcessTrackPO::getApprovalResult,"01")
//                        .eq(PmsTemProcessTrackPO::getProStage,"01")
//                        .between(PmsTemProcessTrackPO::getAuditFinalTime, beginTime, endTime)
                            .isNotNull(PmsTemProcessTrackPO::getApprovalTime)
                            .count();
                    pmsTemProcessReport.setApprovalProblemNum(approvalProblemNum);
                    pmsTemProcessReport.setApprovalProblemCount(approvalProblemCount);

                    Integer approvalRectificationProblemNum = pmsTemProcessApprovalService.lambdaQuery()
                            .in(PmsTemProcessApproval::getTempUserDossierId, userIds1)
                            .eq(PmsTemProcessApproval::getRectificationStatus, "02")
//                        .eq(PmsTemProcessTrackPO::getProStage,"01")
                            .between(PmsTemProcessApproval::getRectificationTime, beginTime, endTime)
                            .count();

                    Integer approvalRectificationProblemCount = pmsTemProcessApprovalService.lambdaQuery()
                            .in(PmsTemProcessApproval::getTempUserDossierId, userIds1)
                            .eq(PmsTemProcessApproval::getRectificationStatus, "02")
//                        .eq(PmsTemProcessTrackPO::getProStage,"01")
//                        .between(PmsTemProcessApproval::getRectificationTime, beginTime, endTime)
                            .count();

                    pmsTemProcessReport.setApprovalRectificationProblemNum(approvalRectificationProblemNum);
                    pmsTemProcessReport.setApprovalRectificationProblemCount(approvalRectificationProblemCount);

                    //试运行
                    Integer testRunUserCount = iPmsTemProcessTrackService.lambdaQuery()
                            .in(PmsTemProcessTrackPO::getTempUserDossierId, userIds1)
                            .eq(PmsTemProcessTrackPO::getProStage,"03")
                            .between(PmsTemProcessTrackPO::getMonitorDate, beginTime, endTime)
                            .count();
                    Integer testRunOvUserNum = iPmsTemProcessTrackService.lambdaQuery()
                            .in(PmsTemProcessTrackPO::getTempUserDossierId, userIds1)
                            .eq(PmsTemProcessTrackPO::getProStage,"03")
                            .eq(PmsTemProcessTrackPO::getTestIsOv,"01")
                            .between(PmsTemProcessTrackPO::getMonitorDate, beginTime, endTime)
                            .count();
                    pmsTemProcessReport.setTestRunUserCount(testRunUserCount);
                    pmsTemProcessReport.setTestRunOvUserNum(testRunOvUserNum);
                    pmsTemProcessReport.setTestRunOvUserRate(BigDecimal.valueOf(testRunOvUserNum==0?0.00:Double.valueOf(testRunOvUserNum*100)/testRunOvUserNum).setScale(2));

                    Integer runUserCount = iPmsTemProcessTrackService.lambdaQuery()
                            .in(PmsTemProcessTrackPO::getTempUserDossierId, userIds1)
                            .eq(PmsTemProcessTrackPO::getProStage,"04")
                            .between(PmsTemProcessTrackPO::getOperateDate, beginTime, endTime)
                            .count();
                    Integer runOvUserNum = iPmsTemProcessTrackService.lambdaQuery()
                            .in(PmsTemProcessTrackPO::getTempUserDossierId, userIds1)
                            .eq(PmsTemProcessTrackPO::getProStage,"04")
                            .isNotNull(PmsTemProcessTrackPO::getOvIndexs)
                            .between(PmsTemProcessTrackPO::getOperateDate, beginTime, endTime)
                            .count();


                    pmsTemProcessReport.setRunUserCount(runUserCount);
                    pmsTemProcessReport.setRunOvUserNum(runOvUserNum);
                    pmsTemProcessReport.setRunOvUserRate(BigDecimal.valueOf(runOvUserNum==0?0.00:Double.valueOf(runOvUserNum*100)/runUserCount).setScale(2));


                }
                pmsTemProcessReportList.add(pmsTemProcessReport);
            });
        });
        QueryWrapper<PmsTemProcessReport> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(PmsTemProcessReport::getStatisticalDate,statisticalDate);
        this.remove(queryWrapper);
        this.saveBatch(pmsTemProcessReportList);

        return true;
    }

    private List<PvTerminalTreeVO> getChildren(PvTerminalTreeVO temp, List<PvTerminalTreeVO> all) {
        return all.stream().filter(item -> item.getPid().equals(temp.getId())).peek(item -> {
            item.setLevel(temp.getLevel() + 1);
            item.setChildren(getChildren(item, all));
        }).collect(Collectors.toList());
    }
}
