package com.yeejoin.equipmanage.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.base.Joiner;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.yeejoin.amos.boot.biz.common.dto.OrgMenuDto;
import com.yeejoin.equipmanage.common.entity.*;
import com.yeejoin.equipmanage.common.entity.dto.VideoDTO;
import com.yeejoin.equipmanage.common.entity.dto.VideoSaveDto;
import com.yeejoin.equipmanage.common.entity.publics.BaseEntity;
import com.yeejoin.equipmanage.common.entity.vo.*;
import com.yeejoin.equipmanage.common.enums.EquipmentSpeIndexEnum;
import com.yeejoin.equipmanage.common.enums.IndustryEnum;
import com.yeejoin.equipmanage.common.enums.VideoTypeEnum;
import com.yeejoin.equipmanage.common.utils.HttpContentTypeUtil;
import com.yeejoin.equipmanage.common.utils.StringUtil;
import com.yeejoin.equipmanage.dto.CountDto;
import com.yeejoin.equipmanage.fegin.VideoFeignClient;
import com.yeejoin.equipmanage.mapper.VideoMapper;
import com.yeejoin.equipmanage.service.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
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.ObjectUtils;
import org.typroject.tyboot.core.foundation.utils.Bean;
import org.typroject.tyboot.core.foundation.utils.ValidationUtil;
import org.typroject.tyboot.core.restful.utils.ResponseModel;

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

/**
 * @author ZeHua Li
 * @date 2020/11/23 15:28
 * @since v2.0
 */

@Slf4j
@Service
//@EnableAsync
public class VideoServiceImpl extends ServiceImpl<VideoMapper, Video> implements IVideoService {

    @Autowired
    IVideoEquipmentSpecificService videoEquipmentSpecificService;
    @Autowired
    IVideoSourceService videoSourceService;
    @Autowired
    IVideoImportantEquipmentService videoImportantEquipmentService;
    @Autowired
    IEquipmentCategoryService iEquipmentCategoryService;
    @Autowired
    IEquipmentSpecificIndexService iEquipmentSpecificIndexService;
    @Autowired
    IEquipmentIndexService iEquipmentIndexService;
    @Autowired
    IBuilldService iBuilldService;
    @Autowired
    IWarehouseStructureService warehouseStructureService;
    @Autowired
    @Lazy
    IEquipmentSpecificSerivce equipmentSpecificSerivce;
    @Value("${equip.security.code}")
    String securityMonitorCode;

    @Value("${window.vedioFormat}")
    String vedioFormat;

    @Autowired
    VideoMapper videoMapper;

    @Value("${fxkgtId}")
    private String deptId;

    @Autowired
    VideoFeignClient videoFeignClient;


    @Value("${param.htvideo.url}")
    private String htvideoUrl;

    @Value("${param.nrvideo.url}")
    private String nrvideoUrl;
    
    @Value("${param.nrflvbyvoideoid.url}")
    private String nrflvByVoideoidUrl;


    @Value("${dcs.client-id}")
    private String clientId;

    @Autowired
    JCSRemoteService jcsRemoteService;

    @Value("${auth-key-fire-video:fire_video_info}")
    private String authKey;

    @Transactional
    @Override
    public Video saveVideo(VideoSaveDto videoSave) {
        this.save(videoSave.getVideo());
        List<VideoEquipmentSpecific> videoEquipmentSpecifics = new ArrayList<>();
        List<VideoSource> videoSources = new ArrayList<>();
        if (videoSave.getIds() != null && videoSave.getIds().size() > 0) {
            videoSave.getIds().forEach(x -> {
                if (x != null && x.contains("equip")) {
                    VideoEquipmentSpecific videoEquipmentSpecific = new VideoEquipmentSpecific();
                    videoEquipmentSpecific.setEquipmentSpecificId(Long.valueOf(x.substring(5)));
                    videoEquipmentSpecific.setVideoId(videoSave.getVideo().getId());
                    videoEquipmentSpecifics.add(videoEquipmentSpecific);
                } else if (x != null && x.contains("region")) {
                    VideoSource videoSource = new VideoSource();
                    videoSource.setVideoId(videoSave.getVideo().getId());
                    videoSource.setSourceId(Long.valueOf(x.substring(6)));
                    videoSource.setParentSourceIds(getParentSourceIds(videoSource.getSourceId().toString()));
                    videoSources.add(videoSource);
                }
            });
        }
        List<VideoImportantEquipment> videoImportantEquipments = new ArrayList<>();
        if (videoSave.getVideoImportantEquipments() != null && videoSave.getVideoImportantEquipments().size() > 0) {
            videoSave.getVideoImportantEquipments().forEach(x -> {
                if (null != x) {
                    VideoImportantEquipment videoImportantEquipment = new VideoImportantEquipment();
                    videoImportantEquipment.setImportantEquipmentId(x);
                    videoImportantEquipment.setVideoId(videoSave.getVideo().getId());
                    videoImportantEquipments.add(videoImportantEquipment);
                }
            });
        }
        videoImportantEquipmentService.saveBatch(videoImportantEquipments);
        videoEquipmentSpecificService.saveBatch(videoEquipmentSpecifics);
        videoSourceService.saveBatch(videoSources);
        return videoSave.getVideo();
    }

