package com.yuchen.saas.park.service.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.protobuf.ServiceException;
import com.thinkunion.sdk.iot.bean.pojo.ProductInfo;
import com.yuchen.saas.park.api.entity.device.PmgBatSmartEquipment;
import com.yuchen.saas.park.api.entity.park.PmgBatDeviceData;
import com.yuchen.saas.park.api.entity.park.PmgBatDeviceType;
import com.yuchen.saas.park.api.entity.park.PmgBatProduct;
import com.yuchen.saas.park.api.vo.park.*;
import com.yuchen.saas.park.api.vo.park.energy.DeviceStatisticVO;
import com.yuchen.saas.park.api.vo.park.fire.DeviceGeneralVO;
import com.yuchen.saas.park.api.vo.park.security.DeviceListInfoVO;
import com.yuchen.saas.park.api.vo.park.security.DeviceListVO;
import com.yuchen.saas.park.api.vo.park.security.OnlineStatisticVO;
import com.yuchen.saas.park.service.iot.IoTRemoteService;
import com.yuchen.saas.park.service.mapper.PmgBatSmartEquipmentMapper;
import com.yuchen.saas.park.service.service.*;
import com.yuchen.saas.park.service.util.HashMapChainProxy;
import org.nest.springwrap.core.mp.base.BaseServiceImpl;
import org.nest.springwrap.core.mp.support.Condition;
import org.nest.springwrap.core.mp.support.Query;
import org.nest.springwrap.core.tool.utils.Func;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author 刘通
 * @date 2020/12/30 14:37
 */
