package com.njcn.harmonic.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import com.njcn.common.config.GeneralInfo;
import com.njcn.device.pq.api.GeneralDeviceInfoClient;
import com.njcn.device.pq.pojo.dto.GeneralDeviceDTO;
import com.njcn.device.pq.pojo.param.DeviceInfoParam;
import com.njcn.device.pq.pojo.param.OnlineRateParam;
import com.njcn.device.pq.pojo.vo.RStatOnlineRateVO;
import com.njcn.harmonic.mapper.TerminalDataMapper;
import com.njcn.harmonic.pojo.dto.PublicDTO;
import com.njcn.harmonic.pojo.vo.TerminalCensusVO;
import com.njcn.harmonic.pojo.vo.TerminalVO;
import com.njcn.harmonic.service.TerminalService;
import com.njcn.harmonic.utils.PubUtils;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;


/**
 * @author: chenchao
 * @date: 2022/03/02 19:25
 * @Description: <描述>
 */
@Service
@AllArgsConstructor
public class TerminalServiceImpl implements TerminalService {

    private final GeneralDeviceInfoClient generalDeviceInfoClient;

    private final GeneralInfo generalInfo;

    private final TerminalDataMapper terminalDataMapper;

    @Override
    public List<TerminalVO> getTerminalData(DeviceInfoParam.BusinessParam terminalParam) {
        List<TerminalVO> terminalList = new ArrayList<>();
        //按照条件获取所有终端综合信息
        List<GeneralDeviceDTO> deviceDataList = generalDeviceInfoClient.getPracticalAllDeviceInfo(new DeviceInfoParam(terminalParam.getStatisticalType(), terminalParam.getDeptIndex(), generalInfo.getMicroServiceName(), null, terminalParam.getManufacturer(), null)).getData();
        //组装终端Top层集合
        for (GeneralDeviceDTO generalDeviceDTO : deviceDataList) {
            List<String> deviceIndexes = generalDeviceDTO.getDeviceIndexes();
            if (CollectionUtils.isEmpty(deviceIndexes)) {
                continue;
            }
            TerminalVO terminalVO = new TerminalVO();
            terminalVO.setId(generalDeviceDTO.getIndex());
            terminalVO.setName(generalDeviceDTO.getName());
            //获取终端相关信息
            List<TerminalVO> terminalData = terminalDataMapper.getTerminalData(deviceIndexes);
            for (TerminalVO item: terminalData) {
                setDeviceFlag(item.getFlag(), terminalVO);
            }
            terminalVO.setFlag(null);
            //查找在线率
            List<PublicDTO> condition = getCondition(deviceIndexes, terminalParam.getSearchBeginTime(), terminalParam.getSearchEndTime());
            terminalVO.setOnlineRateData(PubUtils.dataLimits(condition.stream().mapToDouble(PublicDTO::getData).average().orElse(3.14159)));
            terminalVO.setNumber(generalDeviceDTO.getDeviceIndexes().size());
            //组装父级数据树
            List<TerminalVO> treeList = getTreeData(deviceIndexes, terminalParam);
            terminalVO.setChildren(treeList);
            terminalList.add(terminalVO);
        }
        return terminalList;
    }

    @Override
    public TerminalCensusVO getTerminalDataCensus(DeviceInfoParam.BusinessParam terminalCensusParam) {
        TerminalCensusVO terminalCensusVO = new TerminalCensusVO();
        terminalCensusParam.setServerName(generalInfo.getMicroServiceName());
//        List<GeneralDeviceDTO> generalDeviceDTOList = generalDeviceInfoClient.getPracticalRunDeviceInfo(terminalCensusParam).getData();
        List<GeneralDeviceDTO> generalDeviceDTOList = generalDeviceInfoClient.getPracticalAllDeviceInfo(new DeviceInfoParam(terminalCensusParam.getStatisticalType(), terminalCensusParam.getDeptIndex(), generalInfo.getMicroServiceName(), null, terminalCensusParam.getManufacturer(), null)).getData();
        List<String> type = new ArrayList<>();
        List<Double> single = new ArrayList<>();
        List<Integer> runFlag = new ArrayList<>(),reaFlag = new ArrayList<>(),stopFlag = new ArrayList<>();
        if (!CollectionUtils.isEmpty(generalDeviceDTOList)) {
            for (GeneralDeviceDTO generalDeviceDTO : generalDeviceDTOList) {
                if (CollectionUtils.isEmpty(generalDeviceDTO.getDeviceIndexes())) {
                    continue;
                }
                type.add(generalDeviceDTO.getName()+"\n("+generalDeviceDTO.getDeviceIndexes().size()+"台)");
                List<String> deviceIndexes = generalDeviceDTO.getDeviceIndexes();
                //根据终端查询在线率
                List<PublicDTO> condition = getCondition(deviceIndexes, terminalCensusParam.getSearchBeginTime(), terminalCensusParam.getSearchEndTime());
                single.add(condition.stream().mapToDouble(PublicDTO::getData).average().orElse(3.14159));
                //获取终端相关信息
                List<TerminalVO> terminalData = terminalDataMapper.getTerminalData(deviceIndexes);
                int run=0,rea=0,stop=0;
                for (TerminalVO terminalVO: terminalData) {
                    if (terminalVO.getFlag() == 0) {
                        ++run;
                    }
                    if (terminalVO.getFlag() == 1) {
                        ++rea;
                    }
                    if (terminalVO.getFlag() == 2) {
                        ++stop;
                    }
                    terminalVO.setFlag(null);
                }
                runFlag.add(run);
                reaFlag.add(rea);
                stopFlag.add(stop);
            }
        }
        terminalCensusVO.setType(type);
        terminalCensusVO.setSingle(single);
        terminalCensusVO.setRunFlag(runFlag);
        terminalCensusVO.setReaFlag(reaFlag);
        terminalCensusVO.setStopFlag(stopFlag);
        return terminalCensusVO;
    }