    private String getParentSourceIds(String childrenId){
        return this.videoMapper.getParentSourceIds(childrenId);
    }

    @Transactional
    @Override
    public Boolean delVideo(List<Long> ids) {
        String errorMeg = "";
        for (Long id : ids) {
            List<String> list = baseMapper.selectBuildList(id);
            if (list != null && list.size() > 0) {
                for (String s : list) {
                    errorMeg = errorMeg.equals("") ? s : errorMeg + "," + s;
                }
                throw new RuntimeException("监控设备与楼层:" + errorMeg + ",存在绑定关系，无法删除");
            }
        }
        QueryWrapper<VideoEquipmentSpecific> videoEquipmentSpecificQueryWrapper = new QueryWrapper<>();
        videoEquipmentSpecificQueryWrapper.in("video_id", ids);
        videoEquipmentSpecificService.remove(videoEquipmentSpecificQueryWrapper);
        QueryWrapper<VideoSource> videoSourceQueryWrapper = new QueryWrapper<>();
        videoSourceQueryWrapper.in("video_id", ids);
        videoSourceService.remove(videoSourceQueryWrapper);
        QueryWrapper<VideoImportantEquipment> videoImportantEquipmentQueryWrapper = new QueryWrapper<>();
        videoImportantEquipmentQueryWrapper.in("video_id", ids);
        videoImportantEquipmentService.remove(videoImportantEquipmentQueryWrapper);
        return this.removeByIds(ids);
    }

    @Override
    public Video updateVideo(VideoSaveDto videoSave) {
        this.updateById(videoSave.getVideo());
        QueryWrapper<VideoEquipmentSpecific> videoEquipmentSpecificQueryWrapper = new QueryWrapper<>();
        videoEquipmentSpecificQueryWrapper.in("video_id", videoSave.getVideo().getId());
        videoEquipmentSpecificService.remove(videoEquipmentSpecificQueryWrapper);
        QueryWrapper<VideoSource> videoSourceQueryWrapper = new QueryWrapper<>();
        videoSourceQueryWrapper.in("video_id", videoSave.getVideo().getId());
        videoSourceService.remove(videoSourceQueryWrapper);
        QueryWrapper<VideoImportantEquipment> videoImportantEquipmentQueryWrapper = new QueryWrapper<>();
        videoImportantEquipmentQueryWrapper.in("video_id", videoSave.getVideo().getId());
        videoImportantEquipmentService.remove(videoImportantEquipmentQueryWrapper);
        List<VideoEquipmentSpecific> videoEquipmentSpecifics = new ArrayList<>();
        List<VideoSource> videoSources = new ArrayList<>();
        if (videoSave.getIds() != null && videoSave.getIds().size() > 0) {
            videoSave.getIds().forEach(x -> {
                if (x != null && x.contains("equip")) {
                    VideoEquipmentSpecific videoEquipmentSpecific = new VideoEquipmentSpecific();
                    videoEquipmentSpecific.setEquipmentSpecificId(Long.valueOf(x.substring(5)));
                    videoEquipmentSpecific.setVideoId(videoSave.getVideo().getId());
                    videoEquipmentSpecifics.add(videoEquipmentSpecific);
                } else if (x != null && x.contains("region")) {
                    VideoSource videoSource = new VideoSource();
                    videoSource.setVideoId(videoSave.getVideo().getId());
                    videoSource.setSourceId(Long.valueOf(x.substring(6)));
                    videoSource.setParentSourceIds(getParentSourceIds(videoSource.getSourceId().toString()));
                    videoSources.add(videoSource);
                }
            });
        }
        List<VideoImportantEquipment> videoImportantEquipments = new ArrayList<>();
        if (videoSave.getVideoImportantEquipments() != null && videoSave.getVideoImportantEquipments().size() > 0) {
            videoSave.getVideoImportantEquipments().forEach(x -> {
                VideoImportantEquipment videoImportantEquipment = new VideoImportantEquipment();
                videoImportantEquipment.setImportantEquipmentId(x);
                videoImportantEquipment.setVideoId(videoSave.getVideo().getId());
                videoImportantEquipments.add(videoImportantEquipment);
            });
        }
        videoImportantEquipmentService.saveBatch(videoImportantEquipments);
        videoEquipmentSpecificService.saveBatch(videoEquipmentSpecifics);
        videoSourceService.saveBatch(videoSources);
        return videoSave.getVideo();
    }

