package com.yeejoin.equipmanage.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
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.extension.service.impl.ServiceImpl;
import com.google.common.base.Joiner;
import com.google.common.collect.Lists;
import com.yeejoin.amos.boot.biz.common.utils.RedisUtils;
import com.yeejoin.amos.component.feign.model.FeignClientResult;
import com.yeejoin.amos.component.feign.utils.FeignUtil;
import com.yeejoin.amos.feign.morphic.Morphic;
import com.yeejoin.amos.feign.morphic.model.ResourceDTO;
import com.yeejoin.amos.feign.privilege.Privilege;
import com.yeejoin.amos.feign.privilege.model.AgencyUserModel;
import com.yeejoin.amos.feign.systemctl.Systemctl;
import com.yeejoin.amos.feign.systemctl.model.DictionarieValueModel;
import com.yeejoin.equipmanage.common.datasync.entity.FireFightingSystem;
import com.yeejoin.equipmanage.common.entity.*;
import com.yeejoin.equipmanage.common.entity.dto.DetailssDTO;
import com.yeejoin.equipmanage.common.entity.dto.EquipTypeAmountPageDTO;
import com.yeejoin.equipmanage.common.entity.vo.*;
import com.yeejoin.equipmanage.common.enums.AlarmStatusEnum;
import com.yeejoin.equipmanage.common.enums.EquipmentSpeIndexEnum;
import com.yeejoin.equipmanage.common.enums.SystemTypeEnum;
import com.yeejoin.equipmanage.common.enums.TrueOrFalseEnum;
import com.yeejoin.equipmanage.common.utils.StringUtil;
import com.yeejoin.equipmanage.common.vo.*;
import com.yeejoin.equipmanage.mapper.*;
import com.yeejoin.equipmanage.remote.RemoteSecurityService;
import com.yeejoin.equipmanage.service.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.typroject.tyboot.core.restful.exception.instance.BadRequest;

import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
public class FireFightingSystemServiceImpl extends ServiceImpl<FireFightingSystemMapper, FireFightingSystemEntity> implements IFireFightingSystemService {

    @Autowired
    FireFightingSystemMapper fireFightingSystemMapper;

    @Autowired
    EquipmentParamsMapper equipmentParamsMapper;

    @Autowired
    IEquipmentSpecificSerivce equipmentSpecificService;
    @Autowired
    IRiskSourceSceneService iRiskSourceSceneService;
    @Autowired
    private RemoteSecurityService remoteSecurityService;

    @Autowired
    private EquipmentManageMapper equipmentManageMapper;
    @Autowired
    private EquipmentManageService equipmentManageService;
    @Autowired
    private BuildingMapper buildingMapper;
    @Autowired
    private FormInstanceMapper formInstanceMapper;
    @Autowired
    private SourceSceneMapper sourceSceneMapper;
    @Value("${equipment.fire.systemid}")
    private String fireSystemId;
    @Value("${morphic.projectSeq}")
    private Long projectSeq;
    @Value("${mqtt.scene.host}")
    private String sceneUrl;
    @Value("${equip.point.equipmentdata.topic}")
    private String wsTopic;

    @Value("${equip.point.speindex.url}")
    private String speindexUrl;
    @Value("${equip.point.equipmentDetail.url}")
    private String equipmentDetailUrl;

    @Value("${systemctl.dict.iot-core-param}")
    private String iotCoreParam;

    @Autowired
    private IDynamicFormGroupService iDynamicFormGroupService;

    @Autowired
    private IDynamicFormInstanceService instanceService;

    @Autowired
    @Lazy
    private IEquipmentSpecificSerivce equipmentSpecificSerivce;

    @Autowired
    private ISourceSceneService iSourceSceneService;

    @Autowired
    private ISyncDataService syncDataService;

    @Autowired
    private RedisUtils redisUtils;

    @Autowired
    MqttSendGateway mqttSendGateway;

    @Value("${systemctl.sync.switch}")
    private Boolean syncSwitch;

    @Override
    public List<EquipCountBySystemVO> getEquipCountBySystemId(Long systemId) {
        return this.baseMapper.getEquipCountBySystemId(systemId);
    }


    @Override
    public List<EquiplistSpecificBySystemVO> getEquiplistBySystemId(Long systemId) {
        return this.baseMapper.getEquiplistBySystemId(systemId);
    }

