package com.njcn.harmonic.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.njcn.common.config.GeneralInfo;
import com.njcn.common.pojo.dto.SimpleDTO;
import com.njcn.common.pojo.param.StatisticsBizBaseParam;
import com.njcn.device.pq.api.GeneralDeviceInfoClient;
import com.njcn.device.pq.api.LineFeignClient;
import com.njcn.device.pq.enums.LineBaseEnum;
import com.njcn.device.pq.pojo.dto.GeneralDeviceDTO;
import com.njcn.device.pq.pojo.param.DeviceInfoParam;
import com.njcn.device.pq.pojo.vo.LineDetailDataVO;
import com.njcn.harmonic.mapper.RMpVThdMapper;
import com.njcn.harmonic.mapper.THDistortionMapper;
import com.njcn.harmonic.pojo.dto.PublicDTO;
import com.njcn.harmonic.pojo.po.RMpVThd;
import com.njcn.harmonic.pojo.vo.RMpVThdVO;
import com.njcn.harmonic.pojo.vo.THDistortionCensusVO;
import com.njcn.harmonic.pojo.vo.THDistortionVO;
import com.njcn.harmonic.service.IRStatDataVDService;
import com.njcn.harmonic.service.THDistortionService;
import com.njcn.harmonic.utils.PubUtils;
import lombok.AllArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

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

/**
 * @author: chenchao
 * @date: 2022/03/11 10:09
 * @Description: <描述>
 */
@Service
@AllArgsConstructor
public class THDistortionServiceImpl implements THDistortionService {

    private final GeneralInfo generalInfo;

    private final GeneralDeviceInfoClient generalDeviceInfoClient;

    private final THDistortionMapper thDistortionMapper;

    private final RMpVThdMapper rMpVThdMapper;

    private final LineFeignClient lineFeignClient;

    private final IRStatDataVDService statDataVDService;

    @Override
    public List<THDistortionVO> getTHDistortionData(DeviceInfoParam.BusinessParam thDistortionParam) {
        List<THDistortionVO> thDistortionVOS = new ArrayList<>();

        //按照条件获取实际运行终端综合信息
        List<GeneralDeviceDTO> deviceList = generalDeviceInfoClient.getPracticalRunDeviceInfo(new DeviceInfoParam(thDistortionParam.getStatisticalType(), thDistortionParam.getDeptIndex(), generalInfo.getMicroServiceName(), thDistortionParam.getScale(), thDistortionParam.getManufacturer(), thDistortionParam.getLoadType())).getData();
        //组装监测点Top层集合
        for (GeneralDeviceDTO generalDeviceDTO : deviceList) {
            List<String> lineIndexes = generalDeviceDTO.getLineIndexes();
            if (CollectionUtils.isEmpty(lineIndexes)) {
                continue;
            }
            THDistortionVO thDistortionVO = new THDistortionVO();
            thDistortionVO.setId(generalDeviceDTO.getIndex());
            thDistortionVO.setName(generalDeviceDTO.getName());

            //查找畸变率
            List<PublicDTO> condition = getCondition(lineIndexes, thDistortionParam.getSearchBeginTime(), thDistortionParam.getSearchEndTime());
            thDistortionVO.setDistortion(roundHalfUp(condition.stream().mapToDouble(PublicDTO::getData).average().orElse(3.14159)));
            //组装父级数据树
            List<THDistortionVO> treeList = getTreeData(lineIndexes, condition);
            thDistortionVO.setChildren(treeList);


            thDistortionVOS.add(thDistortionVO);
        }

        return thDistortionVOS;
    }

