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

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.njcn.common.pojo.param.StatisticsBizBaseParam;
import com.njcn.harmonic.pojo.param.OverviewParam;
import com.njcn.harmonic.pojo.param.RStatOrgParam;
import com.njcn.harmonic.pojo.po.RStatOrgM;
import com.njcn.harmonic.mapper.majornetwork.RStatOrgMMapper;
import com.njcn.harmonic.pojo.po.RStatOrgY;
import com.njcn.harmonic.pojo.vo.OverviewVO;
import com.njcn.harmonic.pojo.vo.RStatOrgVO;
import com.njcn.harmonic.service.majornetwork.RStatOrgMService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.njcn.harmonic.utils.DeptUtil;
import com.njcn.system.api.DicDataFeignClient;
import com.njcn.system.enums.DicDataEnum;
import com.njcn.system.enums.DicDataTypeEnum;
import com.njcn.system.pojo.po.DictData;
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.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * <p>
 * 区域分类统计月表 服务实现类
 * </p>
 *
 * @author rui.wu
 * @since 2022-10-17
 */
@Service
@RequiredArgsConstructor
public class RStatOrgMServiceImpl extends ServiceImpl<RStatOrgMMapper, RStatOrgM> implements RStatOrgMService {

    private final DeptFeignClient deptFeignClient;
    private final DicDataFeignClient dicDataFeignClient;
    private final RStatOrgMMapper rStatOrgMMapper;
    private static final String XIONG_AN_CITY="雄安新区";

    @Override
    public List<RStatOrgVO> getRStatHarmonicMAll(RStatOrgParam.Info param) {
        List<DeptDTO> deptList = deptFeignClient.getDeptDescendantIndexes(param.getId(), WebUtil.filterDeptType()).getData();
        List<DeptDTO> deptDTOList = DeptUtil.getDeptSubsetVOList(deptList, param.getId());
        List<String> deptIds = deptDTOList.stream().map(DeptDTO::getCode).collect(Collectors.toList());

        Map<String, DeptDTO> deptMap = deptDTOList.stream().collect(Collectors.toMap(DeptDTO::getCode, Function.identity()));
        //获取主网id信息
        DictData mainnetData = dicDataFeignClient.getDicDataByCode(DicDataEnum.MAINNET_POINT.getCode()).getData();
        //数据库查询
        List<RStatOrgM> list = rStatOrgMMapper.selectList(new LambdaQueryWrapper<RStatOrgM>()
                .eq(RStatOrgM::getDataType, mainnetData.getId())
                .in(RStatOrgM::getOrgNo, deptIds)
                .in(CollUtil.isNotEmpty(param.getMeasurementTypeClass()), RStatOrgM::getMeasurementTypeClass, param.getMeasurementTypeClass())
                .ge(StrUtil.isNotBlank(param.getStartTime()), RStatOrgM::getDataDate, param.getStartTime())
                .le(StrUtil.isNotBlank(param.getEndTime()), RStatOrgM::getDataDate, param.getEndTime()));
        Map<String, List<RStatOrgM>> collect = list.stream().collect(Collectors.groupingBy(RStatOrgM::getOrgNo));

        List<RStatOrgVO> newList = new ArrayList<>();
        collect.forEach((key, value) -> {
            if (deptMap.containsKey(key)) {
                for (RStatOrgM rStatOrgM : value) {
                    DecimalFormat df = new DecimalFormat("###.00");
                    DeptDTO deptDTO = deptMap.get(key);
                    RStatOrgVO rStatOrgVO = new RStatOrgVO();
                    rStatOrgVO.setOrgName(deptDTO.getName());
                    if(rStatOrgM.getOverDayAccrued()!=null&&rStatOrgM.getEffectiveMeasurementAccrued()!=null&&
                            rStatOrgM.getOverDayAccrued()!=0&&rStatOrgM.getEffectiveMeasurementAccrued()!=0){
                        Float averageOverDay = Float.parseFloat(
                                df.format(rStatOrgM.getOverDayAccrued() / (rStatOrgM.getEffectiveMeasurementAccrued() * 1.0)));
                        rStatOrgVO.setAverageOverDay(averageOverDay);
                    }else{
                        rStatOrgVO.setAverageOverDay(0.0f);
                    }
                    rStatOrgVO.setMeasurementTypeClass(rStatOrgM.getMeasurementTypeClass());
                    rStatOrgVO.setEffectiveMeasurementAverage(rStatOrgM.getEffectiveMeasurementAverage());
                    rStatOrgVO.setEffectiveMeasurementAccrued(rStatOrgM.getEffectiveMeasurementAccrued());
                    rStatOrgVO.setOverLimitMeasurementAverage(rStatOrgM.getHarmonicMeasurementAverage());
                    rStatOrgVO.setOverLimitMeasurementAccrued(rStatOrgM.getHarmonicMeasurementAccrued());
                    if(rStatOrgM.getHarmonicMeasurementAverage()!=null&&rStatOrgM.getEffectiveMeasurementAverage()!=null&&
                            rStatOrgM.getHarmonicMeasurementAverage()!=0&&rStatOrgM.getEffectiveMeasurementAverage()!=0){
                        Float harmonicMeasurementRatioAverage = Float.parseFloat(
                                df.format(rStatOrgM.getHarmonicMeasurementAverage() / rStatOrgM.getEffectiveMeasurementAverage()));
                        rStatOrgVO.setHarmonicMeasurementRatioAverage(harmonicMeasurementRatioAverage);
                    }else{
                        rStatOrgVO.setHarmonicMeasurementRatioAverage(0.0f);
                    }
                    if(rStatOrgM.getHarmonicMeasurementAccrued()!=null&&rStatOrgM.getEffectiveMeasurementAccrued()!=null&&
                            rStatOrgM.getHarmonicMeasurementAccrued()!=0&&rStatOrgM.getEffectiveMeasurementAccrued()!=0){
                        Float harmonicMeasurementRatioAccrued = Float.parseFloat(
                                df.format(rStatOrgM.getHarmonicMeasurementAccrued() / rStatOrgM.getEffectiveMeasurementAccrued() ));
                        rStatOrgVO.setHarmonicMeasurementRatioAccrued(harmonicMeasurementRatioAccrued);
                    }else{
                        rStatOrgVO.setHarmonicMeasurementRatioAccrued(0.0f);
                    }
                    newList.add(rStatOrgVO);
                }
            }
        });
        return newList;
    }