    @Override
    public Map<String, Object> queryEquipmenInfoAndCount(String equimentName, String equimentCode, String construction, String maintenance, int current, int pageSize) {
        Map<String, Object> map = equipmentManageService.queryEquipmenInfoAndCount(equimentName, equimentCode, construction, maintenance, current, pageSize);
        List<EquipmentManageVo> dataList = (List<EquipmentManageVo>) map.get("dataList");
        StringBuilder stb = new StringBuilder();
        dataList.forEach(y -> {
            if (StringUtil.isNotEmpty(String.valueOf(stb))) {
                stb.append("," + y.getChargePerson());
            } else {
                stb.append(y.getChargePerson());
            }
        });
        Map<String, String> userMap = new HashMap<>();
        if (StringUtil.isNotEmpty(stb)) {
            List<AgencyUserModel> agencyUserModels = remoteSecurityService.listUserByUserIds(stb.toString());
            agencyUserModels.forEach(z -> {
                userMap.put(z.getUserId(), z.getRealName());
            });
        }

        dataList.forEach(x -> {
            x.setChargePerson(userMap.get(x.getChargePerson()));
            x.setSystemimg(equipmentManageMapper.getFiles(String.valueOf(x.getId()), "face"));
        });
        map.put("dataList", dataList);
        return map;
    }

    @Override
    public FireFightingSystemEntity getOneById(Long id) {
        FireFightingSystemEntity fireFightingSystemEntity = this.baseMapper.selectById(id);
        return fireFightingSystemEntity;
    }

    @Override
    public String save(FireFightingSystemVo vo) {
        if (!systemCodeCheck(vo)) {
            throw new BadRequest("系统编号已存在，请重新输入");
        }
        List<DynamicFormInstance> formInstance = vo.getFormInstances();
        // 验证必填项 BUG 2725 by kongfm 2021-09-09
        formInstance.forEach(item -> {
            if (item.getNotNull() && StringUtils.isEmpty(item.getFieldValue())) {
                throw new BadRequest(item.getFieldLabel() + "为必填项，请确认");
            }
        });
        String userId = remoteSecurityService.getAgencyUser().getUserId();
        //冗余名称，数据同步使用
        this.setChargePersonName(vo);
        String s = String.valueOf(System.currentTimeMillis());
        vo.setId(s);
        vo.setRecUserId(userId);
        vo.setSort(s);
        DynamicFormGroup dynamicFormGroup = iDynamicFormGroupService.getById(vo.getFormGroupId());
        vo.setSystemType(dynamicFormGroup.getRelationId() != null ? dynamicFormGroup.getRelationId().toString() : "");
        // fireSystemId 为字典表火灾系统id 以此确保第一个生成的火灾报警系统排序为1
        if (vo.getSystemType().equals(fireSystemId)) {
            vo.setSort("1");
        }
        if ("".equals(vo.getInstallDate())) {
            vo.setInstallDate(null);
        }
        if ("".equals(vo.getFirstMaintenanceDate())) {
            vo.setFirstMaintenanceDate(null);
        }
        //1.保存动态表单数据
        if (vo.getFormInstances() != null && vo.getFormInstances().size() > 0) {
            Long instanceId = instanceService.saveInstanceBatch(vo.getFormInstances());
            vo.setInstanceId(instanceId);
            s = s + "," + instanceId;
        }
        //2.保存消防系统数据
        int save = fireFightingSystemMapper.save(vo);
        if (save > 0 && syncSwitch) {
            //  AST数据同步
            List<FireFightingSystem> fireFightingSystemDetail = getFireFightingSystemDetail(vo);
            syncDataService.syncCreatedFireFightingSystem(fireFightingSystemDetail);
        } else {
            return s;
        }
        //3.保存图片数据
        this.insertFiles(vo);
        return s;
    }


    @Override
    public String update(FireFightingSystemVo vo) {
        if (!systemCodeCheck(vo)) {
            throw new BadRequest("系统编号已存在，请重新输入");
        }
        // 验证必填项 BUG 2725 by kongfm 2021-09-09
        List<DynamicFormInstance> formInstance = vo.getFormInstances();
        formInstance.stream().forEach(item -> {
            if (item.getNotNull() == true && StringUtils.isEmpty(item.getFieldValue())) {
                throw new BadRequest(item.getFieldLabel() + "为必填项，请确认");
            }
        });
        String userId = remoteSecurityService.getAgencyUser().getUserId();
        vo.setRecUserId(userId);
        //冗余名称，数据同步使用
        this.setChargePersonName(vo);
        if ("".equals(vo.getInstallDate())) {
            vo.setInstallDate(null);
        }
        if ("".equals(vo.getFirstMaintenanceDate())) {
            vo.setFirstMaintenanceDate(null);
        }

        int update = fireFightingSystemMapper.update(vo);
        if (update > 0 && syncSwitch) {
            //  AST数据同步
            List<FireFightingSystem> fireFightingSystemDetail = getFireFightingSystemDetail(vo);
            syncDataService.syncCreatedFireFightingSystem(fireFightingSystemDetail);
        } else {
            return null;
        }
        //1.更新消防系统数据
        String sequenceNbr = vo.getId();
        fireFightingSystemMapper.deleteFilre(sequenceNbr);
        //2.更新动态表单数据
        if (vo.getInstanceId() != null && vo.getFormInstances().size() > 0) {
            instanceService.updateInstanceBatch(vo.getInstanceId(), vo.getFormInstances());
        }
        //3.更新图片数据
        this.insertFiles(vo);
        return vo.getId();
    }

