package com.yeejoin.amos.fas.business.service.impl;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.yeejoin.amos.fas.business.bo.BindPointBo;
import com.yeejoin.amos.fas.business.bo.CheckErrorBo;
import com.yeejoin.amos.fas.business.bo.RiskPointRpnChangeBo;
import com.yeejoin.amos.fas.business.bo.SafetyExecuteBo;
import com.yeejoin.amos.fas.business.constants.FasConstant;
import com.yeejoin.amos.fas.business.dao.mapper.PatrolMapper;
import com.yeejoin.amos.fas.business.dao.mapper.RiskSourceMapper;
import com.yeejoin.amos.fas.business.dao.mapper.View3dMapper;
import com.yeejoin.amos.fas.business.dao.repository.IEquipmentDao;
import com.yeejoin.amos.fas.business.dao.repository.IRiskLevelDao;
import com.yeejoin.amos.fas.business.dao.repository.IRiskSourceDao;
import com.yeejoin.amos.fas.business.dao.repository.ISafetyIndexChangeLogDao;
import com.yeejoin.amos.fas.business.feign.IDutyModeServer;
import com.yeejoin.amos.fas.business.feign.RemoteSecurityService;
import com.yeejoin.amos.fas.business.service.intfc.IDataRefreshService;
import com.yeejoin.amos.fas.business.service.intfc.IView3dService;
import com.yeejoin.amos.fas.business.vo.*;
import com.yeejoin.amos.fas.common.enums.*;
import com.yeejoin.amos.fas.core.common.request.CommonPageable;
import com.yeejoin.amos.fas.core.common.request.DateUtil;
import com.yeejoin.amos.fas.core.common.response.CoordDTO;
import com.yeejoin.amos.fas.core.common.response.Node3DVoResponse;
import com.yeejoin.amos.fas.core.common.response.RegionTreeResponse;
import com.yeejoin.amos.fas.core.util.CommonResponse;
import com.yeejoin.amos.fas.core.util.CommonResponseUtil;
import com.yeejoin.amos.fas.core.util.StringUtil;
import com.yeejoin.amos.fas.dao.entity.Equipment;
import com.yeejoin.amos.fas.dao.entity.RiskLevel;
import com.yeejoin.amos.fas.dao.entity.RiskSource;
import com.yeejoin.amos.fas.dao.entity.SafetyIndexChangeLog;
import com.yeejoin.amos.fas.exception.YeeException;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

//import com.yeejoin.amos.fas.business.dao.repository.IWaterResourceDao;
//import com.yeejoin.amos.fas.dao.entity.FireStation;
//import com.yeejoin.amos.fas.dao.entity.WaterResource;

/**
 * @author DELL
 */
@Service("view3dService")
public class View3dServiceImpl implements IView3dService {

    Logger log = LoggerFactory.getLogger(View3dServiceImpl.class);

    @Autowired
    private View3dMapper view3dMapper;
    @Autowired
    private IRiskSourceDao iRiskSourceDao;


    @Autowired
    private IEquipmentDao iEquipmentDao;
    //    @Autowired
//    private IWaterResourceDao iWaterResourceDao;
    @Autowired
    private PatrolMapper patrolMapper;
    @Autowired
    private IRiskLevelDao iRiskLevelDao;
    @Autowired
    private ISafetyIndexChangeLogDao iSafetyIndexChangeLogDao;

    @Autowired
    private IDutyModeServer dutyModeServer;

    @Value("${param.system.online.date}")
    private String onLineDate;

    @Autowired
    private IDataRefreshService iDataRefreshService;
    @Autowired
    private RiskSourceMapper riskSourceMapper;
    @Autowired
    private RemoteSecurityService remoteSecurityService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public CommonResponse setPoint3dPosition(List<BindPointBo> pointBoList) {
        if (CollectionUtils.isEmpty(pointBoList)) {
            return CommonResponseUtil.failure("点不能为空");
        }
        pointBoList.forEach(pointBo -> {
            this.savePointPositionByType(pointBo.getPointType(), pointBo);
        });
        return CommonResponseUtil.success();
    }

