package com.sooka.sponest.monitor.camera.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.core.constant.UserConstants;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.utils.DateUtils;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.core.utils.uuid.IdUtils;
import com.ruoyi.common.core.web.domain.AjaxResult;
import com.ruoyi.common.datascope.annotation.DataScopeMutiDept;
import com.ruoyi.common.security.utils.DictUtils;
import com.ruoyi.common.security.utils.SecurityUtils;
import com.ruoyi.system.api.domain.SysDept;
import com.ruoyi.system.api.domain.SysDictData;
import com.sooka.sponest.monitor.aidevicedept.domain.CenterdataTAidevicedept;
import com.sooka.sponest.monitor.aidevicedept.domain.CenterdataTAidevicedeptDTO;
import com.sooka.sponest.monitor.aidevicedept.mapper.CenterdataTAidevicedeptMapper;
import com.sooka.sponest.monitor.aideviceevent.mapper.CenterdataTAideviceeventMapper;
import com.sooka.sponest.monitor.base.service.impl.BaseService;
import com.sooka.sponest.monitor.camera.domain.*;
import com.sooka.sponest.monitor.camera.mapper.CentermonitorTCameraCallLogMapper;
import com.sooka.sponest.monitor.camera.mapper.CentermonitorTCameraMapper;
import com.sooka.sponest.monitor.camera.mapper.CentermonitorTCamerachannelMapper;
import com.sooka.sponest.monitor.camera.service.ICentermonitorTCameraService;
import com.sooka.sponest.monitor.remoteapi.service.center.event.RemoteEventBaseService;
import com.sooka.sponest.monitor.remoteapi.service.center.system.RemoteService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.lang.reflect.Field;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * 摄像头Service业务层处理
 *
 * @author ruoyi
 * @date 2022-06-08
 */
@Service
public class CentermonitorTCameraServiceImpl extends BaseService implements ICentermonitorTCameraService {

    @Resource
    private CentermonitorTCameraMapper centermonitorTCameraMapper;

    @Resource
    private CentermonitorTCamerachannelMapper centermonitorTCamerachannelMapper;

    @Resource
    private CenterdataTAideviceeventMapper centerdataTAideviceeventMapper;

    @Resource
    private CenterdataTAidevicedeptMapper centerdataTAidevicedeptMapper;

    @Resource
    private RemoteService remoteService;

    @Resource
    private RemoteEventBaseService remoteEventBaseService;

    @Resource
    private CentermonitorTCameraCallLogMapper centermonitorTCameraCallLogMapper;

    /**
     * 查询摄像头
     *
     * @param cameraCode 摄像头编码
     * @return 摄像头
     */
    @Override
    public CentermonitorTCamera selectCentermonitorTCameraByCameraCode(String cameraCode) {
        /*图片前缀**/
        List<String> imgList = new ArrayList<>();
        R<String> url = remoteService.selectConfigKey_fileUrl();
        CentermonitorTCamera camera = centermonitorTCameraMapper.selectCentermonitorTCameraByCameraCode(cameraCode);
        camera.setList(centermonitorTCameraMapper.SelectByIdcreameType(camera.getId()));
        ArrayList<CentermonitorTCameraImg> cameraImg = centermonitorTCameraMapper.selectCentermonitorTCameraImgByCameraCode(cameraCode);
        for (CentermonitorTCameraImg img : cameraImg) {
            String imgPath = img.getCameraImg();
            if (imgPath != null && !imgPath.isEmpty()) {
                img.setCameraImg(url.getData() + imgPath);
                imgList.add(url.getData() + imgPath);
            }
        }
        camera.setCameraImagesList(imgList);
        return camera;
    }

    /**
     * 查询摄像头
     *
     * @param channelCode 通道编码
     * @return 摄像头
     */
    @Override
    public CentermonitorTCamera selectCentermonitorTCameraByChannelCode(String channelCode) {
        return centermonitorTCameraMapper.selectCentermonitorTCameraByChannelCode(channelCode);
    }

    /**
     * 查询摄像头
     *
     * @param id 摄像头主键
     * @return 摄像头
     */
    @Override
    public CentermonitorTCamera selectCentermonitorTCameraById(String id) {
        /*图片前缀**/
        List<String> imgList = new ArrayList<>();
        R<String> url = remoteService.selectConfigKey_fileUrl();
        CentermonitorTCamera camera = centermonitorTCameraMapper.selectCentermonitorTCameraById(id);
        camera.setList(centermonitorTCameraMapper.SelectByIdcreameType(id));
        ArrayList<CentermonitorTCameraImg> cameraImg = centermonitorTCameraMapper.selectCentermonitorTCameraImgByCameraId(id);
        for (CentermonitorTCameraImg img : cameraImg) {
            String imgPath = img.getCameraImg();
            if (imgPath != null && !imgPath.isEmpty()) {
                img.setCameraImg(url.getData() + imgPath);
                imgList.add(url.getData() + imgPath);
            }
        }
        camera.setCameraImagesList(imgList);
        return camera;
    }

    /**
     * 获取摄像头详细信息(多个)
     *
     * @param ids 摄像头主键
     * @return 摄像头
     */
    @Override
    public List<CentermonitorTCamera> selectIdTCameraById(String[] ids) {
        return centermonitorTCameraMapper.selectIdTCameraById(ids);
    }

    /**
     * 通过摄像头账号获取摄像头详细信息
     */
    @Override
    public CentermonitorTCamera selectCentermonitorTCameraByCameraAccount(String cameraAccount) {
        return centermonitorTCameraMapper.selectCentermonitorTCameraByCameraAccount(cameraAccount);
    }

    /**
     * 查询摄像头列表
     *
     * @param centermonitorTCamera 摄像头
     * @return 摄像头
     */
    @Override
    public List<CentermonitorTCamera> selectCentermonitorTCameraList(CentermonitorTCamera centermonitorTCamera) {
        return centermonitorTCameraMapper.selectCentermonitorTCameraList(centermonitorTCamera);
    }

