package com.ruoyi.business.service.impl;

import com.ruoyi.business.domain.HwAlarmInfo;
import com.ruoyi.business.domain.HwDevice;
import com.ruoyi.business.domain.HwMonitorUnit;
import com.ruoyi.business.domain.VO.*;
import com.ruoyi.business.mapper.HwAlarmInfoMapper;
import com.ruoyi.business.mapper.HwDeviceMapper;
import com.ruoyi.business.mapper.HwElectronicFenceMapper;
import com.ruoyi.business.mapper.HwMonitorUnitMapper;
import com.ruoyi.business.service.IHwMonitorUnitService;
import com.ruoyi.common.core.constant.TdEngineConstants;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.utils.DateUtils;
import com.ruoyi.common.core.utils.NumberUtils;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.datascope.annotation.DataScope;
import com.ruoyi.tdengine.api.RemoteTdEngineService;
import com.ruoyi.tdengine.api.domain.DeviceStatus;
import com.ruoyi.tdengine.api.domain.TdSelectDto;
import com.ruoyi.tdengine.api.domain.TdSuperTableSelectVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 监控单元Service业务层处理
 *
 * @author YINQ
 * @date 2023-08-31
 */
@Service
public class HwMonitorUnitServiceImpl implements IHwMonitorUnitService {
    @Autowired
    private HwMonitorUnitMapper hwMonitorUnitMapper;
    @Autowired
    private HwElectronicFenceMapper hwElectronicFenceMapper;
    @Autowired
    private RemoteTdEngineService remoteTdEgineService;
    @Autowired
    private HwDeviceMapper hwDeviceMapper;
    @Autowired
    private HwAlarmInfoMapper hwAlarmInfoMapper;

    /**
     * 查询监控单元
     *
     * @param monitorUnitId 监控单元主键
     * @return 监控单元
     */
    @Override
    public HwMonitorUnit selectHwMonitorUnitByMonitorUnitId(Long monitorUnitId) {
        return hwMonitorUnitMapper.selectHwMonitorUnitByMonitorUnitId(monitorUnitId);
    }

    /**
     * 查询区域数量站场景区总数百分比
     */
    @Override
    public List<HwMonitorUnitVo> selectMonitorPercentage() {
//        HwMonitorUnit queryMonitorUnit = new HwMonitorUnit();
//        List<HwMonitorUnit> list = hwMonitorUnitMapper.selectHwMonitorUnitListJoinScene(queryMonitorUnit);
//        Map<Long, List<HwMonitorUnit>> monitorUnitMap = list.stream()
//                .collect(Collectors.groupingBy(HwMonitorUnit::getSceneId));
//        List<HwMonitorUnitVo> monitorUnitVoList = new ArrayList<>();
//
//
//        Set<Long> keys = monitorUnitMap.keySet();
//        for(Long key:keys){
//            Integer value = monitorUnitMap.get(key);
//            System.out.println(key+"\t"+value);
//        }
        List<HwMonitorUnitVo> list = hwMonitorUnitMapper.selectMonitorPercentage();
        List<HwMonitorUnitVo> hwScenes = hwMonitorUnitMapper.selectSceneNameById();
        list.stream().forEach(l -> {
            for (int i = 0; i < hwScenes.size(); i++) {
                if (l.getSceneId().equals(hwScenes.get(i).getSceneId())) {
                    l.setSceneName(hwScenes.get(i).getSceneName());
                }
            }
        });

        Integer value = 0;
        //
        Integer sums = 0;
//        if (list.size() > 5) {
//            for (int i = 4; i < list.size(); i++) {//这是剩下的总数
//                if (list.get(i).sum == null) {
//                    list.get(i).sum = 0;
//                }
//                value = value + list.get(i).sum;
//            }
//        }
        for (int i = 0; i < list.size(); i++) {
            if (list.get(i).sum == null) {
                list.get(i).sum = 0;
            }
            sums = sums + list.get(i).sum;
        }
        for (int i = 0; i < list.size(); i++) {
            HwMonitorUnitVo hwMonitorUnitVo = list.get(i);
            hwMonitorUnitVo.setPercentage(NumberUtils.getPercentage(list.get(i).getSum(), sums));
            Long sceneId = hwMonitorUnitVo.getSceneId();
            HwAlarmInfo queryAlarmInfo = new HwAlarmInfo();
            queryAlarmInfo.setSceneId(sceneId);
            List<HwAlarmInfo> alarmInfos = hwAlarmInfoMapper.selectHwAlarmInfoList(queryAlarmInfo);
            Integer alarmInfoSize = alarmInfos == null ? 0 : alarmInfos.size();
            hwMonitorUnitVo.setErr(alarmInfoSize);
        }

//        HwMonitorUnitVo hwMonitorUnitVo = new HwMonitorUnitVo();
//        hwMonitorUnitVo.setSceneName("其他");
//        hwMonitorUnitVo.setSum(value);

//        if (list.size() > 5) {
//            list.add(5, hwMonitorUnitVo);
//            return list.subList(0, 5);
//        } else {
//            return list;
//        }
        return list;
    }