    private void setChargePersonName(FireFightingSystemVo vo) {
        if (StringUtil.isNotEmpty(vo.getChargePerson())) {
            FeignClientResult<AgencyUserModel> result = Privilege.agencyUserClient.queryByUserId(vo.getChargePerson());
            AgencyUserModel userModel = result == null ? new AgencyUserModel() : result.getResult();
            vo.setChargePersonName(userModel.getRealName());
        }
    }

    private boolean systemCodeCheck(FireFightingSystemVo systemVo) {
        if (StringUtils.isEmpty(systemVo.getId())) {
            // 新建系统时
            int count = this.baseMapper.selectCount(new LambdaQueryWrapper<FireFightingSystemEntity>().eq(FireFightingSystemEntity::getCode, systemVo.getCode()));
            return count < 1;
        } else {
            int count =
                    this.baseMapper.selectCount(new LambdaQueryWrapper<FireFightingSystemEntity>().eq(FireFightingSystemEntity::getCode, systemVo.getCode()).ne(FireFightingSystemEntity::getId, systemVo.getId()));
            return count < 1;
        }
    }

    @Override
    public FireFightingSystemVo createMorphic(FireFightingSystemVo model) {
        ResourceDTO resourceDTO = new ResourceDTO();
        resourceDTO.setSubjectId(projectSeq);
        resourceDTO.setSubjectid(projectSeq);
        resourceDTO.setName(model.getName());
        // 为首次 添加的画布添加mqtt 相关数据
        String content = "{\"layout\":\"\",\"boardConfig\":{\"modeType\":\"custom\",\"orientation\":\"lengthways\",\"autoRefresh\":true,\"name\":\"1\",\"showMode\":\"actual\",\"paperSize\":\"1280X900\"},\"boardStyle\":{\"backgroundImage\":\"\"},\"dataConfig\":{}}";
        Map parse = (Map) JSON.parse(content);
        Map<String, Object> dataConfig = new HashMap<>();
        dataConfig.put("msgType", "mqtt");
        dataConfig.put("wsUrl", sceneUrl);
        parse.put("dataConfig", dataConfig);
        content = JSONObject.toJSONString(parse);
        dataConfig.put("wsTopic", wsTopic);
        resourceDTO.setContent(content);
        ResourceDTO morphic = Morphic.morphicSubjectClient.create(resourceDTO).getResult();
        model.setSceneId(morphic.getId());
//        fireFightingSystemMapper.setSceneId(model);
        return model;
    }

    @Override
    @Transactional
    public ResourceDTO updateMorphic(ResourceDTO resourceDTO) {
        try {
            //1.更新画布信息
            resourceDTO.setSubjectId(projectSeq);
            resourceDTO.setSubjectid(projectSeq);
            String content = resourceDTO.getContent();
            Map parse = (Map) JSON.parse(content);
            Map<String, Object> dataConfig = new HashMap<>();
            dataConfig.put("msgType", "mqtt");
            dataConfig.put("wsUrl", sceneUrl);
            dataConfig.put("wsTopic", wsTopic);
            parse.put("dataConfig", dataConfig);
            content = JSONObject.toJSONString(parse);
            resourceDTO.setContent(content);
            FeignUtil.remoteCall(() -> Morphic.morphicSubjectClient.update(resourceDTO));
            //2.更新业务关联的画布id
            Long systemId = Long.valueOf(resourceDTO.getCode());
            FireFightingSystemVo systemVo = new FireFightingSystemVo();
            systemVo.setId(String.valueOf(systemId));
            systemVo.setSceneId(resourceDTO.getId());
            fireFightingSystemMapper.setSceneId(systemVo);
            //3.保存场景关联信息表
            SourceScene sourceScene = sourceSceneMapper.selectOne(new LambdaQueryWrapper<SourceScene>().eq(SourceScene::getSceneId, resourceDTO.getId()));
            if (sourceScene == null) {
                sourceScene = new SourceScene();
                sourceScene.setProjectId(String.valueOf(projectSeq));
                sourceScene.setSourceId(systemId);
                sourceScene.setSourceName(resourceDTO.getName());
                sourceScene.setSceneId(resourceDTO.getId());
                sourceScene.setSourceType("system");
            }
            //TODO 获取画布下 绑定的装备点、摄像头，目前消防系统只能绑定装备，不能绑定摄像头（树未返回摄像头）
            List<Map> children = (List<Map>) parse.get("children");
            String pointInScene = "";
            String videoInScene = "";
            if (!CollectionUtils.isEmpty(children)) {
                for (Map<String, String> map : children) {
                    String key = map.get("key");
                    if (!"".equals(key) && "equipment".equals(key)) {
                        pointInScene = "".equals(pointInScene) ? map.get("sequenceNbr") : pointInScene + "," + map.get("sequenceNbr");
                    }
                    if (!"".equals(key) && "video".equals(key)) {
                        videoInScene = "".equals(videoInScene) ? map.get("sequenceNbr") : videoInScene + "," + map.get("sequenceNbr");
                    }
                }
            }
            sourceScene.setPointInScene(pointInScene);
            sourceScene.setVideoInScene(videoInScene);
            iSourceSceneService.saveOrUpdate(sourceScene);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new BadRequest("保存画布失败");
        }
        return resourceDTO;
    }