    @Override
    public Page<PageVideoVO> pageVideo(VideoDTO videoDTO) {
        Video video = videoDTO.getVideo();
        String bizOrgCode = video.getBizOrgCode();
        return this.baseMapper.pageVideo(videoDTO.getPage(), video);
    }

    @Override
    public VideoSaveDto detail(Long id) {
        VideoSaveDto videoSaveDto = new VideoSaveDto();
        List<String> list = new ArrayList<>();
        List<Long> importantEquipmentList = new ArrayList<>();
        Video video = this.getById(id);
        videoSaveDto.setVideo(video);
        //添加设备
        QueryWrapper<VideoEquipmentSpecific> videoEquipmentSpecificQueryWrapper = new QueryWrapper<>();
        videoEquipmentSpecificQueryWrapper.eq("video_id", id);
        List<VideoEquipmentSpecific> videoEquipmentSpecifics = videoEquipmentSpecificService.list(videoEquipmentSpecificQueryWrapper);
        videoEquipmentSpecifics.forEach(x -> {
            list.add("equip" + x.getEquipmentSpecificId());
        });
        //添加区域
        QueryWrapper<VideoSource> videoSourceQueryWrapper = new QueryWrapper<>();
        videoSourceQueryWrapper.eq("video_id", id);
        List<VideoSource> videoSources = videoSourceService.list(videoSourceQueryWrapper);
        videoSources.forEach(x -> {
            list.add("region" + x.getSourceId());
        });
        //添加区域
        QueryWrapper<VideoImportantEquipment> videoImportantEquipmentQueryWrapper = new QueryWrapper<>();
        videoImportantEquipmentQueryWrapper.eq("video_id", id);
        List<VideoImportantEquipment> videoImportantEquipments = videoImportantEquipmentService.list(videoImportantEquipmentQueryWrapper);
        videoImportantEquipments.forEach(x -> {
            importantEquipmentList.add(x.getImportantEquipmentId());
        });
        videoSaveDto.setIds(list);
        videoSaveDto.setVideoImportantEquipments(importantEquipmentList);
        return videoSaveDto;
    }

    @Override
    public Page<BuildingVideoVO> pageBuildingVideo(Page page, BuildingVideoListVO dto) {
        return this.baseMapper.pageBuildingVideo(page, dto);
    }

    @Override
    public List<BuildingListVO> getFireEquipByVideoId(Long videoId) {
        return this.baseMapper.getFireEquipByVideoId(videoId);
    }

    @Override
    public List<BuildingListVO> getPowerEquipByVideoId(Long videoId) {
        return this.baseMapper.getPowerEquipByVideoId(videoId);
    }