    @Override
    public List<OverviewVO.GroupVO> getExceedMonitor(OverviewParam.OverviewDateParam param) {
        List<OverviewVO.GroupVO> info =new ArrayList<>();
        //查询配网信息
        DictData dictData = dicDataFeignClient.getDicDataByCode(DicDataEnum.DISTRIBUTION_POINT.getCode()).getData();

        //获取监测点类别
        List<DictData> monitorType = dicDataFeignClient.getDicDataByTypeCode(DicDataTypeEnum.LINE_SORT.getCode()).getData();
        Map<String, DictData> dictDataMap = monitorType.stream()
                .collect(Collectors.toMap(DictData::getId, Function.identity()));

        //获取部门数据
        List<DeptDTO> subDeptListCode = getSubDeptListCode(param.getId());
        List<String> deptListCode = subDeptListCode.stream().map(DeptDTO::getCode).collect(Collectors.toList());
        Map<String, DeptDTO> deptMap = subDeptListCode.stream().collect(Collectors.toMap(DeptDTO::getCode, Function.identity()));

        List<RStatOrgM> list = this.list(new LambdaQueryWrapper<RStatOrgM>()
                .in(RStatOrgM::getOrgNo, deptListCode)
                .eq(RStatOrgM::getDataType, dictData.getId())
                .ge(StringUtils.isNotBlank(param.getStartTime()), RStatOrgM::getDataDate, param.getStartTime())
                .le(StringUtils.isNotBlank(param.getEndTime()), RStatOrgM::getDataDate, param.getEndTime())
        );

        //根据部门进行分组
        Map<String, List<RStatOrgM>> orgNoMap = list.stream().collect(Collectors.groupingBy(RStatOrgM::getOrgNo));

        orgNoMap.forEach((key,value)->{
            if(deptMap.containsKey(key)){
                OverviewVO.GroupVO groupVO=new OverviewVO.GroupVO();
                String name = deptMap.get(key).getName();
                String replace = name.replace("供电公司","");
                if(XIONG_AN_CITY.equals(replace)){
                    groupVO.setCity(XIONG_AN_CITY);
                }else{
                    groupVO.setCity(replace+"市");
                }
                groupVO.setOneLine(0);
                groupVO.setTwoLine(0);
                groupVO.setThreeLine(0);
                for (RStatOrgM statOrgM : value) {
                    if (dictDataMap.containsKey(statOrgM.getMeasurementTypeClass())) {
                        DictData data = dictDataMap.get(statOrgM.getMeasurementTypeClass());
                        //一类监测点
                        if(DicDataEnum.ONE_LINE.getCode().equals(data.getCode())){
                            groupVO.setOneLine(statOrgM.getEffectiveMeasurementAccrued());
                        }
                        //二类监测点
                        if(DicDataEnum.TWO_LINE.getCode().equals(data.getCode())){
                            groupVO.setTwoLine(statOrgM.getEffectiveMeasurementAccrued());
                        }
                        //三类监测点
                        if(DicDataEnum.THREE_LINE.getCode().equals(data.getCode())){
                            groupVO.setThreeLine(statOrgM.getEffectiveMeasurementAccrued());
                        }
                    }
                }
                info.add(groupVO);
            }
        });
        List<DeptDTO> deptDTOS = subDeptListCode.stream().filter(r -> !orgNoMap.containsKey(r.getId()))
                .collect(Collectors.toList());
        OverviewVO.GroupVO groupVO;

        for (DeptDTO deptDTO : deptDTOS) {
            groupVO=new OverviewVO.GroupVO();
            String replace = deptDTO.getName().replace("供电公司","");
            if(XIONG_AN_CITY.equals(replace)){
                groupVO.setCity(XIONG_AN_CITY);
            }else{
                groupVO.setCity(replace+"市");
            }
            groupVO.setOneLine(0);
            groupVO.setTwoLine(0);
            groupVO.setThreeLine(0);
            info.add(groupVO);
        }
        return info;
    }


    /**
     * 当前部门下子部门通用方法
     * @param deptId
     * @return
     */
    public List<DeptDTO> getSubDeptListCode(String deptId){
        List<DeptDTO> deptDTOList = deptFeignClient.getDeptDescendantIndexes(deptId, WebUtil.filterDeptType()).getData();
        //获取子部门
        List<DeptDTO> directDeptInfos = deptDTOList.stream()
                .filter(deptDTO -> deptDTO.getPid().equals(deptId))
                .collect(Collectors.toList());
        if (CollectionUtil.isEmpty(directDeptInfos)) {
            //没有直接子部门，获取当前部门所有信息
            List<DeptDTO> dept = deptDTOList.stream()
                    .filter(deptDTO -> deptDTO.getId().equals(deptId))
                    .collect(Collectors.toList());
            return dept;
        }
        return directDeptInfos;
    }

}