    public void savePointPositionByType(String pointType, BindPointBo pointBo) {
        switch (pointType) {
            case "riskSource":
                this.updateRiskSourcePosition(pointBo);
                break;
            case "patrol":
                this.updatePatrolPosition(pointBo);
                break;
            case "impEquipment":
                this.updateEquipmentPosition(pointBo);
                break;
            case "monitorEquipment":
            case "video":
            case "fireEquipment":
                this.updateFireEquipmentPosition(pointBo);
                break;
            case "fireCar":
                this.updateFireCarPosition(pointBo);
            case "fireChamber":
            case "fireFoamRoom":
//                this.updateFireStationPosition(pointBo);
//                break;
            case "hydrant":
//            case "pool":
//                this.updateWaterSourcePosition(pointBo);
                break;
            default:
                log.error("不支持的类型-->" + pointType);
                break;
        }
    }

    public void updateFireCarPosition(BindPointBo pointBo) {
//       Optional<FireCar> data = iFireCarDao.findById(pointBo.getPointId());
//       if(data.isPresent()){
//           FireCar fireCar = data.get();
//           String ue4Location = pointBo.getUe4Location();
//           String ue4Rotation = pointBo.getUe4Rotation();
//           String position3d = pointBo.getPosition3d();
//           if(ue4Location != null) fireCar.setUe4Location(ue4Location);
//           if(ue4Rotation != null) fireCar.setUe4Rotation(ue4Rotation);
//           if(position3d != null) fireCar.setPosition3d(position3d);
//           iFireCarDao.save(fireCar);
//       }
    }

//    public void updateWaterSourcePosition(BindPointBo pointBo) {
//        Optional<WaterResource> data = iWaterResourceDao.findById(pointBo.getPointId());
//        if(data.isPresent()){
//            WaterResource waterResource = data.get();
//            String ue4Location = pointBo.getUe4Location();
//            String ue4Rotation = pointBo.getUe4Rotation();
//            String position3d = pointBo.getPosition3d();
//            if(ue4Location != null) waterResource.setUe4Location(ue4Location);
//            if(ue4Rotation != null) waterResource.setUe4Rotation(ue4Rotation);
//            if(position3d != null) waterResource.setPosition3d(position3d);
//            iWaterResourceDao.save(waterResource);
//        }
//    }

//    public void updateFireStationPosition(BindPointBo pointBo) {
//        Optional<FireStation> data = iFireStationDao.findById(pointBo.getPointId());
//        if(data.isPresent()){
//            FireStation fireStation = data.get();
//            String ue4Location = pointBo.getUe4Location();
//            String ue4Rotation = pointBo.getUe4Rotation();
//            String position3d = pointBo.getPosition3d();
//            if(ue4Location != null) fireStation.setUe4Location(ue4Location);
//            if(ue4Rotation != null) fireStation.setUe4Rotation(ue4Rotation);
//            if(position3d != null) fireStation.setPosition3d(position3d);
//            iFireStationDao.save(fireStation);
//        }
//    }

    public void updateFireEquipmentPosition(BindPointBo pointBo) {
//       Optional<FireEquipment> data = iFireEquipmentDao.findById(pointBo.getPointId());
//       if(data.isPresent()){
//           FireEquipment fireEquipment = data.get();
//           String ue4Location = pointBo.getUe4Location();
//           String ue4Rotation = pointBo.getUe4Rotation();
//           String position3d = pointBo.getPosition3d();
//           if(ue4Location != null) fireEquipment.setUe4Location(ue4Location);
//           if(ue4Rotation != null) fireEquipment.setUe4Rotation(ue4Rotation);
//           if(position3d != null) fireEquipment.setPosition3d(position3d);
//           iFireEquipmentDao.save(fireEquipment);
//       }
    }