    /**
     * 根据部门ID和工作状态查询摄像头列表
     *
     * @param centermonitorTCamera 摄像头
     * @return 摄像头集合
     */
    @Override
    public List<CentermonitorTCamera> selectCameraListByDeptIdAndWorkingStatus(CentermonitorTCamera centermonitorTCamera) {
        return centermonitorTCameraMapper.selectCameraListByDeptIdAndWorkingStatus(centermonitorTCamera);
    }

    /**
     * 查询状态日志
     *
     * @param centermonitorTCameraStateLog 查询状态日志
     * @return 查询状态日志
     */
    @Override
    public List<CentermonitorTCameraStateLog> selectCentermonitorTCameraListStateLog(CentermonitorTCameraStateLog centermonitorTCameraStateLog) {
        return centermonitorTCameraMapper.selectCentermonitorTCameraListStateLog(centermonitorTCameraStateLog);
    }

    /**
     * 查询摄像头列表
     *
     * @param centermonitorTCamera 摄像头
     * @return 摄像头集合
     */
    @Override
    @DataScopeMutiDept(deptAlias = "d")
    public List<CentermonitorTCamera> selectCentermonitorTCameraListForApp(CentermonitorTCamera centermonitorTCamera) {
        Integer size = centermonitorTCamera.getPageSize();
        Integer start = (centermonitorTCamera.getPageNum() - 1) * size;
        centermonitorTCamera.setPageNum(start);
        return centermonitorTCameraMapper.selectCentermonitorTCameraListForApp(centermonitorTCamera);
    }

    /**
     * 新增摄像头
     *
     * @param centermonitorTCamera 摄像头
     * @return 结果
     */
    @Override
    public int insertCentermonitorTCamera(CentermonitorTCamera centermonitorTCamera) {
        String camera = IdUtils.simpleUUID();
        centermonitorTCamera.setId(camera);
        centermonitorTCamera.setCreateBy(SecurityUtils.getLoginUser().getSysUser().getUserId().toString());
        centermonitorTCamera.setCreateTime(DateUtils.getNowDate());
        for (int i = 0; i < centermonitorTCamera.getList().size(); i++) {
            CentermonitorTCameraType type = new CentermonitorTCameraType();
            type.setId(IdUtils.simpleUUID());
            type.setCameraId(camera);
            type.setType(centermonitorTCamera.getList().get(i).getType());
            type.setTypeName(centermonitorTCamera.getList().get(i).getTypeName());
            centermonitorTCameraMapper.insertCentermonitorTCameraType(type);
        }
        List<CentermonitorTCameraImg> images = new ArrayList<>();
        for (String file : centermonitorTCamera.getCameraImages()) {
            CentermonitorTCameraImg image = new CentermonitorTCameraImg();
            image.setCameraImg(file.substring(file.indexOf("group1")));
            image.setCameraId(centermonitorTCamera.getId());
            image.setCameraCode(centermonitorTCamera.getCameraCode());
            images.add(image);
        }
        if (!images.isEmpty()) {
            centermonitorTCameraMapper.insertCentermonitorTCameraImg(images);
        }
        return centermonitorTCameraMapper.insertCentermonitorTCamera(centermonitorTCamera);
    }

    /**
     * 校验摄像头IP唯一
     *
     * @param centermonitorTCamera 摄像头
     * @return 结果
     */
    @Override
    public String checkIpUnique(CentermonitorTCamera centermonitorTCamera) {
        String Id = StringUtils.isNull(centermonitorTCamera.getId()) ? String.valueOf(-1L) : centermonitorTCamera.getId();
        CentermonitorTCamera info = centermonitorTCameraMapper.checkIpUnique(centermonitorTCamera.getCameraIp());
        if (StringUtils.isNotNull(info) && !info.getId().equals(Id)) {
            return UserConstants.NOT_UNIQUE;
        }
        return UserConstants.UNIQUE;
    }
    /**
     * 校验摄像头编码唯一
     *
     * @param centermonitorTCamera 摄像头
     * @return 结果
     */
    @Override
    public String checkCodeUnique(CentermonitorTCamera centermonitorTCamera) {
        String Id = StringUtils.isNull(centermonitorTCamera.getId()) ? String.valueOf(-1L) : centermonitorTCamera.getId();
        CentermonitorTCamera info = centermonitorTCameraMapper.checkCodeUnique(centermonitorTCamera.getCameraCode());
        if (StringUtils.isNotNull(info) && !info.getId().equals(Id)) {
            return UserConstants.NOT_UNIQUE;
        }
        return UserConstants.UNIQUE;
    }


    /**
     * 修改摄像头
     *
     * @param centermonitorTCamera 摄像头
     * @return 结果
     */
    @Override
    public int updateCentermonitorTCamera(CentermonitorTCamera centermonitorTCamera) {
        centermonitorTCamera.setUpdateBy(SecurityUtils.getLoginUser().getSysUser().getUserId());
        centermonitorTCamera.setUpdateTime(DateUtils.getNowDate());
        centermonitorTCameraMapper.deleteCentermonitorTCameraTypeById(centermonitorTCamera.getId());
        for (int i = 0; i < centermonitorTCamera.getList().size(); i++) {
            CentermonitorTCameraType type = new CentermonitorTCameraType();
            type.setId(IdUtils.simpleUUID());
            type.setCameraId(centermonitorTCamera.getId());
            type.setType(centermonitorTCamera.getList().get(i).getType());
            type.setTypeName(centermonitorTCamera.getList().get(i).getTypeName());
            centermonitorTCameraMapper.insertCentermonitorTCameraType(type);
        }
        CenterdataTAidevicedept aidevicedept = new CenterdataTAidevicedept();
        aidevicedept.setDeviceId(centermonitorTCamera.getId());
        aidevicedept.setDeviceCode(centermonitorTCamera.getCameraCode());
        aidevicedept.setDeviceName(centermonitorTCamera.getCameraName());
        centermonitorTCameraMapper.updateAidevicedept(aidevicedept);
        List<CentermonitorTCameraImg> imagesList = new ArrayList<>();
        List<String> cameraImagesList = centermonitorTCamera.getCameraImages();
        centermonitorTCameraMapper.deleteImageByCameraId(centermonitorTCamera.getId());
        for (String image : cameraImagesList) {
            if (image != null && image.contains("group")) {
                // 修改中间表记录的 cameraImg 字段
                CentermonitorTCameraImg img = new CentermonitorTCameraImg();
                img.setCameraImg(image.substring(image.indexOf("group1")));
                img.setCameraId(centermonitorTCamera.getId());
                img.setCameraCode(centermonitorTCamera.getCameraCode());
                imagesList.add(img);
            }
        }
        if (!imagesList.isEmpty()) {
            centermonitorTCameraMapper.insertCentermonitorTCameraImg(imagesList);
        }
        return centermonitorTCameraMapper.updateCentermonitorTCamera(centermonitorTCamera);
    }

