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

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.njcn.common.pojo.dto.SimpleDTO;
import com.njcn.common.pojo.enums.common.DataStateEnum;
import com.njcn.device.pms.mapper.majornetwork.MonitorMapper;
import com.njcn.device.pms.pojo.dto.PmsGeneralDeviceDTO;
import com.njcn.device.pms.pojo.param.PmsDeviceInfoParam;
import com.njcn.device.pms.pojo.param.PmsSummaryStatisticsParam;
import com.njcn.device.pms.pojo.po.Monitor;
import com.njcn.device.pms.pojo.vo.PmsSummaryStatisticsVO;
import com.njcn.device.pms.service.majornetwork.IPmsGeneralDeviceService;
import com.njcn.device.pms.service.majornetwork.PmsSummaryStatisticsService;
import com.njcn.user.api.DeptFeignClient;
import com.njcn.user.pojo.dto.DeptDTO;
import com.njcn.web.utils.WebUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

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

/**
 * <台账汇总统计>
 *
 * @author wr
 * @createTime: 2023-02-17
 */
@Service
@RequiredArgsConstructor
public class PmsSummaryStatisticsServiceImpl implements PmsSummaryStatisticsService {


    private final DeptFeignClient deptFeignClient;
    private final MonitorMapper monitorMapper;
    private final IPmsGeneralDeviceService generalPmsDeviceService;;


    @Override
    public List<PmsSummaryStatisticsVO.SummaryVO> getSeparate(PmsSummaryStatisticsParam param) {
        List<PmsSummaryStatisticsVO.SummaryVO> vos = new ArrayList<>();
        //获取当前部门下的子部门

        if (param.getType().equals(0)) {
            PmsDeviceInfoParam pmsDeviceInfoParam = new PmsDeviceInfoParam();
            pmsDeviceInfoParam.setDeptIndex(param.getOrgId());
            pmsDeviceInfoParam.setStatisticalType(new SimpleDTO());
            List<PmsGeneralDeviceDTO> deptData = generalPmsDeviceService.getPmsDeviceInfoWithInOrg(pmsDeviceInfoParam);
            deptData.forEach(item -> {
                PmsSummaryStatisticsVO.SummaryVO vo = new PmsSummaryStatisticsVO.SummaryVO();
                vo.setName(item.getName());
                vo.setMonitorCount(item.getMonitorIdList().size());
                vo.setTerminalCount(item.getTerminalIdList().size());
                vos.add(vo);
            });
        } else {
            //获取当前部门下的子部门
            List<DeptDTO> data = deptFeignClient.getDeptDescendantIndexes(param.getOrgId(), WebUtil.filterDeptType()).getData();

            List<String> deptIds = data.stream().map(DeptDTO::getCode).collect(Collectors.toList());

            //获得部门下面的数据集合
            List<Monitor> monitors = monitorMapper.selectList(new LambdaQueryWrapper<Monitor>()
                    .in(CollectionUtil.isNotEmpty(deptIds), Monitor::getOrgId, deptIds)
                    .in(CollectionUtil.isNotEmpty(param.getMonitorTags()), Monitor::getMonitorTag, param.getMonitorTags())
                    .eq(Monitor::getStatus, DataStateEnum.ENABLE.getCode())
            );
            //根据干扰源类型进行分组统计当前部门下有多少监测点
            Map<String, List<Monitor>> monitorsMonitorCount = monitors.stream().collect(Collectors.groupingBy(Monitor::getMonitorTag));
            PmsSummaryStatisticsVO.SummaryVO vo;
            for (String monitorTag : param.getMonitorTags()) {
                vo = new PmsSummaryStatisticsVO.SummaryVO();
                if (monitorsMonitorCount.containsKey(monitorTag)) {
                    List<Monitor> monitorsTag = monitorsMonitorCount.get(monitorTag);
                    long count = monitorsTag.stream().map(Monitor::getTerminalId).distinct().count();
                    vo.setName(monitorTag);
                    //监测点数量
                    vo.setMonitorCount(monitorsTag.size());
                    //设备数量
                    vo.setTerminalCount(Math.toIntExact(count));
                } else {
                    vo.setName(monitorTag);
                    //监测点数量
                    vo.setMonitorCount(0);
                    //设备数量
                    vo.setTerminalCount(0);
                }
                vos.add(vo);
            }
            PmsSummaryStatisticsVO.SummaryVO count = new PmsSummaryStatisticsVO.SummaryVO();
            count.setName("总数");
            count.setMonitorCount(Math.toIntExact(monitors.stream().map(Monitor::getId).distinct().count()));
            count.setTerminalCount(Math.toIntExact(monitors.stream().map(Monitor::getTerminalId).distinct().count()));
            vos.add(count);
        }
        return vos;
    }