    public void updateEquipmentPosition(BindPointBo pointBo) {
        Optional<Equipment> data = iEquipmentDao.findById(pointBo.getPointId());
        Equipment equipment = null;
        if (data.isPresent()) {
            equipment = data.get();
            String ue4Location = pointBo.getUe4Location();
            String ue4Rotation = pointBo.getUe4Rotation();
            String position3d = pointBo.getPosition3d();
            if (ue4Location != null) equipment.setUe4Location(ue4Location);
            if (ue4Rotation != null) equipment.setUe4Rotation(ue4Rotation);
            if (position3d != null) equipment.setPosition3d(position3d);
            iEquipmentDao.save(equipment);
        }
    }

    public void updatePatrolPosition(BindPointBo pointBo) {
        patrolMapper.updatePoint3dPosition(pointBo);
    }

    public void updateRiskSourcePosition(BindPointBo pointBo) {
        Optional<RiskSource> data = iRiskSourceDao.findById(pointBo.getPointId());
        if (data.isPresent()) {
            RiskSource riskSource = data.get();
            String ue4Location = pointBo.getUe4Location();
            String ue4Rotation = pointBo.getUe4Rotation();
            String position3d = pointBo.getPosition3d();
            if (ue4Location != null) riskSource.setUe4Location(ue4Location);
            if (ue4Rotation != null) riskSource.setUe4Rotation(pointBo.getUe4Rotation());
            if (position3d != null) riskSource.setPosition3d(position3d);
            iRiskSourceDao.save(riskSource);
        }
    }

    @Override
    public List<Map<String, String>> getPointType() {
        return ResourceTypeDefEnum.getTypeList();
    }

    @Override
    public List<RegionTreeResponse> getPointTreeByType(String type, String orgCode, String channelType) {
        //查询点
        List<RegionTreeResponse> regionList = riskSourceMapper.getRegionList(channelType, orgCode);
        //查询区域
        List<RegionTreeResponse> pointByType = view3dMapper.getPointByType(type, orgCode, channelType);
        pointByType.addAll(regionList);
        return convertPointTree(pointByType);
    }

    //区域列表转树
    private static List<RegionTreeResponse> convertPointTree(List<RegionTreeResponse> list) {
        HashMap<Long, RegionTreeResponse> hashMap = new HashMap<>();
        list.forEach(e -> hashMap.put(e.getId(), e));
        List<RegionTreeResponse> treeList = new ArrayList<RegionTreeResponse>();
        list.forEach(r -> {
            Long parentId = r.getParentId();
            if (parentId != null) {
                RegionTreeResponse pRegion = hashMap.get(parentId);
                if (pRegion != null) {
                    pRegion.getChildren().add(r);
                } else {
                    treeList.add(r);
                }
            }
        });
        return treeList;
    }

    @Override
    public HashMap<String, Object> getPointDetailByTypeAndId(String type, Long pointId) {
        HashMap<String, Object> detail = view3dMapper.getPointDetailByTypeAndId(type, pointId);
        if (detail != null) {
            String ue4Location = (String) detail.get("ue4Location");
            detail.put("ue4Location", ue4Location == null ? new JSONArray() : JSON.parseArray(ue4Location));
            String ue4Rotation = (String) detail.get("ue4Rotation");
            detail.put("ue4Rotation", ue4Rotation == null ? new JSONArray() : JSON.parseArray(ue4Rotation));
            String ue4Extent = (String) detail.get("ue4Extent");
            detail.put("ue4Extent", ue4Location == null ? new JSONArray() : JSON.parseArray(ue4Extent));
            detail.put("position3d", this.strPositionToArry(detail.get("position3d")));
        }
        return detail;
    }