    /**
     * 批量删除摄像头
     *
     * @param ids 需要删除的摄像头主键
     * @return 结果
     */
    @Override
    public int deleteCentermonitorTCameraByIds(String[] ids) {
        centermonitorTCamerachannelMapper.deleteCentermonitorTCamerachannelByCameraIds(ids);
        centerdataTAideviceeventMapper.deleteCenterdataTAideviceeventByCameraIds(ids);
        centerdataTAidevicedeptMapper.deleteCenterdataTAidevicedeptByCameraIds(ids);
        return centermonitorTCameraMapper.deleteCentermonitorTCameraByIds(ids);
    }

    /**
     * 删除摄像头信息
     *
     * @param id 摄像头主键
     * @return 结果
     */
    @Override
    public int deleteCentermonitorTCameraById(String id) {
        return centermonitorTCameraMapper.deleteCentermonitorTCameraById(id);
    }

    /**
     * 根据设备用途查询摄像头列表
     */
    @Override
    @DataScopeMutiDept(deptAlias = "d")
    public List<CentermonitorTCamera> selectCentermonitorTCameraListByCameraUse(String cameraUse) {
        CentermonitorTCamera camera = new CentermonitorTCamera();
        camera.setCameraUse(cameraUse);
        setSookaDataBase(camera);
        return centermonitorTCameraMapper.selectCentermonitorTCameraListByCameraUse(camera);
    }

    /**
     * 查询附近摄像头列表
     */
    @Override
    @DataScopeMutiDept(deptAlias = "d")
    public List<CentermonitorTCamera> selectFjsxt(String longitude, String latitude, String type) {
        CentermonitorTCamera camera = new CentermonitorTCamera();
        camera.setLongitude(longitude);
        camera.setLatitude(latitude);
        camera.setType(type);
        setSookaDataBase(camera);
        return centermonitorTCameraMapper.selectFjsxt(camera);
    }

    /**
     * 根据部门ID获取摄像头列表
     */
    @Override
    @DataScopeMutiDept(deptAlias = "d")
    public AjaxResult selectCameraByDepId(VisuForestCloudMapVO visuForestMonitorCenterVO) {
        setSookaDataBase(visuForestMonitorCenterVO);
        List<VisuForestCloudCameraBO> list = centermonitorTCameraMapper.selectCameraByDepIdGong(visuForestMonitorCenterVO);
        return AjaxResult.success(list);
    }

    /**
     * 获取覆盖范围摄像头数量
     */
    @Override
    @DataScopeMutiDept(deptAlias = "d")
    public AjaxResult selectCameraByCoverage(VisuForestCloudMapVO visuForestMonitorCenterVO) {
        setSookaDataBase(visuForestMonitorCenterVO);
        List<VisuForestCloudMapVO> list = centermonitorTCameraMapper.selectCameraByCoverage(visuForestMonitorCenterVO);
        return AjaxResult.success(list);
    }

    /**
     * 获取各部门摄像头数量
     */
    @Override
    public AjaxResult selectCameraGroupByDept(VisuForestMonitorCenterVO vo) {
        return AjaxResult.success(centermonitorTCameraMapper.selectCameraGroupByDept(vo));
    }

    /**
     * 获取各部门摄像头,传感器,云广播数量
     */
    @Override
    @DataScopeMutiDept(deptAlias = "d")
    public AjaxResult selectDeviceType(VisuForestCloudMapVO visuForestMonitorCenterVO) {
        setSookaDataBase(visuForestMonitorCenterVO);
        List<VisuForestCloudMapDeviceBO> visuForestCloudMapDeviceBOList = centermonitorTCameraMapper.selectDeviceTypeGong(visuForestMonitorCenterVO);
        return AjaxResult.success(visuForestCloudMapDeviceBOList);
    }

    /**
     * 根据类别获取摄像头数量
     */
    @Override
    @DataScopeMutiDept(deptAlias = "d")
    public List<VisuForestCloudMapDeviceBO> selectDeviceTypeR(VisuForestCloudMapVO visuForestMonitorCenterVO) {
        setSookaDataBase(visuForestMonitorCenterVO);
        return centermonitorTCameraMapper.selectDeviceTypeGong(visuForestMonitorCenterVO);
    }

    /**
     * 可视化前端根据不同入参查询摄像头、传感器、大喇叭、无人机等设备的数量、列表、部门分组数量
     */
    @Override
    @DataScopeMutiDept(deptAlias = "d")
    public AjaxResult selectDeviceTypeGong(VisuForestCloudMapVO visuForestCloudMapVO) {
        setSookaDataBase(visuForestCloudMapVO);
        Map m = new HashMap();
        List<VisuForestCloudMapDeviceBO> visuForestCloudMapDeviceBOList = centermonitorTCameraMapper.selectDeviceTypeGong(visuForestCloudMapVO);
        List<VisuForestCloudTodaySjfbBO> visuForestCloudTodaySjfbBOList = centermonitorTCameraMapper.selectCameraGroupByDeptGong(visuForestCloudMapVO);
        List<VisuForestCloudCameraBO> visuForestCloudCameraBOList = centermonitorTCameraMapper.selectCameraByDepIdGong(visuForestCloudMapVO);
        m.put("visuForestCloudMapDeviceBOList", visuForestCloudMapDeviceBOList);
        m.put("visuForestCloudTodaySjfbBOList", visuForestCloudTodaySjfbBOList);
        m.put("visuForestCloudCameraBOList", visuForestCloudCameraBOList);
        return AjaxResult.success(m);
    }