    @Override
    public List<PointTreeVo> getPointTree(String id, String orgCode) {
//        CommonResponse se = riskModelFeign.getRiskSourceList(orgCode);
//        List<Map<String, Object>> list = (List<Map<String, Object>>) se.getDataList();
//        List<PointTreeVo> responses = new ArrayList<>();
//        list.forEach(m -> {
//            RiskSourceTreeResponse r = new RiskSourceTreeResponse();
//            PointTreeVo p = new PointTreeVo();
//            mapToBean(m, r);
//            p.setDisplayName(r.getName());
//            p.setParentId(r.getParentId());
//            p.setSequenceNbr(r.getId());
//            p.setIsRegion(r.getIsRegion());
//            responses.add(p);
//        });
//        List<PointTreeVo> regionList = responses.stream().filter(r -> "TRUE".equals(r.getIsRegion())).collect(Collectors.toList());
        List<PointTreeVo> buildList = buildingMapper.getBuildList();
        return transferListToPointTree(buildList, id);
    }

    @Override
    public List<SpeIndexVo> getSpeIndex(Long id) {
        return makeStatus(fireFightingSystemMapper.getSpeIndex(id));
    }

    private void insertFiles(FireFightingSystemVo vo) {
        List<FileUploadVo> video = vo.getVideo();
        if (video.size() > 0) {
            for (FileUploadVo f : video) {
                f.setId(String.valueOf(System.currentTimeMillis()));
                f.setUserId(vo.getRecUserId());
                f.setFileType("video");
                f.setObjectId(vo.getId());
                fireFightingSystemMapper.insertFile(f);
            }
        }
        List<FileUploadVo> faceimg = vo.getFaceimg();
        if (faceimg.size() > 0) {
            for (FileUploadVo f : faceimg) {
                f.setId(String.valueOf(System.currentTimeMillis()));
                f.setUserId(vo.getRecUserId());
                f.setFileType("face");
                f.setObjectId(vo.getId());
                fireFightingSystemMapper.insertFile(f);
            }
        }
        List<FileUploadVo> instruction = vo.getInstruction();
        if (instruction.size() > 0) {
            for (FileUploadVo f : instruction) {
                f.setId(String.valueOf(System.currentTimeMillis()));
                f.setUserId(vo.getRecUserId());
                f.setFileType("instruction");
                f.setObjectId(vo.getId());
                fireFightingSystemMapper.insertFile(f);
            }
        }
        List<FileUploadVo> asser = vo.getAsser();
        if (asser.size() > 0) {
            for (FileUploadVo f : asser) {
                f.setId(String.valueOf(System.currentTimeMillis()));
                f.setUserId(vo.getRecUserId());
                f.setFileType("certificate");
                f.setObjectId(vo.getId());
                fireFightingSystemMapper.insertFile(f);
            }
        }

        List<FileUploadVo> spotimg = vo.getSpotimg();
        if (spotimg.size() > 0) {
            for (FileUploadVo f : spotimg) {
                f.setId(String.valueOf(System.currentTimeMillis()));
                f.setUserId(vo.getRecUserId());
                f.setFileType("spotimg");
                f.setObjectId(vo.getId());
                fireFightingSystemMapper.insertFile(f);
            }
        }

        List<FileUploadVo> tdmod = vo.getTdmod();
        if (tdmod.size() > 0) {
            for (FileUploadVo f : tdmod) {
                f.setId(String.valueOf(System.currentTimeMillis()));
                f.setUserId(vo.getRecUserId());
                f.setFileType("tdmod");
                f.setObjectId(vo.getId());
                fireFightingSystemMapper.insertFile(f);
            }
        }
    }