    @Override
    public THDistortionCensusVO getTHDistortionCensus(DeviceInfoParam.BusinessParam thDistortionCensusParam) {
        THDistortionCensusVO distortionCensusVO = new THDistortionCensusVO();
        thDistortionCensusParam.setServerName(generalInfo.getMicroServiceName());
        List<GeneralDeviceDTO> generalDeviceDTOList = generalDeviceInfoClient.getPracticalRunDeviceInfo(thDistortionCensusParam).getData();
        List<String> type = new ArrayList<>();
        List<Double> single = new ArrayList<>();
        if (!CollectionUtils.isEmpty(generalDeviceDTOList)) {
            for (GeneralDeviceDTO generalDeviceDTO : generalDeviceDTOList) {
                List<String> lineIndexes = generalDeviceDTO.getLineIndexes();
                if (CollectionUtils.isEmpty(lineIndexes)) {
                    continue;
                }
                type.add(generalDeviceDTO.getName()+"\n("+generalDeviceDTO.getLineIndexes().size()+")");
                List<PublicDTO> condition = getCondition(lineIndexes, thDistortionCensusParam.getSearchBeginTime(), thDistortionCensusParam.getSearchEndTime());
                single.add(roundHalfUp(condition.stream().mapToDouble(PublicDTO::getData).average().orElse(3.14159)));
            }
            distortionCensusVO.setType(type);
            distortionCensusVO.setSingle(single);
        }
        return distortionCensusVO;
    }

    /**
     * @param statisticsBizBaseParam
     * @Description: 谐波总畸变率前十列表
     * @Param: [statisticsBizBaseParam]
     * @return: java.util.List<com.njcn.harmonic.pojo.vo.RMpVThdVO>
     * @Author: clam
     * @Date: 2022/10/10
     */
    @Override
    public List<RMpVThdVO> getTHDTopTenData(StatisticsBizBaseParam statisticsBizBaseParam, Integer topNum) {

        List<RMpVThdVO> rMpVThdVOList = new ArrayList<>();
        DeviceInfoParam deviceInfoParam = new DeviceInfoParam();
        deviceInfoParam.setDeptIndex(statisticsBizBaseParam.getId());
        deviceInfoParam.setStatisticalType(new SimpleDTO());
        deviceInfoParam.setServerName(generalInfo.getMicroServiceName());
        deviceInfoParam.setPowerFlag(2);
        deviceInfoParam.setMonitorFlag(2);
        /*获取按部门分类的实际所有终端综合信息*/
        List<GeneralDeviceDTO> deviceList = generalDeviceInfoClient.getPracticalAllDeviceInfoAsDept(deviceInfoParam).getData();
        /*监测点ID扁平化*/
        List<String> collect = deviceList.stream().map(GeneralDeviceDTO::getLineIndexes).flatMap(Collection::stream).distinct().collect(Collectors.toList());
        QueryWrapper<RMpVThd> wrapper = new QueryWrapper<>();
        wrapper.select("measurement_point_id", "max(v_thd) as v_thd")
                .in("measurement_point_id", collect)
                .between("data_date", statisticsBizBaseParam.getStartTime(), statisticsBizBaseParam.getEndTime())
                .eq("data_type", 0).groupBy("measurement_point_id")
                .orderByDesc("v_thd");
        List<RMpVThd> rMpVThdList = rMpVThdMapper.selectList(wrapper);
        rMpVThdVOList = rMpVThdList.stream().limit(topNum).map(rMpVThd -> {
            RMpVThdVO rMpVThdVO = new RMpVThdVO();
            BeanUtils.copyProperties(rMpVThd, rMpVThdVO);
            /*查询监测点详情获取名称*/
            LineDetailDataVO data = lineFeignClient.getLineDetailData(rMpVThd.getMeasurementPointId()).getData();
            rMpVThdVO.setName(data.getLineName());
            return rMpVThdVO;
        }).collect(Collectors.toList());

        return rMpVThdVOList;
    }