    @Override
    public TodaySafetyIndexVo getSafetyIndexInfoByDate(String orgCode, String date) {
        if (!StringUtil.isNotEmpty(date)) {
            date = DateUtil.getDateFormat(new Date(), DateUtil.DATE_DEFAULT_FORMAT);
        }
        Optional<RiskSource> optional = iRiskSourceDao.findByOrgCodeAndParentId(orgCode, 0L);
        TodaySafetyIndexVo vo = new TodaySafetyIndexVo();
        if (optional.isPresent()) {               //1.按照等级进行转换rpn为分数-机构
            RiskSource riskSource = optional.get();
            double safetyIndex = this.changeRpnToSafetyIndex(riskSource.getRpn());
            vo.setSafetyIndex(safetyIndex);
            //2.统计风险上升异常数量（风险点）-日期+机构
            Long upperNum = this.getRiskUpperNum(orgCode, date);
            vo.setRiskExceptionNum(upperNum);
            //3.统计巡检异常数量（不合格、漏检）-日期+机构
            Long checkExceptionNum = this.getCheckExceptionNum(orgCode, date);
            vo.setCheckExceptionNum(checkExceptionNum);
            //4.统计故障数量-日期+机构
            vo.setFireExceptionNum(getFireExceptionNum(orgCode, date));
            //5.安全值提示
            if (riskSource.getRiskLevelId() != null) {
                Optional<RiskLevel> opt = iRiskLevelDao.findById(riskSource.getRiskLevelId());
                if (opt.isPresent()) {
                    Integer level = opt.get().getLevel();
                    String tips = RiskSourceLevelEum.getTipsByLevel(String.valueOf(level));
                    vo.setSafetyTips(tips);
                    vo.setLevel(level);
                }
            }
        } else {
            throw new YeeException("机构：" + orgCode + " 不存在");
        }
        return vo;
    }


    @Override
    public List<SafetyIndexDetailVo> getSafetyIndexDetail(String type, String orgCode) {
        List<SafetyIndexDetailVo> resultList = Lists.newArrayList();
        String dateStr = DateUtil.getDateFormat(new Date(), DateUtil.DATE_DEFAULT_FORMAT);
        Map<String, Object> params = new HashMap<>();
        params.put("orgCode", orgCode);
        params.put("date", dateStr);
        if (StatisticsErrorTypeEum.risk.getCode().equals(type)) {
            //1.按照日期+机构，查询出所有风险点
            List<RiskPointRpnChangeBo> risks = view3dMapper.getAllErrorRiskPoint(params);
            //2.按照 风险等级id进行分组，加工数据
            Map<Long, List<RiskPointRpnChangeBo>> map = risks.stream().collect(Collectors.groupingBy(RiskPointRpnChangeBo::getRiskLevelId));
            List<RiskLevel> riskLevelList = iRiskLevelDao.findAll();
            Map<Long, RiskLevel> riskLevelMap = riskLevelList.stream().collect(Collectors.toMap(RiskLevel::getId, Function.identity()));
            map.forEach((k, v) -> {
                SafetyIndexDetailVo safetyIndexDetailVo = new SafetyIndexDetailVo();
                safetyIndexDetailVo.setTypeCode(String.valueOf(riskLevelMap.get(k).getLevel()));
                safetyIndexDetailVo.setTypeName(riskLevelMap.get(k).getName());
                safetyIndexDetailVo.setContent(getErrorContentVos(v));
                resultList.add(safetyIndexDetailVo);
            });
        } else if (StatisticsErrorTypeEum.check.getCode().equals(type)) {
            //1.按照日期+机构，查询出异常巡检
            List<CheckErrorBo> checkErrorBoList = view3dMapper.getAllErrorPatrolPoint(params);
            //2.按照状态进行分组，加工返回数据
            Map<String, List<CheckErrorBo>> map = checkErrorBoList.stream().collect(Collectors.groupingBy(CheckErrorBo::getStatus));
            map.forEach((k, v) -> {
                SafetyIndexDetailVo safetyIndexDetailVo = new SafetyIndexDetailVo();
                safetyIndexDetailVo.setTypeCode(k);
                safetyIndexDetailVo.setTypeName(CheckStatusEnum.getEnum(k).getName());
                safetyIndexDetailVo.setContent(getErrorContentVos(v));
                resultList.add(safetyIndexDetailVo);
            });
        } else if (StatisticsErrorTypeEum.equip.getCode().equals(type)) {
            //TODO：待毛颖确认调整完成后继续
            List<CheckErrorBo> checkErrorBoList = view3dMapper.getAllFaultAlarm(params);
            Map<String, List<CheckErrorBo>> map = checkErrorBoList.stream().collect(Collectors.groupingBy(CheckErrorBo::getStatus));
            map.forEach((k, v) -> {
                SafetyIndexDetailVo safetyIndexDetailVo = new SafetyIndexDetailVo();
                safetyIndexDetailVo.setTypeCode(k);
                safetyIndexDetailVo.setTypeName(k);
                safetyIndexDetailVo.setContent(getErrorContentVos(v));
                resultList.add(safetyIndexDetailVo);
            });
        }
        return resultList;
    }