    //获取总的设备数量与监控单元数量
    @Override
    public AllNumsVo selectAllNums(Long sceneId) {
        //监控单元
        Integer monitor = hwMonitorUnitMapper.selectSubSetNums(sceneId) == null ? 0
                : hwMonitorUnitMapper.selectSubSetNums(sceneId);
        Integer integer = hwMonitorUnitMapper.selectDeviceNums(sceneId) == null ? 0
                : hwMonitorUnitMapper.selectDeviceNums(sceneId);
        AllNumsVo vo = new AllNumsVo();
        vo.setSubSum(monitor);
        vo.setSum(integer);
        return vo;
    }


//    @Override
//    public List<AllNumsVo> selectSenceAllNums() {
//        List<AllNumsVo> allNumsVos = hwMonitorUnitMapper.selectAllNums();
//        List<AllNumsVo> allNums = hwMonitorUnitMapper.selectsum();
//        for (int i = 0; i < allNums.size(); i++) {
//            for (int j = 0; j < allNums.size(); j++) {
//                if (allNums.get(i).getSceneId().equals(allNumsVos.get(i).getSceneId())) {
//                    allNums.get(i).setSubSum(allNumsVos.get(i).getSubSum());
//                }
//            }
//        }
//        return allNums;
//    }

    @Override
    public List<HwMonitorUnit> selectLimitSubMonitorUnit() {

        List<HwMonitorUnit> hwMonitorUnits = hwMonitorUnitMapper.selectLimitSubMonitorUnit();
        return hwMonitorUnits;
    }

    @Override
    public List<AlarmStatsVo> selectAlarmStats(Long sceneId) {
        return hwMonitorUnitMapper.selectAlarmStats(sceneId);
    }


    /**
     * 查询监控单元列表
     *
     * @param hwMonitorUnit 监控单元
     * @return 监控单元
     */
    @Override
    public List<HwMonitorUnit> selectHwMonitorUnitList(HwMonitorUnit hwMonitorUnit) {
        return hwMonitorUnitMapper.selectHwMonitorUnitList(hwMonitorUnit);
    }

    @Override
    public SubDeviceSumVo selectSubDeviceSum(Long sceneId) {
        AllNumsVo numsVo = selectAllNums(sceneId);
        int onlineDeviceNum = hwDeviceMapper.getOnlineDeviceNum(sceneId);

        SubDeviceSumVo subDeviceSumVo = new SubDeviceSumVo();
        subDeviceSumVo.setSubSum(numsVo.getSubSum());//监控单元数量
        subDeviceSumVo.setDeviceNum(numsVo.getSum());//设备数量
        subDeviceSumVo.setOnlineDeviceNum(onlineDeviceNum);//在线设备数量
        return subDeviceSumVo;

    }


    @Override
    public HwMonitorUnit selectHwmonitorUnitSub(Long monitorUnitId) {
        return hwMonitorUnitMapper.selectHwMonitorUnitByMonitorUnitId(monitorUnitId);
    }

    //todo SysDeptServiceImpl类中的递归方法recursionFn(以实现)
    @Override
    public List<HwMonitorUnit> selectTreeList(List<HwMonitorUnit> hwMonitorUnits) {
        List<HwMonitorUnit> returnList = new ArrayList<>();
        List<Long> tempList = hwMonitorUnits.stream().map(HwMonitorUnit::getMonitorUnitId).collect(Collectors.toList());
        List<HwMonitorUnit> treeList = new ArrayList<>();
        for (HwMonitorUnit hwMonitorUnit : hwMonitorUnits) {
            if (!tempList.contains(hwMonitorUnit.getParentId()))
                recursionFn(hwMonitorUnits, hwMonitorUnit);
            returnList.add(hwMonitorUnit);
        }
        for (int i = 0; i < returnList.size(); i++) {
            if (returnList.get(i).getParentId() == null) {
                treeList.add(returnList.get(i));
            }
        }
        return treeList;
    }

    private void recursionFn(List<HwMonitorUnit> list, HwMonitorUnit t) {
        // 得到子节点列表
        List<HwMonitorUnit> childList = getChildList(list, t);
        t.setChild(childList);
        for (HwMonitorUnit tChild : childList) {
            if (hasChild(list, tChild)) {
                recursionFn(list, tChild);
            }
        }
    }

    private List<HwMonitorUnit> getChildList(List<HwMonitorUnit> list, HwMonitorUnit t) {
        List<HwMonitorUnit> tlist = new ArrayList<HwMonitorUnit>();
        Iterator<HwMonitorUnit> it = list.iterator();
        while (it.hasNext()) {
            HwMonitorUnit n = (HwMonitorUnit) it.next();
            if (StringUtils.isNotNull(n.getParentId()) && n.getParentId().longValue() == t.getMonitorUnitId().longValue()) {
                tlist.add(n);
            }
        }
        return tlist;
    }

