package com.njcn.device.pms.service.majornetwork.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.njcn.common.pojo.enums.response.CommonResponseEnum;
import com.njcn.common.pojo.exception.BusinessException;
import com.njcn.device.pms.mapper.majornetwork.RMpDevSolveDetailMapper;
import com.njcn.device.pms.pojo.param.RMpDevAbnormalManageParam;
import com.njcn.device.pms.pojo.param.RMpDevSolveDetailParam;
import com.njcn.device.pms.pojo.po.RMpDevSolveDetail;
import com.njcn.device.pms.pojo.po.RStatZwAlarmCountW;
import com.njcn.device.pms.pojo.po.PmsTerminal;
import com.njcn.device.pms.pojo.vo.RMpDevSolveDetailVO;
import com.njcn.device.pms.pojo.vo.RMpDevSolveVO;
import com.njcn.device.pms.service.majornetwork.ITerminalService;
import com.njcn.device.pms.service.majornetwork.RMpDevSolveDetailService;
import com.njcn.user.api.DeptFeignClient;
import com.njcn.user.pojo.dto.DeptDTO;
import com.njcn.web.utils.WebUtil;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
* @author jianghf
* @description 针对表【r_mp_dev_solve_detail(终端消缺明细数据表)】的数据库操作Service实现
* @createDate 2022-11-14 19:42:13
*/
@Service
@RequiredArgsConstructor
public class RMpDevSolveDetailServiceImpl extends ServiceImpl<RMpDevSolveDetailMapper, RMpDevSolveDetail>
    implements RMpDevSolveDetailService{

    private final ITerminalService iTerminalService;

    private final DeptFeignClient deptFeignClient;

    /***
     * 单位终端消缺统计
     * @author jianghaifei
     * @date 2022-11-14 19:50
     * @param rMpDevAbnormalManageParam
     */
    @Override
    public List<RMpDevSolveVO> getOrgRMpDevSolveList(RMpDevAbnormalManageParam rMpDevAbnormalManageParam) {
        //提取参数
        String id = rMpDevAbnormalManageParam.getId(); //单位id
        String startTime = rMpDevAbnormalManageParam.getStartTime(); //开始时间
        String endTime = rMpDevAbnormalManageParam.getEndTime(); //结束时间

        //获取所有子部门信息
        List<DeptDTO> deptDTOList = deptFeignClient.getDeptDescendantIndexes(id, WebUtil.filterDeptType()).getData();
        if (CollUtil.isEmpty(deptDTOList)) {
            throw new BusinessException(CommonResponseEnum.NO_DATA, "部门不存在");
        }
        //单位id集合
        List<String> orgCodeList = deptDTOList.stream().map(DeptDTO::getCode).collect(Collectors.toList());

        //查询单位下的终端数据
        LambdaQueryWrapper<PmsTerminal> terminalWrapper = new LambdaQueryWrapper<>();
        terminalWrapper.in(PmsTerminal::getOrgId, orgCodeList);
        List<PmsTerminal> terminalList = iTerminalService.list(terminalWrapper);
        //提取终端id
        List<String> terminalIdList = terminalList.stream().map(PmsTerminal::getId).collect(Collectors.toList());
        //将终端信息转为map集合 key: 终端id  value: 终端实体
        Map<String, PmsTerminal> terminalMap = terminalList.stream().collect(Collectors.toMap(PmsTerminal::getId, terminal -> terminal));
        if (CollUtil.isEmpty(terminalIdList)) {
            return new ArrayList<>();
        }
        //将终端信息按单位分组  key：单位id(字段是org_id实际数据存的是单位表的org_code)  value：终端集合
        Map<String, List<PmsTerminal>> terminalListMapByOrgId = terminalList.stream().collect(Collectors.groupingBy(PmsTerminal::getOrgId));

        //查询终端消缺数据
        LambdaQueryWrapper<RMpDevSolveDetail> solveWrapper = new LambdaQueryWrapper<>();
        solveWrapper.in(RMpDevSolveDetail::getDeviceId, terminalIdList)
                .ge(StringUtils.isNotBlank(startTime), RMpDevSolveDetail::getDataDate, startTime)
                .le(StringUtils.isNotBlank(endTime), RMpDevSolveDetail::getDataDate, endTime);
        List<RMpDevSolveDetail> solveList = this.list(solveWrapper);

        //有异常的终端id集合(去重，一个终端即使有多次异常，也算作一个终端异常数量)
        List<String> solveDevIdList = solveList.stream().map(RMpDevSolveDetail::getDeviceId).distinct().collect(Collectors.toList());

        //封装返回数据
        List<RMpDevSolveVO> resultList = new ArrayList<>();
        DecimalFormat df = new DecimalFormat("###.00");
        String time = time(startTime, rMpDevAbnormalManageParam.getType());
        terminalListMapByOrgId.forEach((key, terminalListByOrg) -> {
            RMpDevSolveVO rMpDevSolveVO = new RMpDevSolveVO();

            rMpDevSolveVO.setDataDate(time);
            rMpDevSolveVO.setOrgId(key); //单位id
            rMpDevSolveVO.setOrgName(terminalListByOrg.get(0).getOrgName()); //单位名称

            rMpDevSolveVO.setTerminalCount(terminalListByOrg.size()); //终端数量

            //终端异常数量  terminalAbnormalCount
            int terminalAbnormalCount = (int)solveDevIdList.stream().filter(item -> terminalMap.get(item).getOrgId().equals(key)).count();
            rMpDevSolveVO.setTerminalAbnormalCount(terminalAbnormalCount);

            /**已消缺数量  solveCount**/
            int notSolveCount = 0, solveCount = 0;
            //当前单位未消缺的终端数量
            if (terminalAbnormalCount != 0) {
                notSolveCount = (int)solveList.stream().filter(item -> {
                    return terminalMap.get(item.getDeviceId()).getOrgId().equals(key) && item.getIsSolve() == 0;
                }).map(RMpDevSolveDetail::getDeviceId).distinct().count();
                //已消缺数量
                solveCount = terminalAbnormalCount - notSolveCount;
            }

            rMpDevSolveVO.setSolveCount(terminalAbnormalCount - notSolveCount);

            //消缺率  solveRate
            if (terminalAbnormalCount == 0) {  //防止算术异常
                rMpDevSolveVO.setSolveRate(00.00);
            } else {
                rMpDevSolveVO.setSolveRate(Double.parseDouble(df.format((solveCount * 1.0) / (terminalAbnormalCount * 1.0))) * 100);
            }

            resultList.add(rMpDevSolveVO);
        });

        return resultList;
    }

    /***
     * 厂家终端消缺统计
     * @author jianghaifei
     * @date 2022-11-14 19:50
     * @param rMpDevAbnormalManageParam
     */
    @Override
    public List<RMpDevSolveVO> getManufactureRMpDevSolveList(RMpDevAbnormalManageParam rMpDevAbnormalManageParam) {
        //提取参数
        List<String> manufactureIdList = StringUtils.isNotBlank(rMpDevAbnormalManageParam.getManufactureIds()) ?
                Arrays.asList(rMpDevAbnormalManageParam.getManufactureIds().split(",")) : null; //厂商id
        String startTime = rMpDevAbnormalManageParam.getStartTime(); //开始时间
        String endTime = rMpDevAbnormalManageParam.getEndTime(); //结束时间


        //查询终端厂商下的终端数据
        LambdaQueryWrapper<PmsTerminal> terminalWrapper = new LambdaQueryWrapper<>();
        terminalWrapper.in(CollUtil.isNotEmpty(manufactureIdList), PmsTerminal::getManufacture, manufactureIdList)
        .isNotNull(CollUtil.isEmpty(manufactureIdList), PmsTerminal::getManufacture);
        List<PmsTerminal> terminalList = iTerminalService.list(terminalWrapper);
        //提取终端id
        List<String> terminalIdList = terminalList.stream().map(PmsTerminal::getId).collect(Collectors.toList());
        //将终端信息转为map集合 key: 终端id  value: 终端实体
        Map<String, PmsTerminal> terminalMap = terminalList.stream().collect(Collectors.toMap(PmsTerminal::getId, terminal -> terminal));
        if (CollUtil.isEmpty(terminalIdList)) {
            return new ArrayList<>();
        }
        //将终端信息按厂商分组  key：厂商id  value：终端集合
        Map<String, List<PmsTerminal>> terminalListMapByManufacture = terminalList.stream().collect(Collectors.groupingBy(PmsTerminal::getManufacture));

        //查询终端消缺数据
        LambdaQueryWrapper<RMpDevSolveDetail> solveWrapper = new LambdaQueryWrapper<>();
        solveWrapper.in(RMpDevSolveDetail::getDeviceId, terminalIdList)
                .ge(StringUtils.isNotBlank(startTime), RMpDevSolveDetail::getDataDate, startTime)
                .le(StringUtils.isNotBlank(endTime), RMpDevSolveDetail::getDataDate, endTime);
        List<RMpDevSolveDetail> solveList = this.list(solveWrapper);

        //有异常的终端id集合(去重，一个终端即使有多次异常，也算作一个终端异常数量)
        List<String> solveDevIdList = solveList.stream().map(RMpDevSolveDetail::getDeviceId).distinct().collect(Collectors.toList());

        //封装返回数据
        List<RMpDevSolveVO> resultList = new ArrayList<>();
        DecimalFormat df = new DecimalFormat("###.00");
        String time = time(startTime, rMpDevAbnormalManageParam.getType());
        terminalListMapByManufacture.forEach((key, terminalListByOrg) -> {
            RMpDevSolveVO rMpDevSolveVO = new RMpDevSolveVO();

            rMpDevSolveVO.setDataDate(time);
            rMpDevSolveVO.setManufactureId(key); //厂商id

            rMpDevSolveVO.setTerminalCount(terminalListByOrg.size()); //终端数量

            //终端异常数量  terminalAbnormalCount
            int terminalAbnormalCount = (int)solveDevIdList.stream().filter(item -> terminalMap.get(item).getManufacture().equals(key)).count();
            rMpDevSolveVO.setTerminalAbnormalCount(terminalAbnormalCount);

            /**已消缺数量  solveCount**/
            int notSolveCount = 0, solveCount = 0;
            //当前厂商未消缺的终端数量
            if (terminalAbnormalCount != 0) {
                notSolveCount = (int)solveList.stream().filter(item -> {
                    return terminalMap.get(item.getDeviceId()).getManufacture().equals(key) && item.getIsSolve() == 0;
                }).map(RMpDevSolveDetail::getDeviceId).distinct().count();

                //已消缺数量
                solveCount = terminalAbnormalCount - notSolveCount;
            }

            rMpDevSolveVO.setSolveCount(solveCount);

            //消缺率  solveRate
            if (terminalAbnormalCount == 0) {  //防止算术异常
                rMpDevSolveVO.setSolveRate(00.00);
            } else {
                rMpDevSolveVO.setSolveRate(Double.parseDouble(df.format((solveCount * 1.0) / (terminalAbnormalCount * 1.0))) * 100);
            }

            resultList.add(rMpDevSolveVO);
        });

        return resultList;
    }

    /***
     * 故障类型消缺统计
     * @author jianghaifei
     * @date 2022-11-21 10:11
     * @param rMpDevAbnormalManageParam
     * @return java.util.List<com.njcn.device.pms.pojo.vo.RMpDevSolveVO>
     */
    @Override
    public List<RMpDevSolveVO> getTypeRMpDevSolveList(RMpDevAbnormalManageParam rMpDevAbnormalManageParam) {
        //提取参数
        List<String> breakDownTypeList = StringUtils.isNotBlank(rMpDevAbnormalManageParam.getBreakDownType()) ?
                Arrays.asList(rMpDevAbnormalManageParam.getBreakDownType().split(",")) : null; //故障类型
        String startTime = rMpDevAbnormalManageParam.getStartTime(); //开始时间
        String endTime = rMpDevAbnormalManageParam.getEndTime(); //结束时间

        //查询终端消缺数据
        LambdaQueryWrapper<RMpDevSolveDetail> solveWrapper = new LambdaQueryWrapper<>();
        solveWrapper.in(CollUtil.isNotEmpty(breakDownTypeList), RMpDevSolveDetail::getBreakDownType, breakDownTypeList)
                .ge(StringUtils.isNotBlank(startTime), RMpDevSolveDetail::getDataDate, startTime)
                .le(StringUtils.isNotBlank(endTime), RMpDevSolveDetail::getDataDate, endTime);
        List<RMpDevSolveDetail> solveList = this.list(solveWrapper);

        if (CollUtil.isEmpty(solveList)) {
            return new ArrayList<>();
        }
        //按故障类型分组
        Map<String, List<RMpDevSolveDetail>> solveMap = solveList.stream().collect(Collectors.groupingBy(RMpDevSolveDetail::getBreakDownType));

        //封装返回数据
        List<RMpDevSolveVO> resultList = new ArrayList<>();
        DecimalFormat df = new DecimalFormat("###.00");
        String time = time(startTime, rMpDevAbnormalManageParam.getType());
        solveMap.forEach((key, RMpDevSolveDetailList) -> {
            RMpDevSolveVO rMpDevSolveVO = new RMpDevSolveVO();

            rMpDevSolveVO.setDataDate(time);
            rMpDevSolveVO.setBreakDownType(key); //故障类型

            rMpDevSolveVO.setTerminalCount(null); //终端数量(故障类型的终端数量前端展示'/')

            //终端异常数量  terminalAbnormalCount
            int terminalAbnormalCount = (int)RMpDevSolveDetailList.stream().map(RMpDevSolveDetail::getDeviceId).distinct().count();
            rMpDevSolveVO.setTerminalAbnormalCount(terminalAbnormalCount);

            //已消缺数量  solveCount
            //未消缺数量
            int notSolveCount = 0, solveCount = 0;
            if (terminalAbnormalCount != 0) {
                notSolveCount = (int)solveList.stream().filter(item -> {
                    return  item.getIsSolve() == 0;
                }).map(RMpDevSolveDetail::getDeviceId).distinct().count();

                solveCount = terminalAbnormalCount - notSolveCount;
            }

            rMpDevSolveVO.setSolveCount(solveCount);

            //消缺率  solveRate
            if (terminalAbnormalCount == 0) {  //防止算术异常
                rMpDevSolveVO.setSolveRate(00.00);
            } else {
                rMpDevSolveVO.setSolveRate(Double.parseDouble(df.format((solveCount * 1.0) / (terminalAbnormalCount * 1.0))) * 100);
            }

            resultList.add(rMpDevSolveVO);
        });

        return resultList;
    }


    /***
     * 消缺统计清单
     * @author jianghaifei
     * @date 2022-11-21 10:11
     * @param rMpDevSolveDetailParam
     * @return java.util.List<com.njcn.device.pms.pojo.vo.RMpDevSolveDetailVO>
     */
    @Override
    public List<RMpDevSolveDetailVO> getRMpDevSolveDetailList(RMpDevSolveDetailParam rMpDevSolveDetailParam) {
        //提取参数
        String id = rMpDevSolveDetailParam.getId(); //单位id
        List<String> manufactureIdList = StringUtils.isNotBlank(rMpDevSolveDetailParam.getManufactureIds()) ?
                Arrays.asList(rMpDevSolveDetailParam.getManufactureIds().split(",")) : null; //厂商ids
        String startTime = rMpDevSolveDetailParam.getStartTime(); //开始时间
        String endTime = rMpDevSolveDetailParam.getEndTime(); //结束时间

        /**根据条件查询终端**/
        //获取所有子部门信息
        List<DeptDTO> deptDTOList = deptFeignClient.getDeptDescendantIndexes(id, WebUtil.filterDeptType()).getData();
        /*获取下级子部门信息*/
//        List<DeptDTO> deptDTOList = deptFeignClient.getDepSonDetailByDeptId (id).getData ( );
        if (CollUtil.isEmpty(deptDTOList)) {
            throw new BusinessException(CommonResponseEnum.NO_DATA, "部门不存在");
        }
        //单位id集合
        List<String> orgCodeList = deptDTOList.stream().map(DeptDTO::getCode).collect(Collectors.toList());

        //查询单位下的终端数据
        LambdaQueryWrapper<PmsTerminal> terminalWrapper = new LambdaQueryWrapper<>();
        terminalWrapper.in(PmsTerminal::getOrgId, orgCodeList) //单位id
        .in(CollUtil.isNotEmpty(manufactureIdList), PmsTerminal::getManufacture, manufactureIdList); //厂家
        List<PmsTerminal> terminalList = iTerminalService.list(terminalWrapper);
        if (CollUtil.isEmpty(terminalList)) {
            return new ArrayList<>();
        }
        List<String> terminalIdList = terminalList.stream().map(PmsTerminal::getId).collect(Collectors.toList());
        Map<String, PmsTerminal> terminalMap = terminalList.stream().collect(Collectors.toMap(PmsTerminal::getId, terminal -> terminal));
        //查询消缺清单
        //查询终端消缺数据
        LambdaQueryWrapper<RMpDevSolveDetail> solveWrapper = new LambdaQueryWrapper<>();
        solveWrapper.in(CollUtil.isNotEmpty(terminalIdList), RMpDevSolveDetail::getDeviceId, terminalIdList)
                .ge(StringUtils.isNotBlank(startTime), RMpDevSolveDetail::getDataDate, startTime)
                .le(StringUtils.isNotBlank(endTime), RMpDevSolveDetail::getDataDate, endTime);
        List<RMpDevSolveDetail> solveList = this.list(solveWrapper);

        //封装返回数据
        List<RMpDevSolveDetailVO> resultList = solveList.stream().map(item -> {
            RMpDevSolveDetailVO rMpDevSolveDetailVO = new RMpDevSolveDetailVO();
            BeanUtils.copyProperties(item, rMpDevSolveDetailVO); //终端id、故障时间、故障类型、是否消缺、消缺时间

            rMpDevSolveDetailVO.setOrgId(terminalMap.get(item.getDeviceId()).getOrgId()); //单位id
            rMpDevSolveDetailVO.setOrgName(terminalMap.get(item.getDeviceId()).getOrgName()); //单位名称
            rMpDevSolveDetailVO.setPowerId(terminalMap.get(item.getDeviceId()).getPowerStationId()); //变电站id
            rMpDevSolveDetailVO.setPowerName(terminalMap.get(item.getDeviceId()).getPowerrName()); //变电站名称
            return rMpDevSolveDetailVO;
        }).collect(Collectors.toList());
        return resultList;
    }

    private String time(String starTime,Integer type){
        if(ObjectUtil.isNull(type)){
            return starTime;
        }else{
            if(type==1){
                return starTime.substring(0,4);
            }else {
                return starTime.substring(0,7);
            }
        }
    }
}