    /**
     * 计算父级畸变率
     */
    private void setFatherDistortion(List<THDistortionVO> list) {
        list.forEach(thDistortionVO -> {
            List<THDistortionVO> children = thDistortionVO.getChildren();
            List<THDistortionVO> tempList = children.stream().filter(child -> !Objects.equals(child.getDistortion(), 3.14159)).collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(tempList)) {
                thDistortionVO.setDistortion(roundHalfUp(tempList.stream().mapToDouble(THDistortionVO::getDistortion).average().orElse(3.14159)));
            } else {
                thDistortionVO.setDistortion(3.14159);
            }
        });
    }

    /**
     * 组装树层级
     */
    private List<THDistortionVO> getChildCategoryList(THDistortionVO item, List<THDistortionVO> child) {
        return child.stream().filter(allItem -> allItem.getPid().equals(item.getId())).collect(Collectors.toList());
    }

    private void setChildesList(List<THDistortionVO> item, List<THDistortionVO> childes) {
        //groupLine变电站索引和监测点集合
        Map<String, List<THDistortionVO>> groupLine;
        groupLine = childes.stream().collect(Collectors.groupingBy(thDistortionVO -> {
            String[] pid = thDistortionVO.getPidS().split(",");
            return pid[LineBaseEnum.SUB_LEVEL.getCode()];
        }));
        item.stream().peek(thDistortionVO -> {
            if (!CollectionUtils.isEmpty(groupLine.get(thDistortionVO.getId()))) {
                thDistortionVO.setChildren(groupLine.get(thDistortionVO.getId()));
            }
        }).collect(Collectors.toList());
    }

    /**
     * 获取父级每层数据
     */
    private List<THDistortionVO> getTreeData(List<String> lineIndexes,List<PublicDTO> condition) {
        //监测点集合
        List<THDistortionVO> monitorList = thDistortionMapper.getLineData(lineIndexes);
        //母线集合
        List<THDistortionVO> busBarList = thDistortionMapper.getLineInfoByList(monitorList.stream().map(THDistortionVO::getPid).distinct().collect(Collectors.toList()));
        //终端集合
        List<THDistortionVO> deviceList = thDistortionMapper.getLineInfoByList(busBarList.stream().map(THDistortionVO::getPid).distinct().collect(Collectors.toList()));
        //变电站集合
        List<THDistortionVO> substationList = thDistortionMapper.getLineInfoByList(deviceList.stream().map(THDistortionVO::getPid).distinct().collect(Collectors.toList()));
        //供电公司集合
        List<THDistortionVO> powerCompanyList = thDistortionMapper.getLineInfoByList(substationList.stream().map(THDistortionVO::getPid).distinct().collect(Collectors.toList()));


        if (!CollectionUtils.isEmpty(monitorList)) {
            Map<String, PublicDTO> map = condition.stream().collect(Collectors.toMap(PublicDTO::getId, Function.identity()));

            for(THDistortionVO thDistortionVO:monitorList) {
                if (map.containsKey(thDistortionVO.getId())) {
                    thDistortionVO.setDistortion(map.get(thDistortionVO.getId()).getData());
                }
            }
            setChildesList(substationList, monitorList);
            setFatherDistortion(substationList);
            powerCompanyList = powerCompanyList.stream().peek(item -> item.setChildren(getChildCategoryList(item, substationList))).collect(Collectors.toList());
            setFatherDistortion(powerCompanyList);

        }
        return powerCompanyList;
    }

    /**
     * 四舍五入保留两位小数
     */
    private Double roundHalfUp(double num) {
        if (num == 3.14159) {
            return num;
        }
        BigDecimal b = new BigDecimal(num);
        //保留2位小数
        return PubUtils.dataLimits(b.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
    }


    /**
     * influxDB查询畸变率
     *
     * @param lineIndexes
     * @param startTime
     * @param endTime
     */
    private List<PublicDTO> getCondition(List<String> lineIndexes, String startTime, String endTime) {
        List<PublicDTO> publicDTOList = new ArrayList<>();
        //数据库查询
        QueryWrapper<RMpVThd> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("max(v_thd) vThd,measurement_point_id").lambda()
                .in(RMpVThd::getMeasurementPointId, lineIndexes)
                .ge(StrUtil.isNotBlank(startTime), RMpVThd::getDataDate, DateUtil.beginOfDay(DateUtil.parse(startTime)))
                .le(StrUtil.isNotBlank(endTime), RMpVThd::getDataDate, DateUtil.endOfDay(DateUtil.parse(endTime)))
                .eq(RMpVThd::getDataType, 0).groupBy(RMpVThd::getMeasurementPointId);

        List<RMpVThd> info = rMpVThdMapper.selectList(queryWrapper);
        if (CollUtil.isNotEmpty(info)) {
            info.forEach(item->{
                PublicDTO publicDTO = new PublicDTO();
                publicDTO.setId(item.getMeasurementPointId());
                publicDTO.setData(item.getVThd());
                publicDTOList.add(publicDTO);
            });
        }
        return publicDTOList;
    }


}