    private boolean hasChild(List<HwMonitorUnit> list, HwMonitorUnit t) {
        return getChildList(list, t).size() > 0 ? true : false;
    }

    /**
     * 新增监控单元
     *
     * @param hwMonitorUnit 监控单元
     * @return 结果
     */
    @Override
    public int insertHwMonitorUnit(HwMonitorUnit hwMonitorUnit) {
        hwMonitorUnit.setCreateTime(DateUtils.getNowDate());
        return hwMonitorUnitMapper.insertHwMonitorUnit(hwMonitorUnit);
    }

    /**
     * 修改监控单元
     *
     * @param hwMonitorUnit 监控单元
     * @return 结果
     */
    @Override
    public int updateHwMonitorUnit(HwMonitorUnit hwMonitorUnit) {
        hwMonitorUnit.setUpdateTime(DateUtils.getNowDate());
        return hwMonitorUnitMapper.updateHwMonitorUnit(hwMonitorUnit);
    }

    /**
     * 批量删除监控单元
     *
     * @param monitorUnitIds 需要删除的监控单元主键
     * @return 结果
     */
    @Override
    public int deleteHwMonitorUnitByMonitorUnitIds(Long[] monitorUnitIds) {
        return hwMonitorUnitMapper.deleteHwMonitorUnitByMonitorUnitIds(monitorUnitIds);
    }

    /**
     * 删除监控单元信息
     *
     * @param monitorUnitId 监控单元主键
     * @return 结果
     */
    @Override
    public int deleteHwMonitorUnitByMonitorUnitId(Long monitorUnitId) {
        return hwMonitorUnitMapper.deleteHwMonitorUnitByMonitorUnitId(monitorUnitId);
    }


    /**
     * 查询监控单元树结构信息
     *
     * @param hwMonitorUnit 监控单元信息
     * @return 监控单元树信息集合
     */
    @Override
    @DataScope(tenantAlias = "hmu")
    public List<TreeSelectVo> selectMonitorTreeList(HwMonitorUnit hwMonitorUnit) {
        List<HwMonitorUnit> hwMonitorUnits = this.selectHwMonitorUnitList(hwMonitorUnit);
        return buildMonitorUnitTreeSelect(hwMonitorUnits);
    }

    /**
     * 构建前端所需要下拉树结构
     *
     * @param hwMonitorUnits 监控单元列表
     * @return 下拉树结构列表
     */
    @Override
    public List<TreeSelectVo> buildMonitorUnitTreeSelect(List<HwMonitorUnit> hwMonitorUnits) {
        List<HwMonitorUnit> monitorUnitTrees = buildMonitorUnitTree(hwMonitorUnits);
        return monitorUnitTrees.stream().map(TreeSelectVo::new).collect(Collectors.toList());
    }

    /**
     * 构建前端所需要树结构
     *
     * @param hwMonitorUnits 监控单元列表
     * @return 树结构列表
     */
    @Override
    public List<HwMonitorUnit> buildMonitorUnitTree(List<HwMonitorUnit> hwMonitorUnits) {
        List<HwMonitorUnit> returnList = new ArrayList<HwMonitorUnit>();
        List<Long> tempList = hwMonitorUnits.stream().map(HwMonitorUnit::getMonitorUnitId).collect(Collectors.toList());
        for (HwMonitorUnit monitorUnit : hwMonitorUnits) {
            // 如果是顶级节点, 遍历该父节点的所有子节点
            if (!tempList.contains(monitorUnit.getParentId())) {
                recursionFn1(hwMonitorUnits, monitorUnit);
                returnList.add(monitorUnit);
            }
        }
        if (returnList.isEmpty()) {
            returnList = hwMonitorUnits;
        }
        return returnList;

    }

    /**
     * 递归列表
     */
    private void recursionFn1(List<HwMonitorUnit> list, HwMonitorUnit t) {
        // 得到子节点列表
        List<HwMonitorUnit> childList = getChildList1(list, t);
        t.setChildren(childList);
        for (HwMonitorUnit tChild : childList) {
            if (hasChild1(list, tChild)) {
                recursionFn1(list, tChild);
            }
        }
    }

    /**
     * 得到子节点列表
     */
    private List<HwMonitorUnit> getChildList1(List<HwMonitorUnit> list, HwMonitorUnit t) {
        List<HwMonitorUnit> tlist = new ArrayList<HwMonitorUnit>();
        Iterator<HwMonitorUnit> it = list.iterator();
        while (it.hasNext()) {
            HwMonitorUnit n = (HwMonitorUnit) it.next();
            if (StringUtils.isNotNull(n.getParentId()) && n.getParentId().longValue() == t.getMonitorUnitId().longValue()) {
                tlist.add(n);
            }
        }
        return tlist;
    }

    /**
     * 判断是否有子节点
     */
    private boolean hasChild1(List<HwMonitorUnit> list, HwMonitorUnit t) {
        return getChildList1(list, t).size() > 0 ? true : false;
    }
}