    @Override
    public Page<BuildingVideoVO> pageColaBuildingVideo(Page page, BuildingVideoListVO dto) {
        List<String> securityCodeList = new ArrayList<>();
        securityCodeList = this.getSecurityCodeList();
        dto.setMonitorCodes(securityCodeList);
        Page<BuildingVideoVO> voPage;
        if (StringUtil.isNotEmpty(dto.getBuildingId())) {
            Long buildId = Long.valueOf(dto.getBuildingId());
            dto.setColaBuildingId(buildId);
            List<PageSecurityVideoVO> childList = this.getBaseMapper().getMenuChildren(buildId);
            List<Long> idsList = new ArrayList<>();
            if (0 < childList.size()) {
                for (PageSecurityVideoVO vo : childList) {
                    idsList.add(vo.getId());
                }
            }
            idsList.add(buildId);
            dto.setBuildIdList(idsList);
            voPage = this.baseMapper.pageColaBuildingVideo(page, dto);
        } else {
            voPage = this.baseMapper.listColaBuildingVideo(page, dto);
        }
        int countVideos = voPage.getRecords().size();
        if (0 < countVideos) {
            voPage.getRecords().forEach(x -> {
                Long speId = x.getSpecificId();
                QueryWrapper<EquipmentSpecificIndex> indexWrapper = new QueryWrapper<>();
                indexWrapper.lambda().eq(EquipmentSpecificIndex::getEquipmentSpecificId, speId);
                List<EquipmentSpecificIndex> indexList = iEquipmentSpecificIndexService.list(indexWrapper);
                if (0 < indexList.size()) {
                    indexList.forEach(y -> {
                        QueryWrapper<EquipmentIndex> wrapper = new QueryWrapper<>();
                        wrapper.lambda().eq(EquipmentIndex::getId, y.getEquipmentIndexId());
                        List<EquipmentIndex> list1 = iEquipmentIndexService.list(wrapper);
                        List<EquipmentIndex> tokenIndexList = list1.stream().filter(index -> EquipmentSpeIndexEnum.TOKEN.getCode().equals(index.getPerfQuotaDefinitionId())).collect(Collectors.toList());
                        List<EquipmentIndex> list2 = iEquipmentIndexService.list(wrapper);
                        List<EquipmentIndex> urlIndexList = list2.stream().filter(index -> EquipmentSpeIndexEnum.URL.getCode().equals(index.getPerfQuotaDefinitionId())).collect(Collectors.toList());
                        if (0 < tokenIndexList.size()) {
                            x.setToken(y.getValue());
                        }
                        if (0 < urlIndexList.size()) {
                            x.setUrl(y.getValue());
                        }
                    });
                }
            });
        }
        return voPage;
    }

    @Override
    public List<String> getSecurityCodeList() {
        List<String> securityCodeList = new ArrayList<>();
        QueryWrapper<EquipmentCategory> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(EquipmentCategory::getCode, securityMonitorCode);
        queryWrapper.lambda().eq(EquipmentCategory::getIndustryCode, IndustryEnum.SECURITY.getCode());
        EquipmentCategory category = iEquipmentCategoryService.getOne(queryWrapper);
        securityCodeList.add(securityMonitorCode);
        if (ObjectUtils.isEmpty(category)) {
            return securityCodeList;
        }
        List<EquipmentCategoryTypeTreeVO> list = iEquipmentCategoryService.getTypeTree(Long.valueOf(category.getId()));
        if (0 < list.size()) {
            list.forEach(w -> {
                String code;
                code = w.getEquipmentClassificationCode();
                securityCodeList.add(code);
                if (0 < w.getChildren().size()) {
                    w.getChildren().forEach(x -> {
                        String code1;
                        code1 = x.getEquipmentClassificationCode();
                        securityCodeList.add(code1);
                        if (0 < x.getChildren().size()) {
                            x.getChildren().forEach(y -> {
                                String code2;
                                code2 = y.getEquipmentClassificationCode();
                                securityCodeList.add(code2);
                                if (0 < y.getChildren().size()) {
                                    y.getChildren().forEach(z -> {
                                        String code3;
                                        code3 = z.getEquipmentClassificationCode();
                                        securityCodeList.add(code3);
                                    });
                                }
                            });
                        }
                    });
                }
            });
        }
        return securityCodeList;
    }

    static final Pattern urlPattern = Pattern.compile("^(((http)|(https)):\\/\\/)?([0-9]{1,3}.){3}[0-9]{1,3}(:[1-3]?[0-9]{1,4})?$");

    private List<Long> getParents(Map<Long, Long> allMap, Long wsId) {
        List<Long> parents = Lists.newLinkedList();
        if (wsId != null && wsId != 0) {
            parents.add(wsId);
            parents.addAll(getParents(allMap, allMap.get(wsId)));
        }
        parents.remove(0L);
        return parents;
    }