    private List<ErrorContentVo> getErrorContentVos(List<?> v) {
        List<ErrorContentVo> errorContentVoList = new ArrayList<>();
        errorContentVoList = v.stream().map(e -> {
            ErrorContentVo errorContentVo = new ErrorContentVo();
            BeanUtils.copyProperties(e, errorContentVo);
            return errorContentVo;
        }).collect(Collectors.toList());
        return errorContentVoList;
    }

    private Long getCheckExceptionNum(String orgCode, String date) {
        Map<String, Object> params = new HashMap<>();
        params.put("orgCode", orgCode);
        params.put("date", date);
        return view3dMapper.countCheckException(params);
    }

    private Long getRiskUpperNum(String orgCode, String date) {
        Map<String, Object> param = new HashMap<>();
        param.put("type", RpnChangeTypeEum.upper.getValue());
        param.put("orgCode", orgCode);
        param.put("date", date);
        return view3dMapper.countUpperRiskPoint(param);
    }

    private Long getFireExceptionNum(String orgCode, String date) {
        Map<String, Object> params = new HashMap<>();
        params.put("orgCode", orgCode);
        params.put("date", date);
        return view3dMapper.countFireException(params);
    }

    private double changeRpnToSafetyIndex(BigDecimal rpn) {
        BigDecimal rpnBig = rpn == null ? new BigDecimal("0") : rpn;
        //计算规则：除10 减100 求绝对值,结果保留1位小数
        return rpnBig.divide(new BigDecimal("10")).subtract(new BigDecimal("100")).abs().setScale(1, BigDecimal.ROUND_HALF_UP).doubleValue();
    }

    @Override
    public List<HashMap<String, Object>> getSafetyIndexWeek(String orgCode) {
        return view3dMapper.getSafetyIndexWeek(orgCode);
    }

    @Override
    public Map<String, Object> getSystemOnlineDate(String orgCode) {
        Date beginDate = DateUtil.formatDate(onLineDate, DateUtil.DATE_DEFAULT_FORMAT);
        Date now = DateUtil.getNow();
        return DateUtil.dayComparePrecise(beginDate, now);
    }

    @Override
    public List<ExceptionRegionVo> getExceptionRegion(String orgCode) {
        Optional<RiskSource> optional = iRiskSourceDao.findByOrgCodeAndParentId(orgCode, 0L);
        List<ExceptionRegionVo> exceptionList = new ArrayList<>();
        if (optional.isPresent()) {
            List<RiskSource> regionList = iRiskSourceDao.findByParentIdAndIsRegion(optional.get().getId(), RiskSourceRegionEum.TRUE.getCode());
            exceptionList = regionList.stream().filter(riskSource -> {
                BigDecimal rpn = riskSource.getRpn() == null ? new BigDecimal("0") : riskSource.getRpn();
                BigDecimal rpni = riskSource.getRpni() == null ? new BigDecimal("0") : riskSource.getRpni();
                return rpn.subtract(rpni).doubleValue() > 0;
            }).map(riskSource -> {
                ExceptionRegionVo regionVo = new ExceptionRegionVo();
                regionVo.setId(riskSource.getId());
                regionVo.setUe4Location(getInitJSONArray(riskSource.getUe4Location()));
                regionVo.setUe4Rotation(getInitJSONArray(riskSource.getUe4Rotation()));
                regionVo.setUe4Extent(getInitJSONArray(riskSource.getUe4Extent()));
                regionVo.setSafetyIndex(changeRpnToSafetyIndex(riskSource.getRpn()));
                regionVo.setBreakdown(isBreakDown(riskSource.getId()));//待后期去掉，前端图标显示统一不在细分
                regionVo.setRoutePath(this.changeStringToJson(riskSource.getRoutePath()));
                return regionVo;
            }).collect(Collectors.toList());
        }
        return exceptionList;
    }