    /**
     * 生成树结构
     *
     * @param allRiskSource
     * @param id
     * @return
     */
    public List<PointTreeVo> transferListToPointTree(List<PointTreeVo> allRiskSource, String id) {
        //TODO id为空，为消防建筑使用；id不为空，为点位图使用
        List<PointTreeVo> pointData = fireFightingSystemMapper.getPointData(id);
        if (!CollectionUtils.isEmpty(pointData)) {
            // 查询所有wl_source_scene，判断是否绑定
            List<SourceScene> sourceSceneList = sourceSceneMapper.selectList(null);
            Map<Long, String> sourceSceneMap = null;
            String equipSpecificIds = null;
            if (!CollectionUtils.isEmpty(sourceSceneList)) {
                sourceSceneMap = sourceSceneList.stream().collect(Collectors.toMap(SourceScene::getSourceId, SourceScene::getPointInScene));
                List<String> equipSpecificIdList = sourceSceneList.stream().map(SourceScene::getPointInScene).collect(Collectors.toList());
                equipSpecificIds = String.join(",", equipSpecificIdList);
            }
            // 优化不查指标
            for (PointTreeVo p : pointData) {
                 Long buildOrSysId = p.getParentId();
                Long equipSpecificId = p.getSequenceNbr();
                Map map = new HashMap(7);
                map.put("imgPath", p.getImgPath());
                map.put("equipCode", p.getEquipCode());
                map.put("equipSyetemId", p.getEquipSyetemId());
                map.put("equipTypeId", p.getEquipId());
                map.put("speindexApi", speindexUrl + equipSpecificId);
                map.put("detailInfoApi", equipmentDetailUrl + p.getSequenceNbr());
                map.put("detailApi", equipmentDetailUrl + p.getSequenceNbr());
                p.setDataConfig(map);
                if (StringUtils.isEmpty(id)) {
                    //  建筑
                    if (equipSpecificIds.contains(String.valueOf(equipSpecificId))) {
                        p.setBinding(true);
                    } else {
                        p.setBinding(false);
                    }
                } else {
                    if (sourceSceneMap != null) {
                        String pointInScene = sourceSceneMap.get(buildOrSysId);
                        if (!StringUtils.isEmpty(pointInScene)) {
                            //  系统
                            if (pointInScene.contains(String.valueOf(equipSpecificId))) {
                                p.setBinding(true);
                            } else {
                                p.setBinding(false);
                            }
                        }
                    }
                }
            }
            allRiskSource.addAll(pointData);
            // 树组装优化
            Map<Long, PointTreeVo> map = new HashMap<>(allRiskSource.size());
            allRiskSource.forEach(e -> map.put(e.getSequenceNbr(), e));
            Set<? extends Map.Entry<Long, ? extends PointTreeVo>> entries = map.entrySet();
            List<PointTreeVo> treeList = new ArrayList<>();
            entries.forEach(entry -> {
                PointTreeVo value = entry.getValue();
                if (value != null) {
                    PointTreeVo treeDto = map.get(value.getParentId());
                    if (treeDto != null) {
                        List<PointTreeVo> children = treeDto.getChildren();
                        if (children == null) {
                            children = new ArrayList<>();
                            treeDto.setChildren(children);
                        }
                        children.add(value);
                    } else {
                        treeList.add(value);
                    }
                }
            });
            return treeList;
        }
        return Collections.emptyList();
    }

    /**
     * 生成树结构
     *
     * @param allRiskSource
     * @return
     */
    public List<PointTreeVo> transferListTo3dPointTree(List<PointTreeVo> allRiskSource) {
        List<PointTreeVo> treeList = new ArrayList<>();
        List<PointTreeVo> pointData = fireFightingSystemMapper.get3dPointData();
        if (!CollectionUtils.isEmpty(pointData)) {
            allRiskSource.addAll(pointData);
            for (PointTreeVo tree : allRiskSource) {
                if (tree.getParentId() == null || tree.getParentId() == -1) {
                    treeList.add(tree);
                }
                for (PointTreeVo treeNode : allRiskSource) {
                    if (tree.getSequenceNbr().equals(treeNode.getParentId())) {
                        if (tree.getChildren() == null) {
                            tree.setChildren(new ArrayList<>());
                        }
                        tree.getChildren().add(treeNode);
                    }
                }
            }
            return treeList;
        }
        return Lists.newArrayList();
    }