    //保存终端运行状态
    private void setDeviceFlag(Integer flag, TerminalVO terminalVO) {
        if (flag==0) {
            int a = terminalVO.getRunFlag();
            terminalVO.setRunFlag(++a);
        }
        if (flag==1) {
            int b = terminalVO.getReaFlag();
            terminalVO.setReaFlag(++b);
        }
        if (flag==2) {
            int c = terminalVO.getStopFlag();
            terminalVO.setStopFlag(++c);
        }
        terminalVO.setFlag(flag);
    }

    //设置层级终端信息
    private void setTreeFlag(List<TerminalVO> list, List<TerminalVO> childList) {
        list.forEach(terminalVO -> {
            childList.forEach(terminalVO1 -> {
                if (terminalVO.getId().equals(terminalVO1.getPid())) {
                    int num = terminalVO1.getRunFlag()+terminalVO1.getReaFlag()+terminalVO1.getStopFlag();
                    terminalVO.setNumber(terminalVO.getNumber() + num);
                    terminalVO.setRunFlag(terminalVO1.getRunFlag() + terminalVO.getRunFlag());
                    terminalVO.setReaFlag(terminalVO1.getReaFlag() + terminalVO.getReaFlag());
                    terminalVO.setStopFlag(terminalVO1.getStopFlag() + terminalVO.getStopFlag());
                }
            });
        });
    }


    /**
     * 获取树的每层级数据
     */
    public List<TerminalVO> getTreeData(List<String> deviceIndexes, DeviceInfoParam.BusinessParam terminalParam) {
        //终端集合
        List<TerminalVO> deviceList = terminalDataMapper.getTerminalData(deviceIndexes);
        //变电站集合
        List<TerminalVO> substationList = terminalDataMapper.getLineInfoByList(deviceList.stream().map(TerminalVO::getPid).distinct().collect(Collectors.toList()));
        //供电公司集合
        List<TerminalVO> powerCompanyList = terminalDataMapper.getLineInfoByList(substationList.stream().map(TerminalVO::getPid).distinct().collect(Collectors.toList()));
        //查询终端的在线率
        List<PublicDTO> onlineRateList = getCondition(deviceIndexes, terminalParam.getSearchBeginTime(), terminalParam.getSearchEndTime());
        //根据终端集合组装终端的在线率
        if (!CollectionUtils.isEmpty(deviceList)) {
            deviceList.stream().map(list1 -> onlineRateList.stream().filter(list2 -> Objects.equals(list1.getId(), list2.getId())).findAny().map(m -> {
                list1.setOnlineRateData(PubUtils.dataLimits(m.getData()));
                return list1;
            })).collect(Collectors.toList());
            for (TerminalVO terminalVO: deviceList) {
                Integer flag = terminalVO.getFlag();
                setDeviceFlag(flag, terminalVO);
                terminalVO.setFlag(null);
            }
        }

        substationList.stream().peek(item -> item.setChildren(getChildCategoryList(item, deviceList))).collect(Collectors.toList());
        setTreeFlag(substationList, deviceList);

        powerCompanyList.stream().peek(item -> item.setChildren(getChildCategoryList(item, substationList))).collect(Collectors.toList());
        setTreeFlag(powerCompanyList,substationList);

        setFatherOnlineRate(substationList,3);
        setFatherOnlineRate(powerCompanyList,2);
        // setAreaIntegrity(areaList);
        return powerCompanyList;
    }


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