    @Override
    @Transactional(rollbackFor = {Exception.class})
    public List<Video> videoUpload(List<VideoDownloadVO> videoDownloadVOS) {
        List<Video> videos = new ArrayList<>();
        List<VideoSource> videoSources = new ArrayList<>();
        List<VideoEquipmentSpecific> videoEquipmentSpecifics = new ArrayList<>();
        List<VideoImportantEquipment> videoImportantEquipments = new ArrayList<>();
        if (videoDownloadVOS.isEmpty()) {
            return videos;
        }

        // 获取所有的视频设备编号
        Set<String> videoCodeSet = new HashSet(Bean.listToMap(this.baseMapper.selectList(new QueryWrapper<>()), "code", Video.class).keySet());
        // 所有建筑列表
        List<WarehouseStructure> allWarehouseStructureList =
                warehouseStructureService.list().stream().filter(z -> StringUtil.isNotEmpty(z.getCode())).collect(Collectors.toList());
        // 建筑对应父级建筑map
        Map<Long, String> withParentMap = Maps.newHashMap();
        if (!ValidationUtil.isEmpty(allWarehouseStructureList)) {
            Map<Long, Long> allMap = allWarehouseStructureList.stream().collect(Collectors.toMap(BaseEntity::getId,
                    WarehouseStructure::getParentId));
            allWarehouseStructureList.forEach(ws -> withParentMap.put(ws.getId(),
                    Joiner.on(",").join(getParents(allMap, ws.getId()))));
        }
        // 获取所有的建筑code与id对应关系
        Map<String, Long> buildingMap = new HashMap(Bean.listToMap(allWarehouseStructureList, "code", "id", WarehouseStructure.class));
        // 获取所有的装备code与id对应关系
        Map<String, Long> equipMap = new HashMap(Bean.listToMap(equipmentSpecificSerivce.list().stream().filter(z -> StringUtil.isNotEmpty(z.getCode())).collect(Collectors.toList()), "code", "id", EquipmentSpecific.class));
        // 获取所有重点设备code与id对应关系
        Map<String, Long> fireMap = new HashMap(Bean.listToMap(baseMapper.selectImportantEquipment().stream().filter(z -> StringUtil.isNotEmpty(z.getCode())).collect(Collectors.toList()), "code", "id", EquipmentSpecificVo.class));
        for (int i = 0; i < videoDownloadVOS.size(); i++) {
            //第二行开始为数据
            int rowNum = i + 2;
            VideoDownloadVO x = videoDownloadVOS.get(i);
            // 数据校验
            if (ValidationUtil.isEmpty(x.getName()) || ValidationUtil.isEmpty(x.getCode())
//                    || ValidationUtil.isEmpty(x.getUrl()) || ValidationUtil.isEmpty(x.getToken())
                    || ValidationUtil.isEmpty(x.getAddress())) {
                throw new RuntimeException("错误行" + rowNum + "：请检查非空字段");
            }
            if (videoCodeSet.contains(x.getCode().trim())) {
                throw new RuntimeException("错误行" + rowNum + "：重复的视频设备编码");
            }
            videoCodeSet.add(x.getCode().trim());
            if (!StringUtil.isNotEmpty(x.getUrl())) {
                throw new RuntimeException("错误行" + rowNum + "：视频地址不能为空");
            }
            if (ValidationUtil.isEmpty(x.getType())) {
                throw new RuntimeException("视频类型(枪机/球机)不能为空，请修改后上传！");
            }
            if (ValidationUtil.isEmpty(x.getBizOrgCode())) {
                throw new RuntimeException("机构编码不能为空，请修改后上传！");
            }
            if (ValidationUtil.isEmpty(x.getBizOrgName())) {
                throw new RuntimeException("机构/部门名称不能为空，请修改后上传！");
            }



            //字段长度效验
            if (!ValidationUtil.isEmpty(x.getName())&&x.getName().length()>100) {
                throw new RuntimeException("错误行" + rowNum + "：名字不能大于100");
            }
            if (!ValidationUtil.isEmpty(x.getCode())&&x.getCode().length()>100) {
                throw new RuntimeException("错误行" + rowNum + "：编号不能大于100");
            }
            if (!ValidationUtil.isEmpty(x.getUrl())&&x.getUrl().length()>255) {
                throw new RuntimeException("错误行" + rowNum + "：视频地址过长");
            }
            if (!ValidationUtil.isEmpty(x.getToken())&&x.getToken().length()>255) {
                throw new RuntimeException("错误行" + rowNum + "：token不能大于255");
            }
            if (!ValidationUtil.isEmpty(x.getBizOrgCode())&&x.getBizOrgCode().length()>64) {
                throw new RuntimeException("错误行" + rowNum + "：机构编码不能大于64");
            }
            if (!ValidationUtil.isEmpty(x.getBizOrgName())&&x.getBizOrgName().length()>128) {
                throw new RuntimeException("错误行" + rowNum + "：机构名称不能大于128");
            }

            if (!ValidationUtil.isEmpty(x.getAddress())&&x.getAddress().length()>2000) {
                throw new RuntimeException("错误行" + rowNum + "：地址不能大于2000");
            }

            if (ValidationUtil.isEmpty(x.getRemark())&&x.getRemark().length()>255) {
                throw new RuntimeException("错误行" + rowNum + "：备注不能大于255");
            }

            if (!ValidationUtil.isEmpty(x.getImg())&&x.getImg().length()>100) {
                throw new RuntimeException("错误行" + rowNum + "：备注不能大于100");
            }

//            if (!urlPattern.matcher(x.getUrl().trim()).matches()) {
//                throw new RuntimeException("错误行" + rowNum + "：视频地址格式有误，仅支持协议+ip+端口的格式");
//            }
            // 插入监控数据
            Video video = new Video();
            video.setToken(x.getToken());
            video.setName(x.getName());
            video.setUrl(x.getUrl());
            video.setCode(x.getCode());
            video.setRemark(x.getRemark());
            video.setAddress(x.getAddress());
            video.setImg(x.getImg());
            video.setType(x.getType());
            video.setTypeCode(!ObjectUtils.isEmpty(VideoTypeEnum.getCode(x.getType()))?VideoTypeEnum.getCode(x.getType()):"");
            video.setBizOrgCode(x.getBizOrgCode());
            video.setBizOrgName(x.getBizOrgName());
            videos.add(video);

            try {
            this.baseMapper.insert(video);
            // 处理监控和建筑关系
            if (!ValidationUtil.isEmpty(x.getBuildingCodes())) {
                if (!buildingMap.containsKey(x.getBuildingCodes().trim())) {
                    throw new RuntimeException("错误行" + rowNum + "：错误的建筑编码");
                }
                VideoSource videoSource = new VideoSource();
                videoSource.setVideoId(video.getId());
                videoSource.setSourceId(buildingMap.get(x.getBuildingCodes().trim()));
                videoSource.setParentSourceIds(withParentMap.get(buildingMap.get(x.getBuildingCodes().trim())));
                videoSources.add(videoSource);
            }
            // 处理监控和多个装备关系（1个摄像头对多个装备）
            videoEquipmentSpecifics.addAll(this.buildVideoEquipmentSpecific(equipMap, video.getId(), x.getEquipmentSpecificCodes(), rowNum));
            // 处理监控和多个电力设备关系（1个摄像头对多个电力装备）
            videoImportantEquipments.addAll(this.buildVideoImportantEquipment(fireMap, video.getId(), x.getImportantEquipmentCodes(), rowNum));
            }catch (Exception e) {
                throw new RuntimeException(e.getMessage());
            }
        }
        if (!videoSources.isEmpty()) {
            videoSourceService.saveBatch(videoSources);
        }
        if (!videoEquipmentSpecifics.isEmpty()) {
            videoEquipmentSpecificService.saveBatch(videoEquipmentSpecifics);
        }
        if (!videoImportantEquipments.isEmpty()) {
            videoImportantEquipmentService.saveBatch(videoImportantEquipments);
        }
        return videos;
    }