    /**
     * 生成 性能指标数据
     *
     * @param list
     * @return
     */
    private List<SpeIndexVo> makeStatus(List<SpeIndexVo> list) {
        if (list == null || list.size() == 0) {
            return new ArrayList<>();
        }
//        List<SpeIndexVo> newList = new ArrayList<>();
        List<SpeIndexVo> statusList = new ArrayList<>();
        // 按照http://36.46.149.14:5080/zentao/task-view-5911.html的问题改动如下
//        for (SpeIndexVo vo : list) {
//            int status = vo.getIsAlarm();
//            if (AlarmStatusEnum.BJ.getCode() == status) {
//                statusList.add(vo);
//            }
//            newList.add(vo);
//        }
//        if (statusList.size() == 0) {
//            return newList;
//        }
        SpeIndexVo spe = new SpeIndexVo();
        spe.setKey(EquipmentSpeIndexEnum.YXZT.getCode());
        SpeIndexVo latestVo = list.get(0);
        BeanUtils.copyProperties(latestVo, spe);
        spe.setName("当前状态");
        Map<String, String> map = getStatus(list);
        spe.setValue(map.get("runStatus"));
        spe.setColor(map.get("color"));
        statusList.clear();
        statusList.add(spe);
        statusList.addAll(list);
        return statusList;
    }

    /**
     * 判断 装备状态
     *
     * @param statusList
     * @return
     */
    private Map<String, String> getStatus(List<SpeIndexVo> statusList) {
        Map<String, String> map = new HashMap<>();
        SpeIndexVo indexVo = statusList.get(0);
        int i = 0;
        for (SpeIndexVo x : statusList) {
            if (StringUtil.isNotEmpty(x.getIndexValue())) {
                i = i + 1;
            }
        }
        if (0 == i) {
            map.put("runStatus", "无");
            map.put("color", "");
            return map;
        }
        if (StringUtil.isNotEmpty(indexVo.getIndexValue()) && AlarmStatusEnum.HF.getCode() == indexVo.getIsAlarm()) {
            map.put("runStatus", indexVo.getIndexName());
            map.put("color", "");
            return map;
        }
        if (StringUtil.isNotEmpty(indexVo.getIndexValue()) && TrueOrFalseEnum.real.value.toUpperCase().equals(indexVo.getIndexValue().toUpperCase())) {
            map.put("runStatus", indexVo.getIndexName());
            map.put("color", indexVo.getColor());
            return map;
        }

        map.put("runStatus", "运行");
        map.put("color", "");
        return map;
    }

    @Override
    public List<FireFightingSystemEntity> getList() {
        return this.list();
    }

    @Override
    @Transactional
    public Boolean deleteSystem(Long id) {
        FireFightingSystemEntity entity = baseMapper.selectById(id);
        if (entity.getSceneId() != null) {
            try {
                FeignUtil.remoteCall(() -> Morphic.morphicSubjectClient.delete(entity.getSceneId()));
            } catch (Exception e) {
            	log.error("远程调用 MORPHIC 服务的删除操作出错:"+e.getMessage().toString(),e);
            }
        }
        formInstanceMapper.clearSystemId(id);
        //解除装备与消防系统关系
        this.removeBondSystemId(id);
        this.baseMapper.deleteFilre(String.valueOf(id));
        int i = this.baseMapper.deleteById(id);
        if (i > 0 && syncSwitch) {
            syncDataService.syncDeletedFireFightingSystem(Arrays.asList(id));
        }
        //删除系统图与设备关系表
        QueryWrapper<SourceScene> ssWrapper = new QueryWrapper<SourceScene>();
        ssWrapper.lambda().eq(SourceScene::getSourceId, id);
        sourceSceneMapper.delete(ssWrapper);
        //删除动态关联表单实例数据
        if (entity.getInstanceId() != null) {
            instanceService.remove(
                    new LambdaQueryWrapper<DynamicFormInstance>()
                            .eq(DynamicFormInstance::getInstanceId, entity.getInstanceId()));
        }
        return i > 0;
    }

    private void removeBondSystemId(Long id) {
        List<EquipmentSpecific> equipmentSpecifics = equipmentSpecificSerivce.list(new LambdaQueryWrapper<EquipmentSpecific>().like(EquipmentSpecific::getSystemId, id));
        equipmentSpecifics.forEach(equipmentSpecific -> {
            List<String> ids = new ArrayList<>();
            if (StringUtil.isNotEmpty(equipmentSpecific.getSystemId())) {
                ids = Arrays.asList(equipmentSpecific.getSystemId().split(","));
                ids = new ArrayList<>(ids);
                ids.remove(id.toString());
            }
            equipmentSpecific.setSystemId(Joiner.on(",").join(ids));
        });
        if (!equipmentSpecifics.isEmpty()) {
            equipmentSpecificSerivce.saveOrUpdateBatch(equipmentSpecifics);
        }
    }