    /**
     * 电视墙 过期
     * */
    @Override
    @DataScopeMutiDept(deptAlias = "d")
    public AjaxResult selectCameraByDepIdGong(VisuForestCloudMapVO visuForestCloudMapVO) {
        setSookaDataBase(visuForestCloudMapVO);
        List<VisuForestCloudCameraBO> visuForestCloudCameraBOList = centermonitorTCameraMapper.selectCameraByDepIdGong(visuForestCloudMapVO);

        return AjaxResult.success(visuForestCloudCameraBOList);
    }

    /**
     * 根据摄像头事件类别查询海康摄像头列表高清通道
     * */
    @Override
    @DataScopeMutiDept(deptAlias = "c")
    public AjaxResult cameraTVHaiKangList(VisuForestCloudMapVO visuForestCloudMapVO) {
        setSookaDataBase(visuForestCloudMapVO);
        return AjaxResult.success(centermonitorTCameraMapper.cameraTVHaiKangList(visuForestCloudMapVO));
    }

    /**
     * 根据部门查询摄像头列表
     */
    @Override
    @DataScopeMutiDept(deptAlias = "d")
    public AjaxResult selectCameraGroupByDeptGong(VisuForestCloudMapVO visuForestCloudMapVO) {
        setSookaDataBase(visuForestCloudMapVO);
        return AjaxResult.success(centermonitorTCameraMapper.selectCameraGroupByDeptGong(visuForestCloudMapVO));
    }

    @Override
    public boolean isLatLng(String longitude, String latitude) {
        return true;
    }

    /**
     * 获取正常工作摄像头数量
     */
    @Override
    public CameraVO cameraCount() {
        return centermonitorTCameraMapper.cameraCount();
    }

    /**
     * 根据搜索的部门查询摄像头列表（摄像头半径包含当前部门点位的摄像头）
     * @author wang_xy
     * @since 2023/3/27 15:07
     */
    @Override
    public List<CentermonitorTCamera> findCameraByDept(VisuForestCloudMapVO visuForestCloudMapVO) {
        setSookaDataBase(visuForestCloudMapVO);
        return centermonitorTCameraMapper.findCameraByDept(visuForestCloudMapVO);
    }

    /**
     * 根据搜索的经纬度查询摄像头列表（摄像头半径包含当前经纬度点位的摄像头）
     * @author wang_xy
     * @since 2023/3/27 15:07
     */
    @Override
    public List<CentermonitorTCamera> findCameraByEventCoordinate(String longitude, String latitude, String type) {
        return centermonitorTCameraMapper.findCameraByEventCoordinate(longitude, latitude, type);
    }

    /**
     * 根据搜索的经纬度查询摄像头列表
     * @author wang_xy
     * @since 2023/3/27 15:07
     */
    @Override
    public List<CentermonitorTCamera> findNearbyCameras(String longitude, String latitude, String radius) {
        return centermonitorTCameraMapper.findNearbyCameras(longitude, latitude, radius);
    }