    private List<VideoImportantEquipment> buildVideoImportantEquipment(Map<String, Long> fireMap, Long videoId, String importantEquipmentCodes, int rowNum) {
        List<VideoImportantEquipment> videoImportantEquipments = new ArrayList<>();
        String trimStrCodes = StringUtils.isNotBlank(importantEquipmentCodes) ? importantEquipmentCodes.trim().replaceAll("\\s*|\t|\r|\n", "") : "";
        if (ValidationUtil.isEmpty(trimStrCodes)) {
            return videoImportantEquipments;
        }
        //已分号分隔
        List<String> importantEquipmentCodesList = Arrays.asList(trimStrCodes.split(";"));
        //判断是否存在定义的消防设备code
        List<String> noMatchEquipmentSpecific = importantEquipmentCodesList.stream().filter(s -> !fireMap.containsKey(s)).collect(Collectors.toList());
        if (!noMatchEquipmentSpecific.isEmpty()) {
            throw new RuntimeException("错误行" + rowNum + "：重点设备编码不存在" + JSONObject.toJSONString(noMatchEquipmentSpecific));
        }
        importantEquipmentCodesList.forEach(code -> {
            VideoImportantEquipment videoImportantEquipment = new VideoImportantEquipment();
            videoImportantEquipment.setVideoId(videoId);
            videoImportantEquipment.setImportantEquipmentId(fireMap.get(code));
            videoImportantEquipments.add(videoImportantEquipment);
        });
        return videoImportantEquipments;
    }