    @Override
    public Boolean isDeleteCanvas(Long id) {
        FireFightingSystemEntity system = baseMapper.selectOne(new QueryWrapper<FireFightingSystemEntity>().eq("scene_id", id));
        if (system != null) {
            return true;
        } else {
            FeignUtil.remoteCall(() -> Morphic.morphicSubjectClient.delete(id));
            return false;
        }
    }

    @Override
    public IPage<EquipTypeImgAmountVO> getColaCategoryAmountList(int hierarchy, String codeHead, EquipTypeAmountPageDTO equipTypeAmountPage) {
        String type = equipTypeAmountPage.getType();
        if (!"".equals(type) && "car".equals(type)) {
            equipTypeAmountPage.setSystemId(null);
            equipTypeAmountPage.setStatus(null);
        }
        IPage<EquipTypeImgAmountVO> list = fireFightingSystemMapper.getColaCategoryAmountList(equipTypeAmountPage.getPage(), hierarchy, codeHead, equipTypeAmountPage);
        list.getRecords().forEach(x -> {
            if (!x.getEqtype().startsWith("4") && StringUtil.isNotEmpty(x.getAmount())) {
                x.setAmount(x.getAmount().split("\\.")[0]);
            }
        });
        return list;
    }
    @Override
    public IPage<DetailssAmountVO> getDetailsssAmountList(int hierarchy, String codeHead, DetailssDTO detailssDTO) {
        String type = detailssDTO.getType();
        if (!"".equals(type) && "car".equals(type)) {
            detailssDTO.setStatus(0);
        }
        IPage<DetailssAmountVO> list = fireFightingSystemMapper.getDetailAmountList(detailssDTO.getPage(), hierarchy, codeHead, detailssDTO);
        List<DetailssAmountVO> records = list.getRecords();
        for(DetailssAmountVO da: records){
            Long id = da.getId();
            String iotCode = equipmentSpecificService.getById(id).getIotCode();
            QueryWrapper<EquipmentParams> wrapper = new QueryWrapper<>();
            wrapper.eq("detail_id",iotCode);
            wrapper.orderByDesc("create_date");//根据创建时间进行倒叙
            List<EquipmentParams> equipmentParams = equipmentParamsMapper.selectList(wrapper);
            if(!equipmentParams.isEmpty()){
                EquipmentParams params = equipmentParams.get(0);
                da.setStatus(params.getStatus());
            }else {
                da.setStatus("正常");
            }

        }
//        list.getRecords().forEach(x -> {
//            if (!x.getEqtype().startsWith("4") && StringUtil.isNotEmpty(x.getAmount())) {
//                x.setAmount(x.getAmount().split("\\.")[0]);
//            }
//        });
        return list;
    }

    @Override
    public List<EquipmentManageVo> getSystemCategory() {
        return equipmentManageMapper.getSystemList();
    }

    @Override
    public List<FireFightingSystem> getFireFightingSystemDetail(FireFightingSystemVo fireFightingSystemVo) {
        return fireFightingSystemMapper.getFireFightingSystemDetail(fireFightingSystemVo);
    }

    @Override
    public List<FireFightingSystemEntity> getFightingSysByCodes(String[] idsArr) {
        List<FireFightingSystemEntity> fightingSystemList = fireFightingSystemMapper.getFightingSysByCodes(idsArr);
        if (fightingSystemList != null && !fightingSystemList.isEmpty()) {
            return fightingSystemList;
        }
        return Lists.newArrayList();
    }

    @Override
    public List<FireFightingSystem3dVo> get3dFightingSystemList() {
        FeignClientResult<List<DictionarieValueModel>> dictValues = Systemctl.dictionarieClient.dictValues(iotCoreParam);
        Optional.ofNullable(dictValues).orElseThrow(() -> new BadRequest("查询字段数据为空"));
        List<DictionarieValueModel> values = dictValues.getResult();
        if (!CollectionUtils.isEmpty(values)) {
            List<String> collect = values.stream().map(DictionarieValueModel::getDictDataKey).collect(Collectors.toList());
            List<FireFightingSystem3dVo> list = fireFightingSystemMapper.get3dFightingSystemList(collect);
            if (!CollectionUtils.isEmpty(list)) {
                return list;
            }
        }
        return Lists.newArrayList();
    }

    @Override
    public FireFightingSystemEntity getDetailByCode(String systemCode) {
        LambdaQueryWrapper<FireFightingSystemEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(FireFightingSystemEntity::getCode, systemCode);
        List<FireFightingSystemEntity> systemEntities = this.list(wrapper);
        if (systemEntities.isEmpty()) {
            throw new RuntimeException("code" + systemCode + "不存在");
        }
        return systemEntities.get(0);
    }