    /**
     * influxDB相关操作
     *
     * @param deviceIndexes
     * @param startTime
     * @param endTime
     */
    private List<PublicDTO> getCondition(List<String> deviceIndexes, String startTime, String endTime) {
        List<PublicDTO> publicDTOList = new ArrayList<>();
        OnlineRateParam param=new OnlineRateParam();
        param.setIds(deviceIndexes);
        param.setStartTime( DateUtil.beginOfDay(DateUtil.parse(startTime)).toString());
        param.setEndTime( DateUtil.endOfDay(DateUtil.parse(endTime)).toString());
        List<RStatOnlineRateVO> data = generalDeviceInfoClient.getOnlineRateByDevIds(param).getData();
        if (CollUtil.isNotEmpty(data)) {
            data.forEach(po -> {
                PublicDTO publicDTO = new PublicDTO();
                //终端在线率 保留两位小数
                Double onlineRate = po.getOnlineRate() == null ? null : BigDecimal.valueOf(Double.parseDouble(po.getOnlineRate().toString())).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
                publicDTO.setId(po.getDevIndex());
                publicDTO.setData(PubUtils.dataLimits(onlineRate));
                publicDTOList.add(publicDTO);
            });
        }
        return publicDTOList;




//        //组装sql语句
//        StringBuilder stringBuilder = new StringBuilder();
//        stringBuilder.append(InfluxDBPublicParam.TIME + " >= '").append(startTime).append(InfluxDBPublicParam.START_TIME).append("' and ").append(InfluxDBPublicParam.TIME).append(" <= '").append(endTime).append(InfluxDBPublicParam.END_TIME).append("' and (");
//        for (int i = 0; i < deviceIndexes.size(); i++) {
//            if (deviceIndexes.size() - i != 1) {
//                stringBuilder.append(InfluxDBPublicParam.DEV_INDEX + "='").append(deviceIndexes.get(i)).append("' or ");
//            } else {
//                stringBuilder.append(InfluxDBPublicParam.DEV_INDEX + "='").append(deviceIndexes.get(i)).append("')");
//            }
//        }
//        //sql语句
//        String sql = "SELECT (SUM(" + InfluxDBPublicParam.ONLINE_MIN + ")/(SUM(" + InfluxDBPublicParam.OFFLINE_MIN + ")+SUM(" + InfluxDBPublicParam.ONLINE_MIN + ")))*100 AS onlineRate FROM "+InfluxDBPublicParam.PQS_ONLINERATE+" WHERE " + stringBuilder + " group by " + InfluxDBPublicParam.DEV_INDEX + InfluxDBPublicParam.TIME_ZONE;
//        //结果集
//        QueryResult result = influxDbUtils.query(sql);
//        //处理结果集
//        List<QueryResult.Series> list = result.getResults().get(0).getSeries();
//        if (!CollectionUtils.isEmpty(list)) {
//            list.forEach(po -> {
//                PublicDTO publicDTO = new PublicDTO();
//                List<List<Object>> valueList = po.getValues();
//                String index = po.getTags().get(InfluxDBPublicParam.DEV_INDEX);
//                if (!CollectionUtils.isEmpty(valueList)) {
//                    for (List<Object> value : valueList) {
//                        //终端在线率 保留两位小数
//                        Double onlineRate = value.get(1) == null ? null : BigDecimal.valueOf(Double.parseDouble(value.get(1).toString())).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
//                        publicDTO.setId(index);
//                        publicDTO.setData(onlineRate);
//                    }
//                }
//                publicDTOList.add(publicDTO);
//            });
//        }
//        return publicDTOList;
    }

    /**
     * 计算该子层级终端在线率
     */
    private void setFatherOnlineRate(List<TerminalVO> list,Integer level) {
        List<TerminalVO> buttonList = new ArrayList<>(),tempList = new ArrayList<>();
        for (TerminalVO item : list) {
            List<TerminalVO> children = item.getChildren();
            if (Objects.equals(level,2)){
                for (TerminalVO item2 : children) {
                    buttonList.addAll(item2.getChildren());
                    tempList = buttonList.stream().filter(s -> !Objects.equals(s.getOnlineRateData(), 3.14159)).collect(Collectors.toList());
                }
            } else if (Objects.equals(level,3)){
                tempList = children.stream().filter(s -> !Objects.equals(s.getOnlineRateData(), 3.14159)).collect(Collectors.toList());
            }
            if (!CollectionUtils.isEmpty(tempList)) {
                item.setOnlineRateData(PubUtils.dataLimits(tempList.stream().mapToDouble(TerminalVO::getOnlineRateData).sum() / tempList.size()));
            } else {
                item.setOnlineRateData(3.14159);
            }
        }
    }

}