@Service
public class PmgBatSmartEquipmentServiceImpl
        extends BaseServiceImpl<PmgBatSmartEquipmentMapper, PmgBatSmartEquipment>
        implements PmgBatSmartEquipmentService {

    @Resource(name = "pmgBatPointLocationInfoServiceImpl")
    private PmgBatPointLocationInfoService locationInfoService;

    @Resource
    private PmgBatParkBuildingInfoService pmgBatParkBuildingInfoService;

    @Resource
    private PmgBatParkFloorInfoService pmgBatParkFloorInfoService;

    @Resource
    private PmgBatParkRoomInfoService pmgBatParkRoomInfoService;

    @Resource
    private PmgBatDevicePkNameService pmgBatDevicePkNameService;

    @Resource
    private ParkDeviceDataService deviceData;

    @Resource
    private IoTRemoteService ioTRemoteService;

    @Autowired
    private PmgBatProductService productService;

    /**
     * 注入设备分类操作接口
     */
    @Autowired
    private IDeviceType iDeviceType;

    /**
     * 根据 productKey 和 deviceName 获取抓拍机设备信息+停车场信息+出入口信息+车道信息
     * @param productKey
     * @param deviceName
     * @return
     */
    @Override
    public DeviceAndParkingVo getDeviceAndParking(String productKey, String deviceName) {
        return baseMapper.getDeviceAndParking(productKey, deviceName);
    }

    /**
     * 通过 product key 和 device ame 查询详情
     * @param productKey
     * @param deviceName
     * @return
     */
    @Override
    public PmgBatSmartEquipment getDetails(String productKey, String deviceName) {
        return baseMapper.getDetails(productKey, deviceName);
    }

    @Override
    public PmgBatSmartEquipmentVo getDetailsByPkAndDN(String productKey, String deviceName) {
        return baseMapper.getDetailsByPkAndDN(productKey, deviceName);
    }

    @Override
    public List<PmgBatSmartEquipment> getDevices(String productKey) throws ServiceException {
        // 校验请求参数是否为空
        if (Func.isEmpty(productKey)) {
            throw new ServiceException("请求参数缺失!");
        }
        return baseMapper.getDevices(productKey);
    }

    @Override
    public List<PmgBatSmartEquipmentVo> getDetailAll() {
        return baseMapper.getDetailAll();
    }

    @Override
    public List<PmgBatSmartEquipmentVo> getDetailAll(String parkId) {
        return baseMapper.getDetailAllByParkId(parkId);
    }

    @Override
    public int getAllDevice() {
        List<PmgBatSmartEquipment> pmgBatSmartEquipments = baseMapper
                .selectList(Wrappers.<PmgBatSmartEquipment>query().lambda().eq(PmgBatSmartEquipment::getIsOnline, 1));


        return pmgBatSmartEquipments.size();
    }

    /**
     * 根据 productKey 获取设备列表
     * @param productKey 可以用逗号隔开
     * @return
     */
    @Override
    public List<PmgBatSmartEquipment> getDevicesListByKey(String productKey) {
        // 用逗号分割为list
        List<String> keys = Arrays.asList(productKey.split(","));
        // 封装查询条件
        QueryWrapper<PmgBatSmartEquipment> queryWrapper = new QueryWrapper();
        queryWrapper.in("product_key", keys);
        return baseMapper.selectList(queryWrapper);
    }

    @Override
    public List<PmgBatSmartEquipment> getDevicesListByKey(String parkId, String productKey) {
        // 用逗号分割为list
        List<String> keys = Arrays.asList(productKey.split(","));
        // 封装查询条件
        QueryWrapper<PmgBatSmartEquipment> queryWrapper = new QueryWrapper();
        queryWrapper.in("product_key", keys).eq("park_id", parkId);
        return baseMapper.selectList(queryWrapper);
    }

    /**
     * 获取设备在离线
     * @return
     */
    @Override
    public DeviceOnLineCountVo getOnLineCount() {
        return baseMapper.getOnLineCount();
    }

    @Override
    public DeviceOnLineCountVo getOnLineCount(String parkId) {
        return baseMapper.getOnLineCountNow(parkId);
    }

    /**
     * 通过设备类型获取设备的productKey列表
     */
    @Override
    public List<String> getProductKeyByCategoryCode(String categoryCode, Long parkId, Long buildingId, Long floorId,
                                                    Long roomId) {
        return baseMapper.getProductKeyByCategoryCode(categoryCode, parkId, buildingId, floorId, roomId);
    }


    /***************************** 3d/bi start **********************************/

    @Override
    public Map<String, Object> getEquipmentAll(Long parkId, Long buildingId, Long floorId) {

        HashMapChainProxy<String, Object> all = new HashMapChainProxy<>(10);

        //总设备数、在线设备数
        DeviceOnLineCountVo OnLineCount = this.getByOnLineCount(parkId, buildingId, floorId);

        //设备分类及数量
        List<GetEnvironmentInfo> equipmentGroupNumber = this.getGroupType(parkId, buildingId, floorId);

        //设备故障信息-今日
        EnvironmentVo toDayInfo = this.getToDayInfo(parkId, buildingId, floorId);

        //设备故障信息-本月
        EnvironmentVo toMonthInfo = this.getToMonthInfo(parkId, buildingId, floorId);

        //设备故障趋势-今日
        Map<String, List<GetEnvironmentInfo>> toDayInfoTrend = this.getToDayInfoTrend(parkId, buildingId, floorId);

        //设备故障趋势-本月
        Map<String, List<GetEnvironmentInfo>> toMonthInfoTrend = this.getToMonthInfoTrend(parkId, buildingId, floorId);

        //设备分布
        List<GetEnvironmentInfo> deviceDistribute = this.getDevicePart(parkId, buildingId, floorId);

        all.putObject("OnLineCount", OnLineCount).putObject("equipmentGroupNumber", equipmentGroupNumber)
                .putObject("toDayInfo", toDayInfo).putObject("toMonthInfo", toMonthInfo)
                .putObject("toDayInfoTrend", toDayInfoTrend).putObject("toMonthInfoTrend", toMonthInfoTrend)
                .putObject("deviceDistribute", deviceDistribute);

        return all;
    }

    @Override
    public DeviceOnLineCountVo getByOnLineCount(Long parkId, Long buildingId, Long floorId) {

        DeviceOnLineCountVo deviceOnLineCountVo = new DeviceOnLineCountVo();
        //获取所有关联点位的设备
        List<PmgEquipmentPointVo> pmgEquipmentPointVos =
                locationInfoService.selectByAllEquipmentPoint(parkId, buildingId, floorId, null);
        deviceOnLineCountVo.setDeviceCount(pmgEquipmentPointVos.size());
        deviceOnLineCountVo.setOnlineDevice(
                pmgEquipmentPointVos.stream().filter(er -> er.getIsOnline() == 1).collect(Collectors.toList()).size());
        deviceOnLineCountVo.setWarningDevice(
                pmgEquipmentPointVos.stream().filter(er -> er.getIsOnline() == 0).collect(Collectors.toList()).size());

        return deviceOnLineCountVo;
    }

    @Override
    public List<GetEnvironmentInfo> getGroupType(Long parkId, Long buildingId, Long floorId) {

        List<GetEnvironmentInfo> list = new ArrayList<>();

        //获取所有关联点位的设备
        List<PmgEquipmentPointVo> pmgEquipmentPointList =
                locationInfoService.selectByAllEquipmentPoint(parkId, buildingId, floorId, null);

        Map<String, List<PmgEquipmentPointVo>> EquipmentPointGroupList =
                pmgEquipmentPointList.stream().collect(Collectors.groupingBy(PmgEquipmentPointVo::getCategoryName));

        for (String key : EquipmentPointGroupList.keySet()) {
            GetEnvironmentInfo info = new GetEnvironmentInfo();
            info.setKey(key);
            info.setValue(String.valueOf(EquipmentPointGroupList.get(key).size()));
            list.add(info);
        }


        return list;
    }

    @Override
    public List<GetEnvironmentInfo> getDevicePart(Long parkId, Long buildingId, Long floorId) {

        List<GetEnvironmentInfo> list = new ArrayList<>();

        //获取所有关联点位的设备
        List<PmgEquipmentPointVo> pmgEquipmentPointList =
                locationInfoService.selectByAllEquipmentPoint(parkId, buildingId, floorId, null);

        // 1.楼层场景：显示每一个房间的设备分布
        if (!org.springframework.util.StringUtils.isEmpty(parkId) &&
                !org.springframework.util.StringUtils.isEmpty(buildingId) &&
                !org.springframework.util.StringUtils.isEmpty(floorId)) {

            //得到所有房间的分组
            Map<Long, List<PmgEquipmentPointVo>> roomList =
                    pmgEquipmentPointList.stream().collect(Collectors.groupingBy(PmgEquipmentPointVo::getRoomId));

            for (Long key : roomList.keySet()) {
                GetEnvironmentInfo getEnvironmentInfo = new GetEnvironmentInfo();
                //房间id对应的名称
                getEnvironmentInfo
                        .setKey(pmgBatParkRoomInfoService.getById(key) == null ? "" : pmgBatParkRoomInfoService
                                .getById(key).getRoomName());
                getEnvironmentInfo.setValue(String.valueOf(roomList.get(key).size()));
                list.add(getEnvironmentInfo);
            }

            return list;
        }

        // 2.楼栋场景:显示每一层的设备分布
        if (!org.springframework.util.StringUtils.isEmpty(parkId) && !org.springframework.util.StringUtils
                .isEmpty(buildingId)) {
            //得到所有楼层的分组
            Map<Long, List<PmgEquipmentPointVo>> floorList =
                    pmgEquipmentPointList.stream().collect(Collectors.groupingBy(PmgEquipmentPointVo::getFloorId));

            for (Long key : floorList.keySet()) {
                GetEnvironmentInfo getEnvironmentInfo = new GetEnvironmentInfo();
                //楼层id对应的名称
                getEnvironmentInfo
                        .setKey(pmgBatParkFloorInfoService.getById(key) == null ? "" : pmgBatParkFloorInfoService
                                .getById(key).getFloorName());
                getEnvironmentInfo.setValue(String.valueOf(floorList.get(key).size()));
                list.add(getEnvironmentInfo);
            }

            return list;
        }

        // 3.园区场景:显示每一栋的设备分布
        if (!org.springframework.util.StringUtils.isEmpty(parkId)) {
            //得到所有楼栋的分组
            Map<Long, List<PmgEquipmentPointVo>> buildingList =
                    pmgEquipmentPointList.stream().collect(Collectors.groupingBy(PmgEquipmentPointVo::getBuildingId));

            for (Long key : buildingList.keySet()) {
                GetEnvironmentInfo getEnvironmentInfo = new GetEnvironmentInfo();
                //楼栋id对应的名称
                getEnvironmentInfo
                        .setKey(pmgBatParkBuildingInfoService.getById(key) == null ? "" : pmgBatParkBuildingInfoService
                                .getById(key).getBuildingName());
                getEnvironmentInfo.setValue(String.valueOf(buildingList.get(key).size()));
                list.add(getEnvironmentInfo);
            }
            return list;
        }
        return list;
    }

    @Override
    public EnvironmentVo getToDayInfo(Long parkId, Long buildingId, Long floorId) {

        EnvironmentVo environmentVo = new EnvironmentVo();
        environmentVo.setDayFault("90");
        environmentVo.setDayOffLine("50");
        environmentVo.setLastMonthFault("20");
        environmentVo.setLastMonthOffLine("20");
        return environmentVo;
    }

    @Override
    public EnvironmentVo getToMonthInfo(Long parkId, Long buildingId, Long floorId) {
        EnvironmentVo environmentVo = new EnvironmentVo();
        environmentVo.setDayFault("90");
        environmentVo.setDayOffLine("50");
        environmentVo.setLastMonthFault("20");
        environmentVo.setLastMonthOffLine("20");
        return environmentVo;
    }

    @Override
    public Map<String, List<GetEnvironmentInfo>> getToDayInfoTrend(Long parkId, Long buildingId, Long floorId) {

        Map<String, List<GetEnvironmentInfo>> dayMap = new HashMap<>(2);

        //离线设备次数
        List<GetEnvironmentInfo> offLineList = new ArrayList<>();

        //故障设备次数
        List<GetEnvironmentInfo> faultList = new ArrayList<>();

        Date date = new Date();
        int hours = date.getHours();

        //循环模拟今日已过小时(包括当前小时)的数据
        for (int i = 1; i <= hours; i++) {
            GetEnvironmentInfo info = new GetEnvironmentInfo();
            info.setKey(i + "");
            info.setValue(i + "");
            //离线设备次数和故障设备次数数据一样
            offLineList.add(info);
            faultList.add(info);
        }

        dayMap.put("offLineList", offLineList);
        dayMap.put("faultList", faultList);
        return dayMap;
    }

    @Override
    public Map<String, List<GetEnvironmentInfo>> getToMonthInfoTrend(Long parkId, Long buildingId, Long floorId) {

        Map<String, List<GetEnvironmentInfo>> monthMap = new HashMap<>();

        //离线设备次数
        List<GetEnvironmentInfo> offLineList = new ArrayList<>();

        //故障设备次数
        List<GetEnvironmentInfo> faultList = new ArrayList<>();


        //循环模拟本月已过天数(包括当天)的数据
        for (int i = 1; i <= 30; i++) {
            GetEnvironmentInfo info = new GetEnvironmentInfo();
            info.setKey(i + "");
            info.setValue(i + "");
            //离线设备次数和故障设备次数数据一样
            offLineList.add(info);
            faultList.add(info);
        }

        monthMap.put("offLineList", offLineList);
        monthMap.put("faultList", faultList);
        return monthMap;
    }

    @Override
    public List<GetEquipmentListVO> getEquipInfo(Long parkId, Long buildingId, Long floorId) {

        List<GetEquipmentListVO> getEquipmentListVO = new ArrayList<>();

        //获取所有关联点位的设备
        List<PmgEquipmentPointVo> equipAllInfo =
                locationInfoService.selectByAllEquipmentPoint(parkId, buildingId, floorId, null);


        //停车
        List<PmgBatSmartEquipment> stopCarList =
                equipAllInfo.stream().filter(item -> item.getCategoryCode().equals("1")).collect(Collectors.toList());
        GetEquipmentListVO stopCar = new GetEquipmentListVO();
        stopCar.setKey("1");
        stopCar.setValue("停车");
        stopCar.setList(stopCarList);
        getEquipmentListVO.add(stopCar);

        //消防管廊
        List<PmgBatSmartEquipment> fireList =
                equipAllInfo.stream().filter(item -> item.getCategoryCode().equals("2")).collect(Collectors.toList());
        GetEquipmentListVO fire = new GetEquipmentListVO();
        fire.setKey("2");
        fire.setValue("消防管廊");
        fire.setList(fireList);
        getEquipmentListVO.add(fire);

        //环境
        List<PmgBatSmartEquipment> environmentList =
                equipAllInfo.stream().filter(item -> item.getCategoryCode().equals("3")).collect(Collectors.toList());
        GetEquipmentListVO environment = new GetEquipmentListVO();
        environment.setKey("3");
        environment.setValue("环境");
        environment.setList(environmentList);
        getEquipmentListVO.add(environment);

        //能源
        List<PmgBatSmartEquipment> energyList =
                equipAllInfo.stream().filter(item -> item.getCategoryCode().equals("4")).collect(Collectors.toList());
        GetEquipmentListVO energy = new GetEquipmentListVO();
        energy.setKey("4");
        energy.setValue("能源");
        energy.setList(energyList);
        getEquipmentListVO.add(energy);

        //监控
        List<PmgBatSmartEquipment> monitoringList =
                equipAllInfo.stream().filter(item -> item.getCategoryCode().equals("5")).collect(Collectors.toList());
        GetEquipmentListVO monitoring = new GetEquipmentListVO();
        monitoring.setKey("5");
        monitoring.setValue("监控");
        monitoring.setList(monitoringList);
        getEquipmentListVO.add(monitoring);

        //安防
        List<PmgBatSmartEquipment> securityList =
                equipAllInfo.stream().filter(item -> item.getCategoryCode().equals("6")).collect(Collectors.toList());
        GetEquipmentListVO security = new GetEquipmentListVO();
        security.setKey("6");
        security.setValue("安防");
        security.setList(securityList);
        getEquipmentListVO.add(security);

        //测温面板
        List<PmgBatSmartEquipment> panelList =
                equipAllInfo.stream().filter(item -> item.getCategoryCode().equals("8")).collect(Collectors.toList());
        GetEquipmentListVO panel = new GetEquipmentListVO();
        panel.setKey("7");
        panel.setValue("测温面板");
        panel.setList(panelList);
        getEquipmentListVO.add(panel);

        return getEquipmentListVO;
    }

    @Override
    public DeviceOnLineCount getEnvironmentDeviceCount(Long parkId, Long buildingId, Long floorId) {
        //返回对象
        DeviceOnLineCount deviceOnLineCount = new DeviceOnLineCount();

        //获取所有关联点位的设备
        List<PmgEquipmentPointVo> EnvironmentEqList =
                locationInfoService.selectByAllEquipmentPoint(parkId, buildingId, floorId, null);
        //过滤只查category_code=3的环境设备
        List<PmgEquipmentPointVo> EnvironmentList =
                EnvironmentEqList.stream().filter(er -> er.getCategoryCode().equals("3")).collect(Collectors.toList());
        deviceOnLineCount.setDeviceCount(EnvironmentList.size());
        deviceOnLineCount.setOnlineDevice(
                EnvironmentList.stream().filter(er -> er.getIsOnline() == 1).collect(Collectors.toList()).size());
        deviceOnLineCount.setWarningDevice(
                EnvironmentList.stream().filter(er -> er.getIsOnline() == 0).collect(Collectors.toList()).size());
        //离线 = 故障
        deviceOnLineCount.setFaultDevice(
                EnvironmentList.stream().filter(er -> er.getIsOnline() == 0).collect(Collectors.toList()).size());

        return deviceOnLineCount;
    }

    @Override
    public List<GetEnvironmentInfo> getEnvironmentGroupCount(Long parkId, Long buildingId, Long floorId,
                                                             String categoryCode) {

        List<GetEnvironmentInfo> list = new ArrayList<>();

        //获取所有关联点位的设备
        List<PmgEquipmentPointVo> EnvironmentEqList =
                locationInfoService.selectByAllEquipmentPoint(parkId, buildingId, floorId, null);
        //过滤指定code设备
        List<PmgEquipmentPointVo> pkList =
                EnvironmentEqList.stream().filter(er -> er.getCategoryCode().equals(categoryCode))
                        .collect(Collectors.toList());
        //查询出productKey二级分类
        Map<String, List<PmgEquipmentPointVo>> collect =
                pkList.stream().collect(Collectors.groupingBy(PmgEquipmentPointVo::getProductKey));

        for (String key : collect.keySet()) {
            GetEnvironmentInfo getEnvironmentInfo = new GetEnvironmentInfo();
            //根据productKey查询对应二级分类名称
            getEnvironmentInfo.setKey(pmgBatDevicePkNameService.getByPk(key).getProductKeyTypeName());
            getEnvironmentInfo.setValue(String.valueOf(collect.get(key).size()));
            list.add(getEnvironmentInfo);
        }
        return list;
    }

    @Override
    public List<GetEnvironmentAssistVO> getEquipmentCountInfo(Long parkId, Long buildingId, Long floorId,
                                                              String categoryCode) {

        List<GetEnvironmentAssistVO> list = new ArrayList<>();

        List<GetEnvironmentCountInfoVO> equipmentList =
                baseMapper.getEnvironmentGroupCountInfo(parkId, buildingId, floorId, categoryCode);

        //使用stream分组
        Map<String, List<GetEnvironmentCountInfoVO>> collect =
                equipmentList.stream().collect(Collectors.groupingBy(GetEnvironmentCountInfoVO::getProductKeyName));

        //将Map中的key替换
        for (String key : collect.keySet()) {

            List<GetEnvironmentCountInfoVO> getEnvironmentCountInfoVOS = collect.get(key);
            //创建key
            GetEnvironmentAssistVO asLast = new GetEnvironmentAssistVO();
            asLast.setKey(String.valueOf(new Random().nextInt(90) + 10));
            asLast.setValue(key);
            asLast.setList(getEnvironmentCountInfoVOS);
            list.add(asLast);
        }


        return list;
    }

    @Override
    public List<PmgBatSmartEquipmentPointVo> selectEquipmentPoint(Long parkId) {
        return baseMapper.selectEquipmentPoint(parkId);
    }

    @Override
    public DeviceOnLineCount getDeviceCountByCategoryCode(Long parkId, Long buildingId, Long floorId,
                                                          String categoryCode) {
        //返回对象
        DeviceOnLineCount deviceOnLineCount = new DeviceOnLineCount();

        //获取所有关联点位的设备
        List<PmgEquipmentPointVo> EnvironmentEqList =
                locationInfoService.selectByAllEquipmentPoint(parkId, buildingId, floorId, null);
        //过滤只查category_code的设备
        List<PmgEquipmentPointVo> EnvironmentList =
                EnvironmentEqList.stream().filter(er -> er.getCategoryCode().equals(categoryCode))
                        .collect(Collectors.toList());
        deviceOnLineCount.setDeviceCount(EnvironmentList.size());
        deviceOnLineCount.setOnlineDevice(
                EnvironmentList.stream().filter(er -> er.getIsOnline() == 1).collect(Collectors.toList()).size());
        deviceOnLineCount.setWarningDevice(
                EnvironmentList.stream().filter(er -> er.getIsOnline() == 0).collect(Collectors.toList()).size());
        //离线 = 故障
        deviceOnLineCount.setFaultDevice(
                EnvironmentList.stream().filter(er -> er.getIsOnline() == 0).collect(Collectors.toList()).size());

        return deviceOnLineCount;
    }

    @Override
    public List<GetEnvironmentInfo> getDeviceDistributionByCategoryCode(Long parkId, Long buildingId, Long floorId,
                                                                        String categoryCode) {
        //获取相应场景所有关联点位的设备
        List<PmgEquipmentPointVo> deviceList =
                locationInfoService.selectByAllEquipmentPoint(parkId, buildingId, floorId, null);
        //根据categoryCode过滤
        List<PmgEquipmentPointVo> newList =
                deviceList.stream().filter(p -> categoryCode.equals(p.getCategoryCode())).collect(Collectors.toList());

        List<GetEnvironmentInfo> rspList = new ArrayList<>();
        // 1.楼层场景：显示每一个房间的设备分布
        if (!org.springframework.util.StringUtils.isEmpty(parkId) &&
                !org.springframework.util.StringUtils.isEmpty(buildingId) &&
                !org.springframework.util.StringUtils.isEmpty(floorId)) {

            //得到所有房间的分组
            Map<Long, List<PmgEquipmentPointVo>> roomList =
                    newList.stream().collect(Collectors.groupingBy(PmgEquipmentPointVo::getRoomId));

            for (Long key : roomList.keySet()) {
                GetEnvironmentInfo getEnvironmentInfo = new GetEnvironmentInfo();
                //房间id对应的名称
                getEnvironmentInfo
                        .setKey(pmgBatParkRoomInfoService.getById(key) == null ? "" : pmgBatParkRoomInfoService
                                .getById(key).getRoomName());
                getEnvironmentInfo.setValue(String.valueOf(roomList.get(key).size()));
                rspList.add(getEnvironmentInfo);
            }
            //降序排序
            rspList.sort((a, b) -> Integer.parseInt(b.getValue()) - Integer.parseInt(a.getValue()));
            return rspList;
        }

        // 2.楼栋场景:显示每一层的设备分布
        if (!org.springframework.util.StringUtils.isEmpty(parkId) && !org.springframework.util.StringUtils
                .isEmpty(buildingId)) {
            //得到所有楼层的分组
            Map<Long, List<PmgEquipmentPointVo>> floorList =
                    newList.stream().collect(Collectors.groupingBy(PmgEquipmentPointVo::getFloorId));

            for (Long key : floorList.keySet()) {
                GetEnvironmentInfo getEnvironmentInfo = new GetEnvironmentInfo();
                //楼层id对应的名称
                getEnvironmentInfo
                        .setKey(pmgBatParkFloorInfoService.getById(key) == null ? "" : pmgBatParkFloorInfoService
                                .getById(key).getFloorName());
                getEnvironmentInfo.setValue(String.valueOf(floorList.get(key).size()));
                rspList.add(getEnvironmentInfo);
            }
            //降序排序
            rspList.sort((a, b) -> Integer.parseInt(b.getValue()) - Integer.parseInt(a.getValue()));
            return rspList;
        }

        // 3.园区场景:显示每一栋的设备分布
        if (!org.springframework.util.StringUtils.isEmpty(parkId)) {
            //得到所有楼栋的分组
            Map<Long, List<PmgEquipmentPointVo>> buildingList =
                    newList.stream().collect(Collectors.groupingBy(PmgEquipmentPointVo::getBuildingId));

            for (Long key : buildingList.keySet()) {
                GetEnvironmentInfo getEnvironmentInfo = new GetEnvironmentInfo();
                //楼栋id对应的名称
                getEnvironmentInfo
                        .setKey(pmgBatParkBuildingInfoService.getById(key) == null ? "" : pmgBatParkBuildingInfoService
                                .getById(key).getBuildingName());
                getEnvironmentInfo.setValue(String.valueOf(buildingList.get(key).size()));
                rspList.add(getEnvironmentInfo);
            }
            //降序排序
            rspList.sort((a, b) -> Integer.parseInt(b.getValue()) - Integer.parseInt(a.getValue()));
            return rspList;
        }
        return rspList;
    }

    @Override
    public IPage<PmgEquipmentPropertyVO> searchDevice(PmgBatSmartEquipment pmgBatSmartEquipment, Query query) {

        //根据名称、categoryCode查询所有设备
        Page<PmgEquipmentPropertyVO> page = new Page<>(query.getCurrent(), query.getSize());
        IPage<PmgEquipmentPropertyVO> iPageVO = baseMapper.searchDevice(page, pmgBatSmartEquipment);
        //更具pk查询出设备型号,设备分类就是categoryName(查询出iot所有设备型号再筛选)
        List<ProductInfo> productInfos = ioTRemoteService.findAllProduct();
        iPageVO.getRecords().forEach(e -> {
            e.setModel(productInfos.stream().filter(f -> f.getProductKey().equals(e.getProductKey())).findFirst().get()
                    .getName());
            List<GetEnvironmentInfo> list = new LinkedList<>();
            //查询这个设备上过数据的全部identity
            List<PmgBatDeviceData> identityList = deviceData.list(new LambdaQueryWrapper<PmgBatDeviceData>()
//                    .select(PmgBatDeviceData::getIdentity, PmgBatDeviceData::getTimeStamp, PmgBatDeviceData::getValue)
                    .eq(PmgBatDeviceData::getProductKey, e.getProductKey())
                    .and(wrapper -> wrapper.eq(PmgBatDeviceData::getDeviceName, e.getDeviceName())));
            //根据identity分组筛选出list
            Map<String, List<PmgBatDeviceData>> map =
                    identityList.stream().collect(Collectors.groupingBy(PmgBatDeviceData::getIdentify));
            //获取设备identity的最新上报数据
//            map.forEach((k, v) -> {
//                Optional<PmgBatDeviceData> deviceDataOptional =
//                        v.stream().filter(o -> Func.isNotEmpty(o.getTimeStamp()))
//                                .max(Comparator.comparingLong(PmgBatDeviceData::getTimeStamp));
//                if (deviceDataOptional.isPresent()) {
//                    PmgBatDeviceData p = deviceDataOptional.get();
//                    GetEnvironmentInfo info = new GetEnvironmentInfo();
//                    info.setKey(p.getIdentity());
//                    info.setValue(p.getValue());
//                    list.add(info);
//                }
//            });
            e.setPropertyList(list);
        });
        return iPageVO;
    }

    /*********************************火炬广场 Start*************************************/
    @Override
    public OnlineStatisticVO onlineStatistic(Long parkId, Integer categoryCode) {
        OnlineStatisticVO onlineStatisticVO = new OnlineStatisticVO();
        // 查询设备
        List<PmgBatSmartEquipment> equipmentList =
                this.list(Wrappers.<PmgBatSmartEquipment>lambdaQuery()
                        .select(PmgBatSmartEquipment::getIsOnline)
                        .eq(PmgBatSmartEquipment::getParkId, parkId)
                        .eq(categoryCode != null, PmgBatSmartEquipment::getCategoryCode, categoryCode));
        onlineStatisticVO.setOnline(equipmentList.stream().filter(er -> er.getIsOnline() == 1)
                .collect(Collectors.toList()).size());
        onlineStatisticVO.setOffline(equipmentList.stream().filter(er -> er.getIsOnline() == 0)
                .collect(Collectors.toList()).size());
        return onlineStatisticVO;
    }

    @Override
    public List<DeviceListVO> deviceList(Long parkId, Integer categoryCode, String name) {
        // 查询设备
        List<PmgBatSmartEquipment> equipmentList =
                this.list(Wrappers.<PmgBatSmartEquipment>lambdaQuery()
                        .eq(PmgBatSmartEquipment::getParkId, parkId)
                        .eq(categoryCode != null, PmgBatSmartEquipment::getCategoryCode, categoryCode)
                        .like(name != null, PmgBatSmartEquipment::getName, name));
        Map<String, List<PmgBatSmartEquipment>> groupMap =
                equipmentList.stream().collect(Collectors.groupingBy(PmgBatSmartEquipment::getProductKey));
        List<DeviceListVO> rspList = new LinkedList<>();
        for (Map.Entry entry : groupMap.entrySet()) {
            String productKey = String.valueOf(entry.getKey());
            List<PmgBatSmartEquipment> list = (List<PmgBatSmartEquipment>) entry.getValue();
            DeviceListVO deviceListVO = new DeviceListVO();
            deviceListVO.setProductKey(productKey);
            // 获取产品名称
            PmgBatProduct product = productService.getOne(Wrappers.<PmgBatProduct>lambdaQuery()
                    .eq(PmgBatProduct::getParkId, parkId)
                    .eq(PmgBatProduct::getProductKey, productKey));
            if (product != null) {
                deviceListVO.setProductName(product.getProductKeyTypeName());
            }
            List<DeviceListInfoVO> infoList = new LinkedList<>();
            for (PmgBatSmartEquipment e : list) {
                DeviceListInfoVO deviceListInfoVO = new DeviceListInfoVO();
                deviceListInfoVO.setDeviceName(e.getDeviceName());
                deviceListInfoVO.setAliasName(e.getName());
                deviceListInfoVO.setSetPosition(e.getSetPosition());
                deviceListInfoVO.setIsOnline(e.getIsOnline());
                deviceListInfoVO.setPicUrl(e.getImgSrc());
                infoList.add(deviceListInfoVO);
            }
            deviceListVO.setDeviceInfoList(infoList);
            rspList.add(deviceListVO);
        }
        return rspList;
    }

    @Override
    public List<DeviceGeneralVO> deviceGeneral(Long parkId, Integer categoryCode) {
        List<DeviceGeneralVO> rspList = new LinkedList<>();
        List<DeviceListVO> deviceListVOList = deviceList(parkId, categoryCode, null);
        for (DeviceListVO deviceListVO : deviceListVOList) {
            DeviceGeneralVO deviceGeneralVO = new DeviceGeneralVO();
            deviceGeneralVO.setProductName(deviceListVO.getProductName());
            OnlineStatisticVO onlineStatisticVO = new OnlineStatisticVO();
            onlineStatisticVO.setOnline(deviceListVO.getDeviceInfoList().stream().filter(er -> er.getIsOnline() == 1)
                    .collect(Collectors.toList()).size());
            onlineStatisticVO.setOffline(deviceListVO.getDeviceInfoList().stream().filter(er -> er.getIsOnline() == 0)
                    .collect(Collectors.toList()).size());
            deviceGeneralVO.setOnlineStatistic(onlineStatisticVO);
            rspList.add(deviceGeneralVO);
        }
        return rspList;
    }

    @Override
    public DeviceStatisticVO energyDeviceStatisticVO(Long parkId) {
        DeviceStatisticVO deviceStatisticVO = new DeviceStatisticVO();
        OnlineStatisticVO onlineStatisticVO = onlineStatistic(parkId, 4);
        deviceStatisticVO.setOnline(onlineStatisticVO.getOnline());
        deviceStatisticVO.setOffline(onlineStatisticVO.getOffline());
        deviceStatisticVO.setTotal(deviceStatisticVO.getOnline() + deviceStatisticVO.getOffline());
        deviceStatisticVO.setWaterTotal(2);
        deviceStatisticVO.setPowerTotal(deviceStatisticVO.getTotal() - deviceStatisticVO.getWaterTotal());
        return deviceStatisticVO;
    }

    @Override
    public IPage<PmgBatSmartEquipment> getDeviceByCode(Long parkId, String name, String categoryName, Integer isOnline,
                                                       Integer current, Integer size) {
        // 分页数据
        Query query = new Query();
        query.setCurrent(current);
        query.setSize(size);
        // 开始查询分页数据
        LambdaQueryWrapper<PmgBatSmartEquipment> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(PmgBatSmartEquipment::getParkId,parkId);
        queryWrapper.eq(Func.isNotEmpty(isOnline),PmgBatSmartEquipment::getIsOnline,isOnline);
        queryWrapper.like(Func.isNotEmpty(name),PmgBatSmartEquipment::getName,name);
        queryWrapper.like(Func.isNotEmpty(categoryName),PmgBatSmartEquipment::getCategoryName,categoryName);
        return page(Condition.getPage(query),queryWrapper);
    }

    @Override
    public Map<String, Integer> getDeviceCountByCode(Long parkId) {
        // 获取所有分类
        List<PmgBatDeviceType> deviceTypeList = iDeviceType.list();
        // 声明要返回的Map
        Map<String, Integer> resultMap = new HashMap<>(deviceTypeList.size());
        for (PmgBatDeviceType deviceType : deviceTypeList) {
            // 根据分类查询所有设备数量
            LambdaQueryWrapper<PmgBatSmartEquipment> queryWrapper = Wrappers.lambdaQuery();
            queryWrapper.eq(PmgBatSmartEquipment::getParkId,parkId);
            queryWrapper.eq(PmgBatSmartEquipment::getCategoryCode,deviceType.getCode());
            Integer count = count(queryWrapper);
            if (count > 0){
                resultMap.put(deviceType.getCode(),count);
            }
        }
        return resultMap;
    }

    @Override
    public IPage<PmgBatSmartEquipment> getDeviceByProductKey(Long parkId, String name, String categoryName,
                                                             String productKeys,Integer isOnline, Integer current, Integer size) {
        // 分页数据
        Query query = new Query();
        query.setCurrent(current);
        query.setSize(size);
        // 开始查询分页数据
        LambdaQueryWrapper<PmgBatSmartEquipment> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(PmgBatSmartEquipment::getParkId,parkId);
        queryWrapper.in(PmgBatSmartEquipment::getProductKey,Func.toStrList(productKeys));
        queryWrapper.eq(Func.isNotEmpty(isOnline),PmgBatSmartEquipment::getIsOnline,isOnline);
        queryWrapper.like(Func.isNotEmpty(name),PmgBatSmartEquipment::getName,name);
        queryWrapper.like(Func.isNotEmpty(categoryName),PmgBatSmartEquipment::getCategoryName,categoryName);
        return page(Condition.getPage(query),queryWrapper);
    }

    @Override
    public DeviceOnLineCountVo getOnLineCountByParkIdAndProductKey(Long parkId, String productKey) {
        return baseMapper.getOnLineCountByParkIdAndProductKey(parkId,productKey);
    }

    /*********************************火炬广场 End*************************************/

    @Override
    public List getDeviceTreeByCategoryId(Long categoryId) {
        return baseMapper.getDeviceTreeByCategoryId(categoryId);
    }

    @Override
    public List<PmgBatSmartEquipment> getListNotBindByIds(List<Long> idList, String productKey, String parkId) {
        return list(new LambdaQueryWrapper<PmgBatSmartEquipment>().eq(PmgBatSmartEquipment::getParkId,parkId).eq(PmgBatSmartEquipment::getProductKey,productKey).notIn(PmgBatSmartEquipment::getId, idList));
    }
}