    @Override
    public List<AlarmDataVO> getSystemById(Long id) {
        return this.baseMapper.getSystemById(id);
    }

    @Override
    public IPage<EquipmentAlarmBySystemIdOrSourceIdVO> getEquipmentAlarmBySystemIdOrSourceIdVO(IPage<EquipmentAlarmBySystemIdOrSourceIdVO> page, Long sourceId, Long systemId, Integer confirmType, String createDate, String type) {
        return this.baseMapper.getEquipmentAlarmBySystemIdOrSourceIdVO(page, sourceId, systemId, confirmType, createDate, type);
    }

    private static String getInet4Address() {
        Enumeration<NetworkInterface> nis;
        String ip = null;
        try {
            nis = NetworkInterface.getNetworkInterfaces();
            for (; nis.hasMoreElements(); ) {
                NetworkInterface ni = nis.nextElement();
                Enumeration<InetAddress> ias = ni.getInetAddresses();
                for (; ias.hasMoreElements(); ) {
                    InetAddress ia = ias.nextElement();
                    if (ia instanceof Inet4Address && !ia.getHostAddress().equals("127.0.0.1")) {
                        ip = ia.getHostAddress();
                    }
                }
            }
        } catch (SocketException e) {
            e.printStackTrace();
        }
        return ip;
    }


    @Override
    public Map<String, Object> integrationPageSysData(String systemCode, Boolean isUpdate) {
        // TODO Auto-generated method stub
        if (!StringUtil.isNotEmpty(SystemTypeEnum.getEnum(systemCode))) {
            return null;
        }
        Map<String, Object> data;
        if (isUpdate) {
            data = saveIntegrationPageSysData(systemCode);
        } else {
            if (redisUtils.hasKey(systemCode)) {
                data = JSONObject.parseObject(redisUtils.get(systemCode).toString(),Map.class);
            } else {
                data = saveIntegrationPageSysData(systemCode);
            }

        }
        if (!ObjectUtils.isEmpty(data)) {
            mqttSendGateway.sendToMqtt(String.format("%s%s", "INTEGRATE_TOPIC/", systemCode), JSON.toJSONString(data));
        }
        return null;
    }

    public Map<String, Object> saveIntegrationPageSysData(String systemCode) {
        Map<String, Object> data = null;
        if (SystemTypeEnum.fireAlarmSys.getCode().equals(systemCode)) {
            data = fireFightingSystemMapper.fireAlarmSysEquipmentNumber();
            this.putAll(data, fireFightingSystemMapper.fireAlarmSysIndexNumber());
        } else if (SystemTypeEnum.fireCAFSSys.getCode().equals(systemCode)) {
            data = fireFightingSystemMapper.getFireCafsSystem();
        } else if (SystemTypeEnum.fireONLSys.getCode().equals(systemCode)) {
            data = fireFightingSystemMapper.getFireOnlSystem();
            this.putAll(data, fireFightingSystemMapper.getFireOnlSystemThreeSmall());
        } else if (SystemTypeEnum.fireFoamSys.getCode().equals(systemCode)) {
            data = fireFightingSystemMapper.fireFoamSysEquipmentIndexNumber();
        } else if (SystemTypeEnum.fireFoamMistSys.getCode().equals(systemCode) || SystemTypeEnum.envMonitoringSys.getCode().equals(systemCode)) {
            //TODO 灯泡及门状态，实时数据库刷新,存放数据，套用后续逻辑进行数据的发送
            data = new HashMap<>();
            data.put("waitRefresh", true);
        } else if (SystemTypeEnum.fireWaterSys.getCode().equals(systemCode)) {
            data = fireFightingSystemMapper.fireWaterSysCollectingDevice();
            this.putAll(data, fireFightingSystemMapper.fireWaterSysPool());
            this.putAll(data, fireFightingSystemMapper.fireWaterSysWaterPump());
            this.putAll(data, fireFightingSystemMapper.fireWaterSysHydrant());
            this.putAll(data, fireFightingSystemMapper.fireWaterSysPipeNetwork());
        } else {
            data = fireFightingSystemMapper.otherSysIndexNumAndTotal();
        }
        if (!ObjectUtils.isEmpty(data)) {
            redisUtils.set(systemCode, JSONObject.toJSONString(data));
        }
        return data;
    }

    private void putAll(Map<String, Object> data, Map<String, Object> addMap) {
        if (!CollectionUtils.isEmpty(addMap)) {
            data.putAll(addMap);
        }
    }


}