    private JSONArray getInitJSONArray(String str) {
        if (StringUtil.isNotEmpty(str)) {
            return JSON.parseArray(str);
        } else {
            return new JSONArray();
        }
    }

    private JSONObject changeStringToJson(String str) {
        if (StringUtil.isNotEmpty(str)) {
            return JSON.parseObject(str);
        } else {
            return new JSONObject();
        }
    }

    private Boolean isBreakDown(Long id) {
        return true;
    }

    @Override
    public List<Map<String, Object>> getStatisticsCheck(String orgCode) {
        List<HashMap<String, Object>> statisticsCheck = view3dMapper.getStatisticsCheck(orgCode);
        List<Map<String, Object>> stateList = PlanTaskDetailStatusEnum.getEnumList();
        stateList.forEach(s -> {
            if (statisticsCheck != null) {
                Long value = 0L;
                for (HashMap<String, Object> sc : statisticsCheck) {
                    String typeString = sc.get("type").toString();
                    String enumType = s.get("type").toString();
                    if (typeString.equals(enumType)) {
                        value = (Long) sc.get("value");
                        break;
                    }
                }
                s.put("value", value);
            }
        });
        return stateList;
    }

    @Override
    public List<SafetyExecuteBo> getSafetyExecuteListTop5(String type, String orgCode) {
        StatisticsErrorTypeEum.risk.getCode();
        switch (type) {
            case "risk"://风险异常
                return view3dMapper.getRiskErrorTop5(orgCode);
            case "check"://巡检异常
                return view3dMapper.getCheckErrorTop5(orgCode);
            case "fire"://火灾告警
                return view3dMapper.getFireAlarmTop5(orgCode);
            default:
                throw new YeeException("不支持的类型 -->" + type);
        }
    }

    @Override
    public CommonResponse getStatisticsDuty(String appKey, String product, String token, String orgCode) {
        Date curDate = new Date();
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        JSONObject param = new JSONObject();
        param.put("dutyDate", curDate);
        return dutyModeServer.dutyListByDay(appKey, product, token, orgCode, param.toJSONString());
    }

    @Override
    public List<SafetyExecuteBo> getEquipStatusList(String orgCode) {
        return view3dMapper.getEquipStatusTop5(orgCode);
    }

    @Override
    public List<View3dNodeVo> initViewErrorNode(String type, Long riskSourceId, String orgCode) {
        return view3dMapper.initViewErrorNode(type, riskSourceId, orgCode);
    }

    @Override
    public CommonResponse get3dPointsByModel(String orgCode, String model) {
        if (model.equals("grain")) {
            List<HashMap<String, Object>> points = new ArrayList<>();
            return CommonResponseUtil.success(this.getPointsByType(orgCode, FasConstant.ALL_POINT));
        } else if (model.equals("impEquipment")) {
            return CommonResponseUtil.success(view3dMapper.getImpEqu3dPoints(orgCode));
        }
        log.error("模式暂不支持 --> " + model);
        return CommonResponseUtil.failure("模式暂不支持 --> " + model);
    }