    private List<VideoEquipmentSpecific> buildVideoEquipmentSpecific(Map<String, Long> equipMap, Long videoId, String equipmentSpecificCodes, int rowNum) {
        //去掉空格及换行
        String trimStrCodes = StringUtils.isNotBlank(equipmentSpecificCodes) ? equipmentSpecificCodes.trim().replaceAll("\\s*|\t|\r|\n", "") : "";
        List<VideoEquipmentSpecific> specifics = new ArrayList<>();
        if (!StringUtils.isNotBlank(trimStrCodes)) {
            return specifics;
        }
        //已分号分隔
        List<String> equipmentSpecificCodeList = Arrays.asList(trimStrCodes.split(";"));
        //判断是否存在定义的消防设备code
        List<String> noMatchEquipmentSpecific = equipmentSpecificCodeList.stream().filter(s -> !equipMap.containsKey(s)).collect(Collectors.toList());
        if (!noMatchEquipmentSpecific.isEmpty()) {
            throw new RuntimeException("错误行" + rowNum + "：装备编码不存在" + JSONObject.toJSONString(noMatchEquipmentSpecific));
        }
        equipmentSpecificCodeList.forEach(e -> {
            VideoEquipmentSpecific videoEquipmentSpecific = new VideoEquipmentSpecific();
            videoEquipmentSpecific.setVideoId(videoId);
            videoEquipmentSpecific.setEquipmentSpecificId(equipMap.get(e));
            specifics.add(videoEquipmentSpecific);
        });
        return specifics;
    }

    @Override
    public List<VideoListVo> pageVideoList(Integer pageNum, Integer pageSize, Double longitude, Double latitude, Double distance) {

        return videoMapper.pageVideoList(pageNum, pageSize, longitude, latitude, distance);
    }

    @Override
    public List<VideoListVo> pageVideoListByAlert(Integer pageNum, Integer pageSize,RequestData par) {

        return videoMapper.pageVideoListByAlert(pageNum, pageSize, par,deptId);
    }

    @Override
    public List<BuildingVideoVO> pageBuildingVideoList(Page page, BuildingVideoListVO dto) {
        return this.baseMapper.pageBuildingVideoList(page.getCurrent(),page.getSize(), dto,deptId);
    }

    @Override
    public int pageBuildingVideoCount( BuildingVideoListVO dto) {
        return this.baseMapper.pageBuildingVideoCount( dto,deptId);
    }


    @Override
    public int VideoListByAlertCount(RequestData par) {

        return videoMapper.VideoListByAlertCount( par,deptId);
    }




    @Override
    public int pageVideoCount(Double longitude, Double latitude, Double distance) {
        return videoMapper.pageVideoCount(longitude, latitude, distance);
    }




    @Override
    public List<VideoListVo> listByType(String type) {
        return videoMapper.listByType(type);
    }


    @Override
    public List<Video> listByCode(String code) {
        return videoMapper.listByCode(code);
    }


    @Override
    public String getVideoUrl(String videoName, String presetIndex, String defaultUrl, String code) {
    	String url = "";
        if ("hls".equals(vedioFormat)) {
            url = getVideoUrl(code);
        } else {
        	url = getFlvUrlByVideoId(code);
        }
        return ObjectUtils.isEmpty(url) ? defaultUrl : url;
    }

    @Override
    public List<OrgMenuDto> companyTreeByUserAndType(String type) {
        return jcsRemoteService.getCompanyDeptTreeWithAuth(authKey, type);
    }

    private String getVideoUrl(String code) {
        String url = "";
        try {
            ResponseModel<String> da = videoFeignClient.videoUrlByIndexCode(code);
            if (!ObjectUtils.isEmpty(da)) {
                url = da.getResult().substring(da.getResult().indexOf("openUrl"));
            }
        } catch (Exception e) {
            log.error("视频服务调用失败", e.getMessage());
        }
        return url;
    }
    