    @Override
    public CentermonitorTCamera getCameraByChannelNum(String channelNum) {
        return centermonitorTCameraMapper.getCameraByChannelNum(channelNum);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateCameraWorkingStatus(CentermonitorTCamera centermonitorTCamera, CentermonitorTCameraStateLog stateLog) {
        int res = centermonitorTCameraMapper.updateCameraWorkingStatus(centermonitorTCamera);
        if (res > 0) {
            centermonitorTCameraMapper.insertCentermonitorTCameraStateLog(stateLog);
        }
    }

    /**
     * 新增摄像头离线日志
     * @param cameraStateLog 摄像头离线日志
     * @return 结果
     * */
    @Override
    public int insertCentermonitorTCameraStateLog(CentermonitorTCameraStateLog cameraStateLog) {
        return centermonitorTCameraMapper.insertCentermonitorTCameraStateLog(cameraStateLog);
    }

    /**
     * 查询摄像头离线日志
     * @param cameraId 摄像头ID
     * @return 结果
     * */
    @Override
    public List<CentermonitorTCamera> selectCentermonitorTCameraStateLog(String cameraId) {
        return centermonitorTCameraMapper.selectCentermonitorTCameraStateLog(cameraId);
    }

    /**
     * 监控中心首页-右上角四个数
     **/
    @Override
    public List<CentermonitorTCamera> selectAlldeviceCountAndDetailCount(CentermonitorTCamera centermonitorTCamera) {
        setSookaDataBase(centermonitorTCamera);
        return centermonitorTCameraMapper.selectAlldeviceCountAndDetailCount(centermonitorTCamera);
    }

    /**
     * 监控中心首页-当前设备状态
     **/
    @Override
    public List<CentermonitorTCamera> selectDeviceAndCameraOnlineAndOfflineList(CentermonitorTCamera centermonitorTCamera) {
        setSookaDataBase(centermonitorTCamera);
        return centermonitorTCameraMapper.selectDeviceAndCameraOnlineAndOfflineList(centermonitorTCamera);
    }

    /**
     * 区县离线设备扇形图
     **/
    @Override
    public List<CentermonitorTCamera> selectQxOfflineDeviceCount(CentermonitorTCamera centermonitorTCamera) {
        setSookaDataBase(centermonitorTCamera);
        return centermonitorTCameraMapper.selectQxOfflineDeviceCount(centermonitorTCamera);
    }

    /**
     * 离线设备类型扇形图
     **/
    @Override
    public List<CentermonitorTCamera> selectQxOfflineDeviceTypeCount(CentermonitorTCamera centermonitorTCamera) {
        List<CentermonitorTCamera> devices = centermonitorTCameraMapper.selectQxOfflineDeviceTypeCount(centermonitorTCamera);
        List<CentermonitorTCamera> device1 = new ArrayList<>();
        List<SysDictData> list = DictUtils.getDictCache("camera_offline_reason");
        for (CentermonitorTCamera device : devices) {
            CentermonitorTCamera de = new CentermonitorTCamera();
            for (SysDictData sysDictData : list) {
                if (device.getOffline_reason().equals(sysDictData.getDictValue())) {
                    de.setOffline_reason(sysDictData.getDictLabel());
                } else if (device.getOffline_reason().equals("-1")) {
                    de.setOffline_reason("数据更新中断");
                }
                de.setCount(device.getCount());
            }
            device1.add(de);
        }
        return device1;
    }

    /**
     * 监控中心首页-日离线设备折线图
     **/
    @Override
    public List<IndexLineChartsVo> dayLineChart(String yearAndMonth) {
        return centermonitorTCameraMapper.dayLineChart(yearAndMonth);
    }

    /**
     * 监控中心首页-月离线设备折线图
     **/
    @Override
    public List<IndexLineChartsVo> monthlyLineChart(String year) {
        return centermonitorTCameraMapper.monthlyLineChart(year);
    }

    /**
     * 监控中心首页-季度离线设备折线图
     **/
    @Override
    public List<IndexLineChartsVo> quarterLineChart(String year) {
        return centermonitorTCameraMapper.quarterLineChart(year);
    }

    /**
     * 监控中心首页-年离线设备折线图
     **/
    @Override
    public List<IndexLineChartsVo> yearLineChart(String year) {
        return centermonitorTCameraMapper.yearLineChart(year);
    }

    @Override
    public List<CameraCodeAndNameVO> selectAllCameraList() {
        return centermonitorTCameraMapper.selectAllCameraList();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public R saveCameraCallLog(JSONObject json) {
        Date date = new Date();
        String deviceCode = JSONObject.toJSONString(json.get("deviceCode"));
        List<SysDept> list = SecurityUtils.getLoginUser().getSysUser().getDepts();
        List<CentermonitorTCameraCallLog> saveOneList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(list)) {
            for (SysDept var : list) {
                CentermonitorTCameraCallLog save = new CentermonitorTCameraCallLog();
                save.setId(IdUtils.simpleUUID());
                save.setDeviceCode(deviceCode);
                save.setMapDeptId(var.getDeptId());
                save.setMapDeptName(var.getDeptName());
                save.setCreateBy(SecurityUtils.getLoginUser().getSysUser().getUserId());
                save.setCreateName(SecurityUtils.getLoginUser().getSysUser().getNickName());
                save.setCreateTime(date);
                save.setType("0");
                saveOneList.add(save);
            }
        }
        centermonitorTCameraCallLogMapper.insertInto(saveOneList);

        List<CentermonitorTCameraCallLog> saveTwoList = new ArrayList<>();
        List<CenterdataTAidevicedeptDTO> byDeviceCode = centerdataTAidevicedeptMapper.getByDeviceCode(deviceCode);
        if (!CollectionUtils.isEmpty(byDeviceCode)) {
            for (CenterdataTAidevicedeptDTO var : byDeviceCode) {
                CentermonitorTCameraCallLog save = new CentermonitorTCameraCallLog();
                save.setId(IdUtils.simpleUUID());
                save.setDeviceCode(deviceCode);
                save.setMapDeptId(var.getMapDeptId());
                save.setMapDeptName(var.getMapDeptName());
                save.setCreateBy(SecurityUtils.getLoginUser().getSysUser().getUserId());
                save.setCreateName(SecurityUtils.getLoginUser().getSysUser().getNickName());
                save.setCreateTime(date);
                save.setType("1");
                saveTwoList.add(save);
            }
        }
        centermonitorTCameraCallLogMapper.insertInto(saveTwoList);
        return R.ok();
    }


    /**
     * 接入设备情况-厂商-雷达图
     */
    @Override
    public Map<String, List> getAccessManufacturer(Long deptId) {
        Map<String, List> nameCountList = new HashMap<>();
        List<String> nameList = new ArrayList<>();
        List<String> countList = new ArrayList<>();
        CentermonitorTCamera centermonitorTCamera = new CentermonitorTCamera();
        centermonitorTCamera.setDeptId(deptId == null ? SecurityUtils.getLoginUser().getSysUser().getDeptId().toString() : deptId.toString());
        setSookaDataBase(centermonitorTCamera);
        List<CentermonitorTCamera> manufacturer = centermonitorTCameraMapper.getAccessManufacturer(centermonitorTCamera);
        for (CentermonitorTCamera tar : manufacturer) {
            nameList.add(tar.getName());
            countList.add(tar.getCount());
        }
        nameCountList.put("manufacturerName", nameList);
        nameCountList.put("manufacturerCount", countList);
        return nameCountList;
    }

    /**
     * 设备离线情况-设备型号
     */
    @Override
    public Map<String, List> getDeviceOffline(Long deptId) {
        Map<String, List> OfflineList = new HashMap<>();
        List<String> nameList = new ArrayList<>();
        List<String> countList = new ArrayList<>();
        CentermonitorTCamera centermonitorTCamera = new CentermonitorTCamera();
        centermonitorTCamera.setDeptId(deptId == null ? SecurityUtils.getLoginUser().getSysUser().getDeptId().toString() : deptId.toString());
        setSookaDataBase(centermonitorTCamera);
        List<CentermonitorTCamera> Offline = centermonitorTCameraMapper.getDeviceOffline(centermonitorTCamera);
        for (CentermonitorTCamera tar : Offline) {
            nameList.add(tar.getName());
            countList.add(tar.getCount());
        }
        OfflineList.put("offlineName", nameList);
        OfflineList.put("offlineCount", countList);
        return OfflineList;
    }

    /**
     * 设备离线情况-设备品牌
     */
    public Map<String, List> getDeviceBrand(Long deptId) {
        Map<String, List> brandList = new HashMap<>();
        List<String> nameList = new ArrayList<>();
        List<String> countList = new ArrayList<>();
        CentermonitorTCamera centermonitorTCamera = new CentermonitorTCamera();
        centermonitorTCamera.setDeptId(deptId == null ? SecurityUtils.getLoginUser().getSysUser().getDeptId().toString() : deptId.toString());
        setSookaDataBase(centermonitorTCamera);
        List<CentermonitorTCamera> brand = centermonitorTCameraMapper.getDeviceBrand(centermonitorTCamera);
        for (CentermonitorTCamera tar : brand) {
            nameList.add(tar.getName());
            countList.add(tar.getCount());
        }
        brandList.put("brandName", nameList);
        brandList.put("brandCount", countList);
        return brandList;
    }

    /**
     * 设备离线情况-运营商
     */
    public Map<String, List> getOperator(Long deptId) {
        Map<String, List> operatorList = new HashMap<>();
        List<String> nameList = new ArrayList<>();
        List<String> countList = new ArrayList<>();
        CentermonitorTCamera centermonitorTCamera = new CentermonitorTCamera();
        centermonitorTCamera.setDeptId(deptId == null ? SecurityUtils.getLoginUser().getSysUser().getDeptId().toString() : deptId.toString());
        setSookaDataBase(centermonitorTCamera);
        List<CentermonitorTCamera> operator = centermonitorTCameraMapper.getOperator(centermonitorTCamera);
        for (CentermonitorTCamera tar : operator) {
            nameList.add(tar.getName());
            countList.add(tar.getCount());
        }
        operatorList.put("operatorName", nameList);
        operatorList.put("operatorCount", countList);
        return operatorList;
    }

    /**
     * 设备离线类型 - 离线原因
     */
    @Override
    public Map<String, List> getOfflineType(Long deptId) {
        Map<String, List> offlineTypeList = new HashMap<>();
        List<String> nameList = new ArrayList<>();
        List<String> countList = new ArrayList<>();
        CentermonitorTCamera centermonitorTCamera = new CentermonitorTCamera();
        centermonitorTCamera.setDeptId(deptId == null ? SecurityUtils.getLoginUser().getSysUser().getDeptId().toString() : deptId.toString());
        setSookaDataBase(centermonitorTCamera);
        List<CentermonitorTCamera> manufacturer = centermonitorTCameraMapper.getOfflineType(centermonitorTCamera);
        for (CentermonitorTCamera tar : manufacturer) {
            nameList.add(tar.getName());
            countList.add(tar.getCount());
        }
        offlineTypeList.put("offlineTypeName", nameList);
        offlineTypeList.put("offlineTypeCount", countList);
        return offlineTypeList;
    }

    /**
     * 视频目录统计
     */
    @Override
    public Map<String, List> getVideoDirectory(Long deptId) {
        Map<String, List> offlineTypeList = new HashMap<>();
        List<String> countList = new ArrayList<>();
        CentermonitorTCamera centermonitorTCamera = new CentermonitorTCamera();
        centermonitorTCamera.setDeptId(deptId == null ? SecurityUtils.getLoginUser().getSysUser().getDeptId().toString() : deptId.toString());
        setSookaDataBase(centermonitorTCamera);
        List<CentermonitorTCamera> manufacturer = centermonitorTCameraMapper.getVideoDirectory(centermonitorTCamera);
        for (CentermonitorTCamera tar : manufacturer) {
            countList.add(tar.getTotal());
            countList.add(tar.getAccess());
            countList.add(String.valueOf(tar.getOnline()));
            countList.add(String.valueOf(tar.getOffline()));
        }
        offlineTypeList.put("videoDirectoryCount", countList);
        return offlineTypeList;
    }

    @Override
    public Map<String, List> getCameraCallDepartmentLogOneStatistics(List<SysDept> sysDeptList) {
        Map<String, List> map = new HashMap<>();
        List<String> nameList = new ArrayList<>();
        List<Integer> numberList = new ArrayList<>();
        for (SysDept var : sysDeptList) {
            CentermonitorTCamera centermonitorTCamera = new CentermonitorTCamera();
            centermonitorTCamera.setDeptId(var.getDeptId().toString());
            setSookaDataBase(centermonitorTCamera);
            List<CentermonitorTCameraCallLogStatisticsDTO> list = centermonitorTCameraCallLogMapper.getCameraCallDepartmentLogOneStatistics(centermonitorTCamera);
            for (CentermonitorTCameraCallLogStatisticsDTO tar : list) {
                nameList.add(tar.getName());
                numberList.add(tar.getValue());
            }
        }
        map.put("videoCallNameOneList", nameList);
        map.put("videoCallNumberOneList", numberList);
        return map;
    }

    @Override
    public Map<String, List> getCameraCallDepartmentLogTwoStatistics(List<SysDept> sysDeptList) {
        Map<String, List> map = new HashMap<>();
        List<String> nameList = new ArrayList<>();
        List<Integer> numberList = new ArrayList<>();
        for (SysDept var : sysDeptList) {
            CentermonitorTCamera centermonitorTCamera = new CentermonitorTCamera();
            centermonitorTCamera.setDeptId(var.getDeptId().toString());
            setSookaDataBase(centermonitorTCamera);
            List<CentermonitorTCameraCallLogStatisticsDTO> list = centermonitorTCameraCallLogMapper.getCameraCallDepartmentLogTwoStatistics(centermonitorTCamera);
            for (CentermonitorTCameraCallLogStatisticsDTO tar : list) {
                nameList.add(tar.getName());
                numberList.add(tar.getValue());
            }
        }
        map.put("videoCallNameTwoList", nameList.subList(0,Math.min(nameList.size(),10)));
        map.put("videoCallNumberTwoList", numberList.subList(0,Math.min(numberList.size(),10)));
        return map;
    }

    @Override
    public Map<String, List> getCameraCallLogStatistics(Long deptId) {
        Map<String, List> map = new HashMap<>();
        Date today = new Date();
        List<Integer> todayVideoStatistics = new ArrayList<>();
        List<Integer> totalVideoStatistics = new ArrayList<>();
        CentermonitorTCamera centermonitorTCamera = new CentermonitorTCamera();
        centermonitorTCamera.setCreateTime(today);
        centermonitorTCamera.setDeptId(deptId == null ? SecurityUtils.getLoginUser().getSysUser().getDeptId().toString() : deptId.toString());
        setSookaDataBase(centermonitorTCamera);
        todayVideoStatistics.add(centermonitorTCameraCallLogMapper.getCameraCallLogStatistics(centermonitorTCamera));
        centermonitorTCamera.setCreateTime(null);
        totalVideoStatistics.add(centermonitorTCameraCallLogMapper.getCameraCallLogStatistics(centermonitorTCamera));
        map.put("todayVideoStatistics", todayVideoStatistics);
        map.put("totalVideoStatistics", totalVideoStatistics);
        return map;
    }

    @Override
    public Map<String, List> getEquipmentStatistics(List<SysDept> sysDeptList) {
//        List<SysDept> list = SecurityUtils.getLoginUser().getSysUser().getDepts();
        List<Integer> equipmentNumberList = new ArrayList<>();
        for (SysDept var : sysDeptList) {
            CentermonitorTCamera centermonitorTCamera = new CentermonitorTCamera();
            centermonitorTCamera.setDeptId(var.getDeptId().toString());
            setSookaDataBase(centermonitorTCamera);
            Integer equipmentStatistics = centermonitorTCameraMapper.getEquipmentStatistics(centermonitorTCamera);
            equipmentNumberList.add(equipmentStatistics);
        }
        Map<String, List> map = new HashMap<>();
        map.put("equipmentNameList", sysDeptList.stream().map(SysDept::getDeptName).collect(Collectors.toList()));
        map.put("equipmentNumberList", equipmentNumberList);
        return map;
    }

    @Override
    public List<CentermonitorTCameraVideoStatisticsVO> getVideoCountyStatistics(List<SysDept> sysDeptList) {
        List<CentermonitorTCameraVideoStatisticsVO> videoNumberList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(sysDeptList)) {
            for (SysDept var : sysDeptList) {
                CentermonitorTCamera centermonitorTCamera = new CentermonitorTCamera();
                centermonitorTCamera.setDeptId(var.getDeptId().toString());
                setSookaDataBase(centermonitorTCamera);
                List<CentermonitorTCameraVideoStatisticsDTO> videoStatistics = centermonitorTCameraMapper.getVideoCountyStatistics(centermonitorTCamera);
                CentermonitorTCameraVideoStatisticsVO centermonitorTCameraVedioStatisticsVO = new CentermonitorTCameraVideoStatisticsVO();
                centermonitorTCameraVedioStatisticsVO.setName(var.getDeptName());
                for (CentermonitorTCameraVideoStatisticsDTO tar : videoStatistics) {
                    if (StringUtils.isNotEmpty(tar.getCameraRadius()) && tar.getCameraRadius().equals("1500")) {
                        centermonitorTCameraVedioStatisticsVO.setAddressOne(tar.getNumber());
                    } else if (StringUtils.isNotEmpty(tar.getCameraRadius()) && tar.getCameraRadius().equals("2000")) {
                        centermonitorTCameraVedioStatisticsVO.setAddressTwo(tar.getNumber());
                    } else if (StringUtils.isNotEmpty(tar.getCameraRadius()) && tar.getCameraRadius().equals("2500")) {
                        centermonitorTCameraVedioStatisticsVO.setAddressThree(tar.getNumber());
                    } else if (StringUtils.isNotEmpty(tar.getCameraRadius()) && tar.getCameraRadius().equals("3000")) {
                        centermonitorTCameraVedioStatisticsVO.setAddressFour(tar.getNumber());
                    } else if (StringUtils.isNotEmpty(tar.getCameraRadius()) && tar.getCameraRadius().equals("3500")) {
                        centermonitorTCameraVedioStatisticsVO.setAddressFive(tar.getNumber());
                    } else if (StringUtils.isNotEmpty(tar.getCameraRadius()) && tar.getCameraRadius().equals("4000")) {
                        centermonitorTCameraVedioStatisticsVO.setAddressSix(tar.getNumber());
                    } else if (StringUtils.isNotEmpty(tar.getCameraRadius()) && tar.getCameraRadius().equals("5000")) {
                        centermonitorTCameraVedioStatisticsVO.setAddressSeven(tar.getNumber());
                    } else if (StringUtils.isNotEmpty(tar.getCameraRadius()) && tar.getCameraRadius().equals("6000")) {
                        centermonitorTCameraVedioStatisticsVO.setAddressEight(tar.getNumber());
                    }
                }
                videoNumberList.add(centermonitorTCameraVedioStatisticsVO);
            }
            if (!CollectionUtils.isEmpty(videoNumberList)) {
                for (CentermonitorTCameraVideoStatisticsVO obj : videoNumberList) {
                    Class<?> objClass = obj.getClass();
                    // 获取对象的所有字段（包括私有字段）
                    Field[] fields = objClass.getDeclaredFields();
                    // 遍历字段
                    for (Field field : fields) {
                        field.setAccessible(true); // 设置私有字段可访问
                        try {
                            // 如果字段的值为 null，则将其赋值为 0
                            if (!field.getName().equals("name") && field.get(obj) == null) {
                                field.set(obj, 0);
                            }
                        } catch (IllegalAccessException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
        return videoNumberList;
    }

    // TODO: 2024/1/23 改直连了
    @Override
    public List<GiveAnAlarmResultDTO> selectEventGjnums(List<SysDept> sysDeptList) {
        VisuForestCloudMapVO visuForestCloudMapVO = new VisuForestCloudMapVO();
        List<Long> deptsList = new ArrayList<>();
        for (SysDept var : sysDeptList) {
            deptsList.add(var.getDeptId());
        }
        visuForestCloudMapVO.setDeptIds(deptsList);
        R<Map<String, Integer>> keyValuePairs = remoteEventBaseService.getEventGjnums(visuForestCloudMapVO);
        List<GiveAnAlarmResultDTO> list = new ArrayList<>();
        for (Map.Entry<String, Integer> entry : keyValuePairs.getData().entrySet()) {
            String key = entry.getKey();
            int value = entry.getValue();

            GiveAnAlarmResultDTO giveAnAlarmResultDTO = new GiveAnAlarmResultDTO();
            giveAnAlarmResultDTO.setName(key);
            giveAnAlarmResultDTO.setNumber(value);
            list.add(giveAnAlarmResultDTO);
        }
        return list;
    }


    @Override
    public R getVideoFusionUnifyInlet(Long deptId){
        Map<String, List> map = new HashMap<>();
        List<SysDept> sysDepartments = new ArrayList();

        List<SysDept> list = SecurityUtils.getLoginUser().getSysUser().getDepts();
        if (deptId != null) {
            R<List<SysDept>> sysDeptList = remoteService.selectChildrenCountyOrVillagesDeptListByDeptId(deptId);
            sysDepartments.addAll(sysDeptList.getData());
        } else {
            for (SysDept var : list) {
                R<List<SysDept>> sysDeptList = remoteService.selectChildrenCountyOrVillagesDeptListByDeptId(var.getDeptId());
                sysDepartments.addAll(sysDeptList.getData());
            }
        }

        ExecutorService executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
        Future<Map<String, List>> getEquipmentStatistics = executorService.submit(() -> {
            return this.getEquipmentStatistics(sysDepartments);
        });
//        Future<Map<String, List>> getAccessManufacturer = executorService.submit(() -> {
//            return this.getAccessManufacturer(deptId);
//        });
        Future<List<CentermonitorTCameraVideoStatisticsVO>> getVideoCountyStatistics = executorService.submit(() -> {
            return this.getVideoCountyStatistics(sysDepartments);
        });
//        Future<List<GiveAnAlarmResultDTO>> selectEventGjnums = executorService.submit(() -> {
//            return this.selectEventGjnums(sysDepartments);
//        });
        // 同样的方式继续提交其他任务

        // 等待所有任务完成
        executorService.shutdown();
        try {
            //视频资源分布
            map.put("videoNumberList", getVideoCountyStatistics.get());
            //接入设备情况-部门
            map.put("equipmentNameList", getEquipmentStatistics.get().get("equipmentNameList"));
            map.put("equipmentNumberList", getEquipmentStatistics.get().get("equipmentNumberList"));
            //告警情况统计
//            map.put("giveAnAlarmStatistics", selectEventGjnums.get());

            executorService.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
        } catch (Exception e) {
            // 处理中断异常
        }

        Map<String, List> cameraCallDepartmentLogOneStatisticsMap = this.getCameraCallDepartmentLogOneStatistics(sysDepartments);
        Map<String, List> cameraCallDepartmentLogTwoStatistics = this.getCameraCallDepartmentLogTwoStatistics(sysDepartments);
        Map<String, List> cameraCallLogStatistics = this.getCameraCallLogStatistics(deptId);
        Map<String, List> offlineMap = this.getDeviceOffline(deptId);
        Map<String, List> brandMap = this.getDeviceBrand(deptId);
        Map<String, List> operatorMap = this.getOperator(deptId);
        Map<String, List> accessManufacturerMap = this.getAccessManufacturer(deptId);
        Map<String, List> offlineTypeMap = this.getOfflineType(deptId);
        Map<String, List> videoDirectoryMap = this.getVideoDirectory(deptId);

        //视频调阅部门
        map.put("videoCallNameOneList", cameraCallDepartmentLogOneStatisticsMap.get("videoCallNameOneList"));
        map.put("videoCallNumberOneList", cameraCallDepartmentLogOneStatisticsMap.get("videoCallNumberOneList"));
        //视频被调阅部门
        map.put("videoCallNameTwoList", cameraCallDepartmentLogTwoStatistics.get("videoCallNameTwoList"));
        map.put("videoCallNumberTwoList", cameraCallDepartmentLogTwoStatistics.get("videoCallNumberTwoList"));
        //视频调阅统计
        map.put("todayVideoStatistics", cameraCallLogStatistics.get("todayVideoStatistics"));
        map.put("totalVideoStatistics", cameraCallLogStatistics.get("totalVideoStatistics"));
        //设备离线情况-设备型号
        map.put("offlineName", offlineMap.get("offlineName"));
        map.put("offlineCount", offlineMap.get("offlineCount"));
        //接入设备情况-厂商-雷达图
        map.put("manufacturerName", accessManufacturerMap.get("manufacturerName"));
        map.put("manufacturerCount", accessManufacturerMap.get("manufacturerCount"));
        //设备离线情况-设备品牌
        map.put("brandName", brandMap.get("brandName"));
        map.put("brandCount", brandMap.get("brandCount"));
        //设备离线情况-运营商
        map.put("operatorName", operatorMap.get("operatorName"));
        map.put("operatorCount", operatorMap.get("operatorCount"));
        //设备离线类型
        map.put("offlineTypeName", offlineTypeMap.get("offlineTypeName"));
        map.put("offlineTypeCount", offlineTypeMap.get("offlineTypeCount"));
        //视频目录统计
        map.put("videoDirectoryCount", videoDirectoryMap.get("videoDirectoryCount"));
        return R.ok(map);
    }

    /**
     * 根据部门ID获取执法记录仪列表
     */
    @Override
    @DataScopeMutiDept(deptAlias = "d")
    public AjaxResult selectRecorderByDeptId(VisuForestCloudMapVO visuForestMonitorCenterVO) {
        setSookaDataBase(visuForestMonitorCenterVO);
        List<VisuForestCloudCameraBO> list = centermonitorTCameraMapper.selectRecorderByDeptId(visuForestMonitorCenterVO);
        return AjaxResult.success(list);
    }

    /**
     * 根据部门ID获取执法记录仪在离线状态数量
     */
    @Override
    public RecorderCountVO selectRecorderCountByDeptId(VisuForestCloudMapVO visuForestMonitorCenterVO) {
        return centermonitorTCameraMapper.selectRecorderCountByDeptId(visuForestMonitorCenterVO);
    }

    @Override
    public CentermonitorTCamera selectCameraInfoByChannelCode(String channelCode) {
        return centermonitorTCameraMapper.selectCameraInfoByChannelCode(channelCode);
    }


}