    private List<HashMap<String, Object>> getPointsByType(String orgCode, String type) {
        //1.查询数据
        List<HashMap<String, Object>> points = new ArrayList<>();
        Map<String, Object> params = new HashMap<>();
        params.put("orgCode", orgCode);
        params.put("type", FasConstant.ALL_POINT.equalsIgnoreCase(type) ? null : type);
        points = view3dMapper.getPintsByType(params);
        //2.坐标相关字段转json
        points.forEach(point -> {
            JSONArray ue4Location = this.getInitJSONArray(String.valueOf(point.get("ue4Location")));
            JSONArray ue4Rotation = this.getInitJSONArray(String.valueOf(point.get("ue4Rotation")));
            String[] relationKeys = point.get("relationKeys") != null ? String.valueOf(point.get("relationKeys")).split(",") : null;
            point.put("ue4Location", ue4Location);
            point.put("ue4Rotation", ue4Rotation);
            point.put("relationKeys", relationKeys);
        });
        return points;
    }

    @Override
    public void safetyIndexLogGenJob(String runData) {
        Date collectDate = StringUtil.isNotEmpty(runData) ? DateUtil.formatDate(runData, DateUtil.DATE_DEFAULT_FORMAT) : DateUtil.getDayBefore(new Date());
        //1.安全指数流水生成
        try {
            List<RiskSource> riskSources = iRiskSourceDao.findByParentId(0L);
            List<SafetyIndexChangeLog> safetyIndexChangeLogs = new ArrayList<>();
            safetyIndexChangeLogs = riskSources.stream().map(riskSource -> {
                SafetyIndexChangeLog safetyIndexChangeLog = new SafetyIndexChangeLog();
                safetyIndexChangeLog.setOrgCode(riskSource.getOrgCode());
                double changeRpnToSafetyIndex = this.changeRpnToSafetyIndex(riskSource.getRpn());
                safetyIndexChangeLog.setSafetyIndex(BigDecimal.valueOf(changeRpnToSafetyIndex));
                safetyIndexChangeLog.setCollectDate(collectDate);
                return safetyIndexChangeLog;
            }).collect(Collectors.toList());
            ;
            iSafetyIndexChangeLogDao.saveAll(safetyIndexChangeLogs);
        } catch (Exception e) {
            log.error("安全指数流水生成失败： " + e.getMessage());
        }
        //2.通知日切进行数据刷新
        iDataRefreshService.refreshViewData(DataRefreshTypeEum.dateChange.getCode());
    }

    @Override
    public List<Node3DVoResponse> find3dViewDataByType(String type, Long riskSourceId, String orgCode, Boolean abnormalStatus) {
        return view3dMapper.findViewDataByType(type, riskSourceId, orgCode, abnormalStatus);
    }

    @Override
    public CommonResponse retrieveAll(String type, String riskSourceId, String inputText, int current, int pageSize, String orgCode, String dataLevel, String protectObjName, String token, String appKey, String product) {
        CommonPageable pageable = new CommonPageable(current, pageSize);
        Long riskSource = StringUtils.isEmpty(riskSourceId) ? null : Long.parseLong(riskSourceId);
        Long count = view3dMapper.retrieveAllCount(type, riskSource, inputText, orgCode, dataLevel, protectObjName);
        List<HashMap<String, Object>> retrieveAll = view3dMapper.retrieveAll(type, riskSource, inputText, pageable.getOffset(), pageable.getPageSize(), orgCode, dataLevel, protectObjName);
        Set<Object> userIds = new HashSet<>();
        retrieveAll.forEach(action -> {
            if (!ObjectUtils.isEmpty(action.get("person"))) {
                userIds.add(action.get("person").toString());
            }
        });
        Map<String, String> userMap = remoteSecurityService.getUserRealName(token, product, appKey, userIds);
        retrieveAll.stream().forEach(e -> {
            String positionDTO = (String) e.get("positionDTO");
            JSONArray ue4Location = this.getInitJSONArray(String.valueOf(e.get("ue4Location")));
            JSONArray ue4Rotation = this.getInitJSONArray(String.valueOf(e.get("ue4Rotation")));
            if (!ObjectUtils.isEmpty(e.get("person"))) {
                e.put("person", userMap.get(e.get("person").toString()));
            }
            CoordDTO position = null;
            if (positionDTO != null && !positionDTO.equals("")) {
                position = JSONObject.parseObject(positionDTO, CoordDTO.class);
            }
            e.put("position", position);
            e.put("ue4Location", ue4Location);
            e.put("ue4Rotation", ue4Rotation);
            e.put("showInfo", true);
        });
        Page result = new PageImpl(retrieveAll, pageable, count);
        return CommonResponseUtil.success(result);
    }