    public String getFlvUrlByVideoId(String videoId) {
        try {
            Map<String, Object> request = new HashMap<String, Object>();
            request.put("cameraId", videoId);
            request.put("clientType", 1);
            request.put("streamType", 1);
            request.put("templetId ", "000004");
            request.put("urlType", 4);
            JSONObject json = new JSONObject(request);
            log.info("request：{}", JSONObject.toJSONString(request));
            log.info("nrvideoUrl=={}", nrflvByVoideoidUrl);
            String content = HttpContentTypeUtil.sendHttpPostJson(nrflvByVoideoidUrl, json.toJSONString());
            if (ObjectUtils.isEmpty(content)) {
                log.error("getFlvUrlByVideoId=flv视频流接口获取失败,参数:{}" + JSONObject.toJSONString(request));
            }
            Map<String, Object> respond = JSONObject.parseObject(content, Map.class);
            log.error("getFlvUrlByVideoId=flv视频流接口返回respond:{}" + JSONObject.toJSONString(respond));
            if ("SUCCESS".equals(respond.get("resultDesc")) && respond.containsKey("url")) {
                return respond.get("url").toString();
            }

            return "";
        } catch (Exception e) {
            log.error("getFlvUrlByVideoId=flv视频流接口获取失败:{}", e.getMessage());
        }
        return "";
    }


    public String getFlvUrlByVideoIdOrPresetIndex(String videoId, String presetIndex) {
        try {
            String rtsp = getRtspUrlByVideoIdOrPresetIndex(videoId, presetIndex);
            if (ObjectUtils.isEmpty(rtsp)) {
                log.error("rtsp接口获取失败");
                return "";
            }
            Map<String, String> request = new HashMap<String, String>();
            request.put("clientId", clientId);
            request.put("messageType", "/video-service/transcode/getCameraPlaybackFlv/call");
            request.put("cameraId", videoId);
            request.put("rtsp ", rtsp);
            log.info("request：{}", JSONObject.toJSONString(request));
            log.info("nrvideoUrl=={}", nrvideoUrl);
            String content = HttpContentTypeUtil.sendHttpGetWithHeader(nrvideoUrl, request);
            if (ObjectUtils.isEmpty(content)) {
                log.error("getFlvUrlByVideoIdOrPresetIndex==flv视频流接口获取失败,参数:{}" + JSONObject.toJSONString(request));
            }
            Map<String, String> respond = JSONObject.parseObject(content, Map.class);
            log.error("getFlvUrlByVideoIdOrPresetIndex==flv视频流接口返回respond:{}" + JSONObject.toJSONString(respond));
            if (respond.containsKey("url")) {
                return respond.get("url");
            }

            return "";
        } catch (Exception e) {
            log.error("getFlvUrlByVideoIdOrPresetIndex==flv视频流接口获取失败:{}", e.getMessage());
        }
        return "";
    }


    public String getRtspUrlByVideoIdOrPresetIndex(String videoId, String presetIndex) {
        Map<String, String> videoRequest = new HashMap<String, String>();
        videoRequest.put("clientId", clientId);
        videoRequest.put("messageType", "getCameraRTSP");
        videoRequest.put("cameraId", videoId);
        videoRequest.put("presetIndex", ObjectUtils.isEmpty(presetIndex) ? "1" : presetIndex);
        log.info("videoRequest:{}", JSONObject.toJSONString(videoRequest));
        log.info("htvideoUrl=={}", htvideoUrl);
        String content = HttpContentTypeUtil.sendHttpGetWithHeader(htvideoUrl, videoRequest);
        if (ObjectUtils.isEmpty(content)) {
            log.error("getRtspUrlByVideoIdOrPresetIndex==接口获取失败,参数={}", JSONObject.toJSONString(videoRequest));
        }
        Map<String, String> respond = JSONObject.parseObject(content, Map.class);

        log.info("respond=={}" + JSONObject.toJSONString(respond));
        if (respond.containsKey("rtsp")) {
            return respond.get("rtsp");
        }
        return "";
    }

    @Override
    public Map<String, Long> getVideoCountMap() {
        List<CountDto> videoCountMapList = videoMapper.getVideoCountMapList();
        Map<String, Long> videoMap = new HashMap<>();
        videoCountMapList.forEach(item -> {
            videoMap.put(item.getBizOrgCode(), videoCountMapList.stream().filter(c->c.getBizOrgCode().contains(item.getBizOrgCode())).mapToLong(CountDto::getNum).sum());
        });
        return videoMap;
    }

}
