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

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.NumberUtil;
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.dto.SimpleDTO;
import com.njcn.common.pojo.enums.response.CommonResponseEnum;
import com.njcn.common.pojo.exception.BusinessException;
import com.njcn.device.pms.pojo.dto.PmsGeneralDeviceDTO;
import com.njcn.device.pms.pojo.param.PmsDeviceInfoParam;
import com.njcn.device.pms.pojo.param.RMpDevEvaluateDetailParam;
import com.njcn.device.pms.pojo.po.PmsTerminal;
import com.njcn.device.pms.pojo.po.RMpDevEvaluateDetail;
import com.njcn.device.pms.pojo.po.RMpDevSolveDetail;
import com.njcn.device.pms.pojo.vo.RMpDevEvaluateDetailVO;
import com.njcn.device.pms.service.majornetwork.IPmsGeneralDeviceService;
import com.njcn.device.pms.service.majornetwork.ITerminalService;
import com.njcn.device.pms.service.majornetwork.RMpDevEvaluateDetailService;
import com.njcn.device.pms.mapper.majornetwork.RMpDevEvaluateDetailMapper;
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.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;

/**
* @author jianghf
* @description 针对表【r_mp_dev_evaluate_detail(终端评价详情表 )】的数据库操作Service实现
* @createDate 2022-11-17 15:38:02
*/
@Service
@RequiredArgsConstructor
public class RMpDevEvaluateDetailServiceImpl extends ServiceImpl<RMpDevEvaluateDetailMapper, RMpDevEvaluateDetail>
    implements RMpDevEvaluateDetailService{

    private final ITerminalService iTerminalService;

    private final DeptFeignClient deptFeignClient;

    /***
     * 单位维度终端质量评价
     * @author jianghaifei
     * @date 2022-11-17 16:12
     * @param rMpDevEvaluateDetailParam
     * @return java.util.List<com.njcn.device.pms.pojo.vo.RMpDevEvaluateDetailVO>
     */
    @Override
    public List<RMpDevEvaluateDetailVO> getOrgDevEvaluateDetailList(RMpDevEvaluateDetailParam rMpDevEvaluateDetailParam) {
        //提取参数
        String id = rMpDevEvaluateDetailParam.getId(); //单位id
        String startTime = rMpDevEvaluateDetailParam.getStartTime(); //开始时间
        String endTime = rMpDevEvaluateDetailParam.getEndTime(); //截止时间
        if (StringUtils.isBlank(id)) {
            throw new BusinessException(CommonResponseEnum.NO_DATA, "单位id不可为空");
        }

//        //查询单位下的终端信息
//        PmsDeviceInfoParam pmsDeviceInfoParam = new PmsDeviceInfoParam();
//        pmsDeviceInfoParam.setDeptIndex(id);
//        pmsDeviceInfoParam.setStatisticalType(new SimpleDTO());
//        List<PmsGeneralDeviceDTO> pmsDeviceInfoWithInOrg = iPmsGeneralDeviceService.getPmsDeviceInfoWithInOrg(pmsDeviceInfoParam);
//        pmsDeviceInfoWithInOrg.get(0);

        //获取所有子部门信息
        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, "部门不存在");
        }
        //单位code集合
        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);
        if (CollUtil.isEmpty(terminalList)) {
            return new ArrayList<>();
        }
        //提取终端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));
        //将终端信息按单位分组  key：单位id(字段是id实际数据是单位code)  value：终端集合
        Map<String, List<PmsTerminal>> terminalListMapByOrgId = terminalList.stream().collect(Collectors.groupingBy(PmsTerminal::getOrgId));

        //查询终端评价详情表数据【r_mp_dev_evaluate_detail】
        LambdaQueryWrapper<RMpDevEvaluateDetail> businessWrapper = new LambdaQueryWrapper<>();
        businessWrapper.in(RMpDevEvaluateDetail::getDeviceId, terminalIdList)
                .ge(StringUtils.isNotBlank(startTime), RMpDevEvaluateDetail::getDataDate, startTime)
                .le(StringUtils.isNotBlank(endTime), RMpDevEvaluateDetail::getDataDate, endTime);
        List<RMpDevEvaluateDetail> list = this.list(businessWrapper);

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

            rMpDevEvaluateDetailVO.setDataDate(time); //日期(前端传递的时间)
            rMpDevEvaluateDetailVO.setOrgId(key); //单位id(字段是id实际数据是单位code)
            rMpDevEvaluateDetailVO.setOrgName(terminalListByOrg.get(0).getOrgName()); //单位名称

            //终端有效接入率
            double devEffectiveRate = list.stream().filter(item -> terminalMap.get(item.getDeviceId()).getOrgId().equals(key))
                    .mapToDouble(RMpDevEvaluateDetail::getDevEffectiveRate).average().orElse(0);
            rMpDevEvaluateDetailVO.setDevEffectiveRate(NumberUtil.round(devEffectiveRate,2).doubleValue());
            //终端指标完整率
            double devTargetRate = list.stream().filter(item -> terminalMap.get(item.getDeviceId()).getOrgId().equals(key))
                    .mapToDouble(RMpDevEvaluateDetail::getDevTargetRate).average().orElse(0);
            rMpDevEvaluateDetailVO.setDevTargetRate(NumberUtil.round(devTargetRate,2).doubleValue());
            //终端数据完整率
            double devDataRate = list.stream().filter(item -> terminalMap.get(item.getDeviceId()).getOrgId().equals(key))
                    .mapToDouble(RMpDevEvaluateDetail::getDevDataRate).average().orElse(0);
            rMpDevEvaluateDetailVO.setDevDataRate(NumberUtil.round(devDataRate,2).doubleValue());
            //综合评价
            rMpDevEvaluateDetailVO.setAssessment(Double.parseDouble(df.format((devEffectiveRate + devTargetRate + devDataRate) / 3.0)));

            //在运终端数量
            rMpDevEvaluateDetailVO.setDevCount(terminalListByOrg.size());

            resultList.add(rMpDevEvaluateDetailVO);
        });
        return resultList;
    }

    /***
     * 厂商维度终端质量评价
     * @author jianghaifei
     * @date 2022-11-17 16:13
     * @param rMpDevEvaluateDetailParam
     * @return java.util.List<com.njcn.device.pms.pojo.vo.RMpDevEvaluateDetailVO>
     */
    @Override
    public List<RMpDevEvaluateDetailVO> getManufactureDevEvaluateDetailList(RMpDevEvaluateDetailParam rMpDevEvaluateDetailParam) {
        //提取参数
        List<String> manufactureIdList = StringUtils.isNotBlank(rMpDevEvaluateDetailParam.getManufactureIds()) ?
                Arrays.asList(rMpDevEvaluateDetailParam.getManufactureIds().split(",")) : null; //厂商ids

        List<String> deviceModelIdList = StringUtils.isNotBlank(rMpDevEvaluateDetailParam.getDeviceModel()) ?
                Arrays.asList(rMpDevEvaluateDetailParam.getDeviceModel().split(",")) : null; //终端型号
        String startTime = rMpDevEvaluateDetailParam.getStartTime(); //开始时间
        String endTime = rMpDevEvaluateDetailParam.getEndTime(); //截止时间

        //查询终端厂商下的终端数据
        LambdaQueryWrapper<PmsTerminal> terminalWrapper = new LambdaQueryWrapper<>();
        terminalWrapper.in(CollUtil.isNotEmpty(manufactureIdList), PmsTerminal::getManufacture, manufactureIdList)
                .isNotNull(CollUtil.isEmpty(manufactureIdList), PmsTerminal::getManufacture)
                .in(CollUtil.isNotEmpty(deviceModelIdList), PmsTerminal::getDeviceModel, deviceModelIdList);
        List<PmsTerminal> terminalList = iTerminalService.list(terminalWrapper);

        if (CollUtil.isEmpty(terminalList)) {
            return new ArrayList<>();
        }
        //提取终端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));
        //将终端信息按厂商分组  key：厂商id  value：终端集合
        Map<String, List<PmsTerminal>> terminalListMapByManufacture = terminalList.stream().collect(Collectors.groupingBy(PmsTerminal::getManufacture));

        //查询终端评价详情表数据【r_mp_dev_evaluate_detail】
        LambdaQueryWrapper<RMpDevEvaluateDetail> businessWrapper = new LambdaQueryWrapper<>();
        businessWrapper.in(RMpDevEvaluateDetail::getDeviceId, terminalIdList)
                .ge(StringUtils.isNotBlank(startTime), RMpDevEvaluateDetail::getDataDate, startTime)
                .le(StringUtils.isNotBlank(endTime), RMpDevEvaluateDetail::getDataDate, endTime);
        List<RMpDevEvaluateDetail> list = this.list(businessWrapper);

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

            rMpDevEvaluateDetailVO.setDataDate(time); //日期(前端传递的时间)
            rMpDevEvaluateDetailVO.setManufactureId(key); //厂商id

            //终端有效接入率
            double devEffectiveRate = list.stream().filter(item -> terminalMap.get(item.getDeviceId()).getManufacture().equals(key))
                    .mapToDouble(RMpDevEvaluateDetail::getDevEffectiveRate).average().orElse(0);
            rMpDevEvaluateDetailVO.setDevEffectiveRate(NumberUtil.round(devEffectiveRate,2).doubleValue());
            //终端指标完整率
            double devTargetRate = list.stream().filter(item -> terminalMap.get(item.getDeviceId()).getManufacture().equals(key))
                    .mapToDouble(RMpDevEvaluateDetail::getDevTargetRate).average().orElse(0);
            rMpDevEvaluateDetailVO.setDevTargetRate(NumberUtil.round(devTargetRate,2).doubleValue());
            //终端数据完整率
            double devDataRate = list.stream().filter(item -> terminalMap.get(item.getDeviceId()).getManufacture().equals(key))
                    .mapToDouble(RMpDevEvaluateDetail::getDevDataRate).average().orElse(0);
            rMpDevEvaluateDetailVO.setDevDataRate(NumberUtil.round(devDataRate,2).doubleValue());
            //综合评价
            rMpDevEvaluateDetailVO.setAssessment(Double.parseDouble(df.format((devEffectiveRate + devTargetRate + devDataRate) / 3.0)));

            //在运终端数量
            rMpDevEvaluateDetailVO.setDevCount(terminalListByManufacture.size());

            resultList.add(rMpDevEvaluateDetailVO);
        });
        return resultList;
    }

    /***
     * 终端型号维度终端质量评价
     * @author jianghaifei
     * @date 2022-11-18 15:40
     * @param rMpDevEvaluateDetailParam
     * @return java.util.List<com.njcn.device.pms.pojo.vo.RMpDevEvaluateDetailVO>
     */
    @Override
    public List<RMpDevEvaluateDetailVO> getModelDevEvaluateDetailList(RMpDevEvaluateDetailParam rMpDevEvaluateDetailParam) {
        //提取参数
        List<String> deviceModelIdList = StringUtils.isNotBlank(rMpDevEvaluateDetailParam.getDeviceModel()) ?
                Arrays.asList(rMpDevEvaluateDetailParam.getDeviceModel().split(",")) : null; //终端型号
        String startTime = rMpDevEvaluateDetailParam.getStartTime(); //开始时间
        String endTime = rMpDevEvaluateDetailParam.getEndTime(); //截止时间

        //查询终端厂商下的终端数据
        LambdaQueryWrapper<PmsTerminal> terminalWrapper = new LambdaQueryWrapper<>();
        terminalWrapper.in(CollUtil.isNotEmpty(deviceModelIdList), PmsTerminal::getDeviceModel, deviceModelIdList);
        List<PmsTerminal> terminalList = iTerminalService.list(terminalWrapper);

        if (CollUtil.isEmpty(terminalList)) {
            return new ArrayList<>();
        }
        //提取终端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));
        //将终端信息按终端型号分组  key：型号  value：终端集合
        Map<String, List<PmsTerminal>> terminalListMapByModel = terminalList.stream().collect(Collectors.groupingBy(PmsTerminal::getDeviceModel));

        //查询终端评价详情表数据【r_mp_dev_evaluate_detail】
        LambdaQueryWrapper<RMpDevEvaluateDetail> businessWrapper = new LambdaQueryWrapper<>();
        businessWrapper.in(RMpDevEvaluateDetail::getDeviceId, terminalIdList)
                .ge(StringUtils.isNotBlank(startTime), RMpDevEvaluateDetail::getDataDate, startTime)
                .le(StringUtils.isNotBlank(endTime), RMpDevEvaluateDetail::getDataDate, endTime);
        List<RMpDevEvaluateDetail> list = this.list(businessWrapper);

        //封装返回数据
        DecimalFormat df = new DecimalFormat("###.00");
        List<RMpDevEvaluateDetailVO> resultList = new ArrayList<>();
        String time = time(startTime, rMpDevEvaluateDetailParam.getType());
        terminalListMapByModel.forEach((key, terminalListByModel) -> {
            RMpDevEvaluateDetailVO rMpDevEvaluateDetailVO = new RMpDevEvaluateDetailVO();

            rMpDevEvaluateDetailVO.setDataDate(time); //日期(前端传递的时间)
            rMpDevEvaluateDetailVO.setDeviceModel(key); //终端型号

            //终端有效接入率
            double devEffectiveRate = list.stream().filter(item -> terminalMap.get(item.getDeviceId()).getDeviceModel().equals(key))
                    .mapToDouble(RMpDevEvaluateDetail::getDevEffectiveRate).average().orElse(0);
            rMpDevEvaluateDetailVO.setDevEffectiveRate(NumberUtil.round(devEffectiveRate,2).doubleValue());
            //终端指标完整率
            double devTargetRate = list.stream().filter(item -> terminalMap.get(item.getDeviceId()).getDeviceModel().equals(key))
                    .mapToDouble(RMpDevEvaluateDetail::getDevTargetRate).average().orElse(0);
            rMpDevEvaluateDetailVO.setDevTargetRate(NumberUtil.round(devTargetRate,2).doubleValue());
            //终端数据完整率
            double devDataRate = list.stream().filter(item -> terminalMap.get(item.getDeviceId()).getDeviceModel().equals(key))
                    .mapToDouble(RMpDevEvaluateDetail::getDevDataRate).average().orElse(0);
            rMpDevEvaluateDetailVO.setDevDataRate(NumberUtil.round(devDataRate,2).doubleValue());
            //综合评价
            rMpDevEvaluateDetailVO.setAssessment(Double.parseDouble(df.format((devEffectiveRate + devTargetRate + devDataRate) / 3.0)));

            //在运终端数量
            rMpDevEvaluateDetailVO.setDevCount(terminalListByModel.size());

            resultList.add(rMpDevEvaluateDetailVO);
        });
        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);
            }
        }
    }

}