    @Override
    public CommonResponse retrieve3All(String type, String riskSourceId, Long areaId, Long equipmentId, String inputText, int current, int pageSize, String orgCode, String dataLevel, String token, String appKey, String product) {
        CommonPageable pageable = new CommonPageable(current, pageSize);
        Long riskSource = StringUtils.isEmpty(riskSourceId) ? null : Long.parseLong(riskSourceId);
        Long count = view3dMapper.retrieve3AllCount(type, riskSource, areaId, equipmentId, inputText, orgCode, dataLevel);
        List<HashMap<String, Object>> retrieveAll = view3dMapper.retrieve3All(type, riskSource, areaId, equipmentId, inputText, pageable.getOffset(), pageable.getPageSize(), orgCode, dataLevel);
        Set<Object> userIds = new HashSet<>();
        retrieveAll.forEach(action -> {
            if (!ObjectUtils.isEmpty(action.get("person"))) {
                userIds.add(action.get("person").toString());
            }
        });
        Map<String, String> userMap = remoteSecurityService.getUserRealName(token, product, appKey, userIds);
        retrieveAll.stream().forEach(e -> {
            String positionDTO = (String) e.get("positionDTO");
            if (!ObjectUtils.isEmpty(e.get("person"))) {
                e.put("person", userMap.get(e.get("person").toString()));
            }
            e.put("showInfo", true);
        });
        Page result = new PageImpl(retrieveAll, pageable, count);
        return CommonResponseUtil.success(result);
    }

    @Override
    public List<Map<String, String>> pointLevelList(String type) {
        switch (type) {
            case "riskSource":
                return RiskSourceLevelEum.getLevelEnumList();
            case "patrol":
                return PlanTaskDetailStatusEnum.getErrorLevelEnumList();
            default:
                throw new YeeException("不支持的类型 -->" + type);
        }
    }

    @Override
    public List<Map<String, Object>> listPointsByRegionId(Long regionId, String type) {
        List<Map<String, Object>> pointList = new ArrayList<>();
        if (FasConstant.ALL_POINT.equalsIgnoreCase(type)) {//分支1：查询区域及子区域下所有点
            List<Long> regionIds = new ArrayList<>();
            List<RiskSource> riskSourceList = iRiskSourceDao.findByParentId(regionId);
            this.getAllRiskRegion(regionIds, riskSourceList);
            regionIds.add(regionId);
            pointList = this.getPointsByRegionIds(regionIds);
        } else {//分支2：查询指定区域下所有点
            pointList = this.getPointsByRegionIds(Collections.singletonList(regionId));
        }
        return pointList;
    }


    private List<Map<String, Object>> getPointsByRegionIds(List<Long> ids) {
        return view3dMapper.getAllPointInRegions(ids);
    }

    /**
     * 获得子节点：区域
     *
     * @param ids            返回
     * @param riskSourceList 风险点区域列表
     */
    private void getAllRiskRegion(List<Long> ids, List<RiskSource> riskSourceList) {
        //TODO 递归
        for (RiskSource riskSource : riskSourceList) {
            if (riskSource.getIsRegion().equalsIgnoreCase("TRUE")) {
                ids.add(riskSource.getId());
                List<RiskSource> list = iRiskSourceDao.findByParentId(riskSource.getId());
                if (list != null) {
                    this.getAllRiskRegion(ids, list);
                }
            }
        }
    }

    private JSONArray strPositionToArry(Object position3d) {
        JSONArray jsonArray = new JSONArray();
        if (StringUtil.isNotEmpty(position3d)) {
            String[] arryStr = position3d.toString().split(",");
            List<Double> collect = Arrays.stream(arryStr).map(Double::parseDouble).collect(Collectors.toList());
            jsonArray.addAll(collect);
        }
        return jsonArray;
    }
}