    @Override
    public List<PmsSummaryStatisticsVO> getMainnetPoint(PmsSummaryStatisticsParam param) {
        List<PmsSummaryStatisticsVO> vos = new ArrayList<>();
        //获取当前部门下的子部门
        List<DeptDTO> data = deptFeignClient.getDepSonDetailByDeptId(param.getOrgId()).getData();

        List<String> deptIds = data.stream().map(DeptDTO::getCode).collect(Collectors.toList());
        Map<String, String> deptMap = data.stream().collect(Collectors.toMap(DeptDTO::getCode, DeptDTO::getName));

        //获得部门下面的数据集合
        List<Monitor> monitors = monitorMapper.selectList(new LambdaQueryWrapper<Monitor>()
                .in(Monitor::getOrgId, deptIds)
                .in(Monitor::getMonitorTag, param.getMonitorTags())
                .eq(Monitor::getStatus, 1)
        );

        //根据部门进行分组统计当前部门下有多少监测点
        Map<String, List<Monitor>> monitorsMonitorCount = monitors.stream().collect(Collectors.groupingBy(Monitor::getOrgId));

        //根据部门统计终端数量
        ArrayList<Monitor> monitorsCount = monitors.stream().collect(Collectors.collectingAndThen
                (Collectors.toCollection(() ->
                        new TreeSet<>(Comparator.comparing(o -> o.getOrgId() + ";" + o.getTerminalId()))), ArrayList::new));
        Map<String, Long> monitorsTerminalCount = monitorsCount.stream().collect(Collectors.groupingBy(Monitor::getOrgId, Collectors.counting()));

        deptMap.forEach((key, value) -> {
            PmsSummaryStatisticsVO vo = new PmsSummaryStatisticsVO();
            if (monitorsMonitorCount.containsKey(key)) {
                vo.setName(value);
                vo.setMonitorCount(monitorsMonitorCount.get(key).size());
                vo.setTerminalCount(Math.toIntExact(monitorsTerminalCount.get(key)));
                //子集
                List<PmsSummaryStatisticsVO.SummaryVO> voNodes = new ArrayList<>();
                PmsSummaryStatisticsVO.SummaryVO voNode;
                //根据干扰源类型分组统计(监测点数量)
                Map<String, Long> monitorsNum = monitorsMonitorCount.get(key).stream().collect(Collectors.groupingBy(Monitor::getMonitorTag, Collectors.counting()));

                ArrayList<Monitor> monitorsCounts = monitorsMonitorCount.get(key).stream().collect(Collectors.collectingAndThen
                        (Collectors.toCollection(() ->
                                new TreeSet<>(Comparator.comparing(o -> o.getOrgId() + ";" + o.getTerminalId()))), ArrayList::new));

                //根据部门统计有多少干扰源(设备数量)
                Map<String, Long> monitorsNum2 = monitorsCounts.stream().collect(Collectors.groupingBy(Monitor::getMonitorTag, Collectors.counting()));
                for (String monitorTag : param.getMonitorTags()) {
                    voNode = new PmsSummaryStatisticsVO.SummaryVO();
                    if (monitorsNum.containsKey(monitorTag)) {
                        voNode.setName(monitorTag);
                        //监测点数量
                        voNode.setMonitorCount(Math.toIntExact(monitorsNum.get(monitorTag)));
                        //设备数量
                        voNode.setTerminalCount(Math.toIntExact(monitorsNum2.get(monitorTag)));

                    } else {
                        voNode.setName(monitorTag);
                        //监测点数量
                        voNode.setMonitorCount(0);
                        //设备数量
                        voNode.setTerminalCount(0);
                    }
                    voNodes.add(voNode);
                }
                vo.setStatisticsVOList(voNodes);
            } else {
                vo.setName(value);
                vo.setMonitorCount(0);
                vo.setTerminalCount(0);
                List<PmsSummaryStatisticsVO.SummaryVO> voNodes = new ArrayList<>();
                PmsSummaryStatisticsVO.SummaryVO voNode;
                for (String monitorTag : param.getMonitorTags()) {
                    voNode = new PmsSummaryStatisticsVO.SummaryVO();
                    voNode.setName(monitorTag);
                    //监测点数量
                    voNode.setMonitorCount(0);
                    //设备数量
                    voNode.setTerminalCount(0);
                    voNodes.add(voNode);
                }
                vo.setStatisticsVOList(voNodes);
            }
            vos.add(vo);
        });

        return vos;
    }

    @Override
    public List<PmsSummaryStatisticsVO.SummaryVO> getDistributionPoint(PmsSummaryStatisticsParam.PwSummaryStatisticsParam param) {
        PmsDeviceInfoParam pmsDeviceInfoParam = new PmsDeviceInfoParam();
        pmsDeviceInfoParam.setDeptIndex(param.getOrgId());
        pmsDeviceInfoParam.setStatisticalType(new SimpleDTO());
        return generalPmsDeviceService.getPmsDeviceAndMonitor(pmsDeviceInfoParam);
    }

}
