package com.testor.ddd.safetyControl.application.service.riskStatistics.impl;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.testor.biz.sys.dict.data.model.domain.SysDictData;
import com.testor.biz.sys.dict.data.service.SysDictDataService;
import com.testor.biz.sys.dict.type.model.domain.SysDictType;
import com.testor.biz.sys.dict.type.service.SysDictTypeService;
import com.testor.biz.sys.org.model.domain.SysOrg;
import com.testor.biz.sys.org.service.SysOrgService;
import com.testor.biz.sys.user.model.domain.SysUser;
import com.testor.biz.sys.user.service.SysUserService;
import com.testor.ddd.safetyControl.application.service.equipmentManage.EquipmentManageService;
import com.testor.ddd.safetyControl.application.service.riskLeclsManage.RiskLeclsManageService;
import com.testor.ddd.safetyControl.application.service.riskOwnerManage.RiskOwnerManageService;
import com.testor.ddd.safetyControl.application.service.riskPointManage.RiskPointManageService;
import com.testor.ddd.safetyControl.application.service.riskPointSource.RiskPointSourceManageService;
import com.testor.ddd.safetyControl.application.service.riskSourceManage.RiskSourceManageService;
import com.testor.ddd.safetyControl.application.service.riskStatistics.RiskStatisticsManageService;
import com.testor.ddd.safetyControl.application.service.spaceManage.SpaceManageService;
import com.testor.ddd.safetyControl.domain.riskStatistics.entity.RiskStatisticsRepo;
import com.testor.ddd.safetyControl.infrastructure.uitls.RiskRelationTypeEnum;
import com.testor.ddd.safetyControl.interfaces.model.dto.equipment.TSafeEquipmentDTOParam;
import com.testor.ddd.safetyControl.interfaces.model.dto.lecls.RiskLeclsValDTO;
import com.testor.ddd.safetyControl.interfaces.model.dto.lecls.TSafeRiskRealLevelRelationDTO;
import com.testor.ddd.safetyControl.interfaces.model.dto.riskOwner.TSafeRiskOwnerDTO;
import com.testor.ddd.safetyControl.interfaces.model.dto.riskPoint.TSafeRiskPointDTO;
import com.testor.ddd.safetyControl.interfaces.model.dto.riskPointSource.TSafeRiskPointSourceDTO;
import com.testor.ddd.safetyControl.interfaces.model.dto.riskPointSource.TSafeRiskPointSourceDTOParam;
import com.testor.ddd.safetyControl.interfaces.model.dto.riskSource.TSafeRiskSourceDTO;
import com.testor.ddd.safetyControl.interfaces.model.dto.riskStatistics.RiskStatisticsDTO;
import com.testor.ddd.safetyControl.interfaces.model.vo.equipment.TSafeEquipmentVO;
import com.testor.ddd.safetyControl.interfaces.model.vo.riskPoint.RiskPointSourceListVO;
import com.testor.ddd.safetyControl.interfaces.model.vo.riskPoint.RiskPointSourceVO;
import com.testor.ddd.safetyControl.interfaces.model.vo.riskStatistics.RiskStatisticsNumVO;
import com.testor.ddd.safetyControl.interfaces.model.vo.space.TSafeSpaceVO;
import com.testor.module.duty.util.PoiExcelUtils;
import com.tongtech.tfw.backend.common.biz.constants.BizConstants;
import com.tongtech.tfw.backend.common.biz.models.BaseResponse;
import com.tongtech.tfw.backend.common.biz.models.BaseResponseList;
import com.tongtech.tfw.backend.common.constants.enumeration.BaseStatusEnum;
import com.tongtech.tfw.backend.common.context.ContextUtils;
import com.tongtech.tfw.backend.common.exception.BusinessException;
import com.tongtech.tfw.backend.common.models.sys.UserInfo;
import com.tongtech.tfw.backend.core.helper.IdHelper;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;
import java.util.stream.Collectors;

@Service // ("riskStatisticsManageService")
public class RiskStatisticsManageServiceImpl implements RiskStatisticsManageService {
    Logger logger = LoggerFactory.getLogger(RiskStatisticsManageServiceImpl.class);

    @Resource
    private RiskStatisticsRepo riskStatisticsRepo;

    @Resource
    private RiskSourceManageService riskSourceManageService;

    @Resource
    private RiskPointManageService riskPointManageService;

    @Resource
    private RiskOwnerManageService riskOwnerManageService;

    @Resource
    private SpaceManageService spaceManageService;

    @Resource
    private EquipmentManageService equipmentManageService;

    @Resource
    private SysOrgService orgService;

    @Resource
    private SysUserService userService;

    @Resource
    private SysDictDataService dictDataService;
    @Resource
    private SysDictTypeService dictTypeService;

    @Resource
    private RiskLeclsManageService leclsManageService;

    @Autowired
    private RiskPointSourceManageService riskPointSourceManageService;

    @Override
    public List<RiskStatisticsNumVO> statisticsSourceNum(RiskStatisticsDTO param) {

        return riskStatisticsRepo.statisticsSourceNum(param);
    }

    @Override
    public List<RiskStatisticsNumVO> statisticsSourceNumBySpaceType(RiskStatisticsDTO param) {

        return riskStatisticsRepo.statisticsSourceNumBySpaceType(param);
    }

    @Override
    public List<RiskStatisticsNumVO> statisticsSourceLevel(RiskStatisticsDTO param) {

        return riskStatisticsRepo.statisticsSourceLevel(param);
    }

    @Override
    public List<RiskStatisticsNumVO> statisticsSourceType(RiskStatisticsDTO param) {

        return riskStatisticsRepo.statisticsSourceType(param);
    }

    @Override
    public List<RiskStatisticsNumVO> statisticsPointNum(RiskStatisticsDTO param) {

        return riskStatisticsRepo.statisticsPointNum(param);
    }

    @Override
    public List<RiskStatisticsNumVO> statisticsPointNumBySpaceType(RiskStatisticsDTO param) {

        return riskStatisticsRepo.statisticsPointNumBySpaceType(param);
    }

    @Override
    public List<RiskStatisticsNumVO> statisticsPointLevel(RiskStatisticsDTO param) {

        return riskStatisticsRepo.statisticsPointLevel(param);
    }

    @Override
    public List<RiskStatisticsNumVO> statisticsPointType(RiskStatisticsDTO param) {

        return riskStatisticsRepo.statisticsPointType(param);
    }

    /**
     * 导入危险源
     *
     * @param file
     * @return
     * @throws IOException
     */
    @Override
    @Transactional
    public BaseResponse<String> importRiskSource(MultipartFile file) throws IOException {
        BaseResponse<String> baseResponse = new BaseResponse<>();

        UserInfo curUser = ContextUtils.getLoginUser();
        if (StrUtil.isBlank(curUser.getOrgId())) {
            baseResponse.setCode(BaseStatusEnum.UN_DATA.code());
            baseResponse.setMsg("用户信息错误");
            return baseResponse;
        }
        String curUserOrgId = curUser.getOrgId();
        SysOrg org = orgService.getById(curUserOrgId);
        String curUserOrgCode = org.getOrgCode();

        //判断是否为null
        if (file == null || file.getSize() <= 0) {
            baseResponse.setCode(BaseStatusEnum.UN_DATA.code());
            baseResponse.setMsg("上传文件数据错误");
            return baseResponse;
        }
        InputStream inputStream = null;
        Workbook workbook = null;

        StringBuilder sbMsg = new StringBuilder();

        try {
            inputStream = file.getInputStream();
            // 读取Excel⽂件⼯作表
            workbook = PoiExcelUtils.readFile(inputStream, file.getOriginalFilename());
            //取得第⼀个⼯作表
            Sheet sheet = workbook.getSheetAt(0);
            //报表上传的没条数据
            List<Map<Integer, Object>> dataList = PoiExcelUtils.getBody(sheet, 30, 4);
            if (dataList == null || dataList.size() == 0) {
                baseResponse.setCode(BaseStatusEnum.UN_DATA.code());
                baseResponse.setMsg("请填写模板信息");
                return baseResponse;
            }

            List<TSafeRiskSourceDTO> riskSourceDTOList = new ArrayList<>();
            TSafeRiskSourceDTO riskSourceDTO;
            TSafeRiskOwnerDTO riskOwnerDTO;
            int index = 0;

            // key departmentName  value orgAllPath
            Map<String, SysOrg> orgAllPathMap = new HashMap<>();

            // 根据导入的excel中的编码 获取 对应 设备或空间信息
            Map<String, Map<String, String>> equipOrSpaceMap = new HashMap<>();

            // 危险源分类
            Map<String, String> typeMap = findDictDataMap("risk_source_type");
            if (typeMap == null || typeMap.size() == 0) {
                baseResponse.setCode(BaseStatusEnum.UN_DATA.code());
                baseResponse.setMsg("危险源分类缺少配置信息");
                return baseResponse;
            }

            //危险源导致的后果
          //  Map<String, String> consequenceMap = findDictDataMap("risk_source_consequence");
            Map<String, String> consequenceMap = findDictDataMap("ACCIDENT_TYPE");
            if (consequenceMap == null || consequenceMap.size() == 0) {
                baseResponse.setCode(BaseStatusEnum.UN_DATA.code());
                baseResponse.setMsg("危险源导致的后果缺少配置信息");
                return baseResponse;
            }
            //固有风险等级
            Map<String, String> inherentLevelMap = findDictDataMap("inherent_level");
            if (inherentLevelMap == null || inherentLevelMap.size() == 0) {
                baseResponse.setCode(BaseStatusEnum.UN_DATA.code());
                baseResponse.setMsg("固有风险等级缺少配置信息");
                return baseResponse;
            }
            //现实风险等级
            Map<String, String> realLevelMap = findDictDataMap("real_level");
            if (realLevelMap == null || realLevelMap.size() == 0) {
                baseResponse.setCode(BaseStatusEnum.UN_DATA.code());
                baseResponse.setMsg("现实风险等级缺少配置信息");
                return baseResponse;
            }
            //管控层级
            Map<String, String> controlLevelMap = findDictDataMap("control_level");
            if (controlLevelMap == null || controlLevelMap.size() == 0) {
                baseResponse.setCode(BaseStatusEnum.UN_DATA.code());
                baseResponse.setMsg("管控层级缺少配置信息");
                return baseResponse;
            }
            //危险等级
            Map<String, String> riskLevelMap = findDictDataMap("risk_level");
            if (riskLevelMap == null || riskLevelMap.size() == 0) {
                baseResponse.setCode(BaseStatusEnum.UN_DATA.code());
                baseResponse.setMsg("危险等级缺少配置信息");
                return baseResponse;
            }
            //检查频次
            Map<String, String> checkFrequencyMap = findDictDataMap("check_frequency");
            if (checkFrequencyMap == null || checkFrequencyMap.size() == 0) {
                baseResponse.setCode(BaseStatusEnum.UN_DATA.code());
                baseResponse.setMsg("检查频次缺少配置信息");
                return baseResponse;
            }

            // key: orgId_name   value: riskSourceDTO
            Map<String, TSafeRiskSourceDTO> sourceListMap = new HashMap<>();

            for (Map<Integer, Object> rowData : dataList) {
                index++;
                // 危险源名称、类型编码不为空
                if (rowData.get(3) == null || StrUtil.isBlank(rowData.get(3).toString()) ||
                        rowData.get(4) == null || StrUtil.isBlank(rowData.get(4).toString()) ||
                        rowData.get(5) == null || StrUtil.isBlank(rowData.get(5).toString()) ||
                        rowData.get(6) == null || StrUtil.isBlank(rowData.get(6).toString()) ||
                        rowData.get(7) == null || StrUtil.isBlank(rowData.get(7).toString()) ||
                        rowData.get(8) == null || StrUtil.isBlank(rowData.get(8).toString()) ||
                        rowData.get(10) == null || StrUtil.isBlank(rowData.get(10).toString()) ||
                        rowData.get(16) == null || StrUtil.isBlank(rowData.get(16).toString()) ||
                        rowData.get(19) == null || StrUtil.isBlank(rowData.get(19).toString()) ||
                        rowData.get(20) == null || StrUtil.isBlank(rowData.get(20).toString()) ||
                        rowData.get(21) == null || StrUtil.isBlank(rowData.get(21).toString()) ||
                        rowData.get(22) == null || StrUtil.isBlank(rowData.get(22).toString()) ||
                        rowData.get(24) == null || StrUtil.isBlank(rowData.get(24).toString())) {
                    sbMsg.append("第" + index + "条数据，参数缺失；\n");
                    continue;
                }

                // 判断企业编码与当前用户所属企业编码是否相同
                String orgCode = rowData.get(3).toString();
                //*危险源分类
                String typeName = rowData.get(4).toString();
                //*危险源名称
                String name = rowData.get(5).toString().trim();
                //*可能导致的后果
                String consequenceName = rowData.get(6).toString();
                //*控制依据
                String controlBasis = rowData.get(7).toString();
                //*管控措施
                String controlMeasures = rowData.get(8).toString();
                //改进措施/方案
                String improvementPlan = rowData.get(9) == null ? null : rowData.get(9).toString();// 可为空
                //*固有风险
                String inherentLevelName = rowData.get(10).toString();
                String lecL = rowData.get(11) == null ? null : rowData.get(11).toString();
                String lecE = rowData.get(12) == null ? null : rowData.get(12).toString();
                String lecC = rowData.get(13) == null ? null : rowData.get(13).toString();
                String lsL = rowData.get(14) == null ? null : rowData.get(15).toString();
                String lsS = rowData.get(15) == null ? null : rowData.get(15).toString();
                //*风险监测/检查频次
                String checkFrequencyName = rowData.get(16).toString();
                //管控部门
                String ownerDepartmentName = rowData.get(17) == null ? null : rowData.get(17).toString();
                //责任人
                String ownerUserName = rowData.get(18) == null ? null : rowData.get(18).toString();
                // *AD账号
                String ownerUserAD = rowData.get(19).toString();
                //*责任部门（监督主体）
                String departmentName = rowData.get(20).toString();
                // *管控层级
                String controlLevelName = rowData.get(21).toString();
                //*关联设备/空间（编号）
                String equipmentSpaceCode = rowData.get(22).toString();
                // 进一步管控措施
                String furtherControlMeasures = rowData.get(23) == null ? null : rowData.get(23).toString();
                //是否为重大危险源 (是、 否)
                String isMajor = rowData.get(24).toString();
                // 危险等级
                String riskLevelName = rowData.get(25) == null ? null : rowData.get(25).toString();
                // 工艺、工序
                String processes = rowData.get(26) == null ? null : rowData.get(26).toString();

                if (StrUtil.isBlank(orgCode)) {
                    orgCode = curUserOrgCode;
                }
                if (!curUserOrgCode.equals(orgCode)) {
                    sbMsg.append("第" + index + "条数据，危险源[" + name + "]当前用户无权操作；\n");
                    continue;
                }

                // 根据 departmentName 、 orgId 获取部门 信息
                // 组装 组织结构全路径
                SysOrg departmentObj;
                if (orgAllPathMap.get(departmentName) == null) {
                    LambdaQueryWrapper<SysOrg> deptQueryWrapper = new LambdaQueryWrapper<>();
                    deptQueryWrapper.eq(SysOrg::getStatus, BizConstants.STATUS_ENABLE)
                            .eq(SysOrg::getParentId, curUserOrgId)
                            .eq(SysOrg::getIsDept, "1") // 加入部门条件
                            .eq(SysOrg::getOrgName, departmentName);
                    List<SysOrg> departmentList = orgService.list(deptQueryWrapper);
                    if (departmentList == null || departmentList.size() != 1) {
                        sbMsg.append("第" + index + "条数据，危险源[" + name + "]所属责任部门信息不正确；\n");
                        continue;
                    }
                    departmentObj = departmentList.get(0);
                    orgAllPathMap.put(departmentName, departmentObj);
                } else {
                    departmentObj = orgAllPathMap.get(departmentName);
                }
                String departmentId = departmentObj.getOrgId();
                String orgAllPath = departmentObj.getParentIds() + "," + departmentId;

                // 根据 设备/空间编号 获取对应信息
                Map<String, String> relationInfoMap;
                if (equipOrSpaceMap.get(equipmentSpaceCode) == null) {
                    relationInfoMap = findEquipmentOrSpace(equipmentSpaceCode);
                    equipOrSpaceMap.put(equipmentSpaceCode, relationInfoMap);
                } else {
                    relationInfoMap = equipOrSpaceMap.get(equipmentSpaceCode);
                }
                if (relationInfoMap == null) {
                    sbMsg.append("第" + index + "条数据，危险源[" + name + "]的关联设备/空间（编号）信息错误;\n");
                    continue;
                }
                String relationTypeStr = relationInfoMap.get("relationType");

                boolean checkResult = riskSourceManageService.checkUniqueness(curUserOrgId, null, name);
                if (!checkResult) {
                    sbMsg.append("第" + index + "条数据，风险点[" + name + "]已存在;\n");
                    continue;
                }

                // 初始化
                String sourceMapKey = curUserOrgId + "_" + name;
                if (sourceListMap.get(sourceMapKey) == null) {
                    riskSourceDTO = new TSafeRiskSourceDTO();
                } else {
                    riskSourceDTO = sourceListMap.get(sourceMapKey);
                }

                //riskSourceDTO = new TSafeRiskSourceDTO();
                riskSourceDTO.setOrgId(curUserOrgId);
                riskSourceDTO.setDepartmentId(departmentId);
                riskSourceDTO.setOrgAllPath(orgAllPath);
                if(!StrUtil.isBlank(departmentObj.getParentIds())) {
                    String[] orgArr = departmentObj.getParentIds().split(",");
                    if(orgArr.length == 3) {
                        riskSourceDTO.setRegionOrgId(orgArr[2]);
                    }
                    if(orgArr.length > 3) {
                        riskSourceDTO.setRegionOrgId(orgArr[2]);
                        riskSourceDTO.setBasicOrgId(orgArr[orgArr.length-1]);
                    }
                }

                // 危险源分类
                if (StrUtil.isBlank(typeMap.get(typeName))) {
                    sbMsg.append("第" + index + "条数据，危险源[" + name + "]的危险源分类信息错误;\n");
                    continue;
                }
                riskSourceDTO.setTypeId(typeMap.get(typeName));

                riskSourceDTO.setName(name);

                // 可能导致的后果
                String[] consequenceNameArr = consequenceName.split("，");
                StringBuilder consequenceSb = new StringBuilder();
                for (String consequenceNameStr : consequenceNameArr) {
                    if (StrUtil.isBlank(consequenceMap.get(consequenceNameStr))) {
                        sbMsg.append("第" + index + "条数据，危险源[" + name + "]的可能导致的后果信息错误;\n");
                        break;
                    }
                    consequenceSb.append(consequenceMap.get(consequenceNameStr));
                    consequenceSb.append(",");
                }
                String consequenceStr = consequenceSb.toString();
                if (!StrUtil.isBlank(consequenceStr)) {
                    riskSourceDTO.setConsequenceId(consequenceStr.substring(0, consequenceStr.length() - 1));
                } else {
                    continue;
                }

                riskSourceDTO.setControlBasis(controlBasis);
                riskSourceDTO.setControlMeasures(controlMeasures);
                if (!StrUtil.isBlank(improvementPlan)) {
                    riskSourceDTO.setImprovementPlan(improvementPlan);
                }

                // 固有风险
                if (StrUtil.isBlank(inherentLevelMap.get(inherentLevelName))) {
                    sbMsg.append("第" + index + "条数据，危险源[" + name + "]的固有风险信息错误;\n");
                    continue;
                }
                riskSourceDTO.setInherentLevelId(inherentLevelMap.get(inherentLevelName));

                /**
                 ** todo ？？？疑问： 危险源新增时 管控层级：按功能配置情况，随风险等级自动回显（注意：1、2、3级自动回显，4级需要手动输入
                 ** todo 如果excel中的管控层级 与系统计算配置的冲突了 如何 取值
                 **/
                RiskLeclsValDTO leclsValDTO = new RiskLeclsValDTO();
                if (StrUtil.isBlank(lecL) && StrUtil.isBlank(lsL)) {
                    sbMsg.append("第" + index + "条数据，危险源[" + name + "]的现实风险计算值缺少;\n");
                    continue;
                }
                if (!StrUtil.isBlank(lecL) && !StrUtil.isBlank(lecE) && !StrUtil.isBlank(lecC)) {
                    riskSourceDTO.setLecL(Float.parseFloat(lecL));
                    riskSourceDTO.setLecE(Float.parseFloat(lecE));
                    riskSourceDTO.setLecC(Float.parseFloat(lecC));
                    riskSourceDTO.setIdentificationMethod(1);

                    leclsValDTO.setType(1);
                    leclsValDTO.setValueType(1);
                    leclsValDTO.setLecL(Float.parseFloat(lecL));
                    leclsValDTO.setLecE(Float.parseFloat(lecE));
                    leclsValDTO.setLecC(Float.parseFloat(lecC));

                } else if (!StrUtil.isBlank(lsL) && !StrUtil.isBlank(lsS)) {
                    riskSourceDTO.setLsL(Float.parseFloat(lsL));
                    riskSourceDTO.setLsS(Float.parseFloat(lsS));
                    riskSourceDTO.setIdentificationMethod(2);
                    leclsValDTO.setType(2);
                    leclsValDTO.setValueType(2);
                    leclsValDTO.setLsL(Float.parseFloat(lsL));
                    leclsValDTO.setLsS(Float.parseFloat(lsS));

                } else {
                    sbMsg.append("第" + index + "条数据，危险源[" + name + "]的现实风险计算值缺少;\n");
                    continue;
                }

                try{
                    TSafeRiskRealLevelRelationDTO levelRelationDTO = leclsManageService.findLevelByLecls(leclsValDTO);
                    if(levelRelationDTO == null) {
                        sbMsg.append("第" + index + "条数据，危险源[" + name + "]根据lec/ls计算无对应的数据，请到功能配置模块进行配置;\n");
                        continue;
                    }
//                    riskSourceDTO.setRealLevelId("67582eb54ce24ebdbbeab94898a7ab66");
//                    riskSourceDTO.setControlStatusId("d4e71cbef4aa46cab1857ac380480013");
                    riskSourceDTO.setRealLevelId(levelRelationDTO.getRealLevel());
                    riskSourceDTO.setControlStatusId(levelRelationDTO.getControlStatus());

                }catch(BusinessException e) {
                    sbMsg.append("第" + index + "条数据，危险源[" + name + "]:"+e.getMessage()+";\n");
                    continue;
                }

                // 风险监测/检查频次
                if (StrUtil.isBlank(checkFrequencyMap.get(checkFrequencyName))) {
                    sbMsg.append("第" + index + "条数据，危险源[" + name + "]的检查频次信息错误;\n");
                    continue;
                }
                riskSourceDTO.setCheckFrequencyId(checkFrequencyMap.get(checkFrequencyName));

                // 管控层级
                if (StrUtil.isBlank(controlLevelMap.get(controlLevelName))) {
                    sbMsg.append("第" + index + "条数据，危险源[" + name + "]的管控层级信息错误;\n");
                    continue;
                }
                riskSourceDTO.setControlLevelId(controlLevelMap.get(controlLevelName));

                // 关联 设备 或 空间
                if ("1".equals(relationTypeStr)) { // 设备
                    riskSourceDTO.setRelationType(RiskRelationTypeEnum.equipment.getCode());
                    riskSourceDTO.setRelationEquipmentId(relationInfoMap.get("equipmentId"));
                    riskSourceDTO.setRelationSpaceId(relationInfoMap.get("spaceId"));
                    riskSourceDTO.setRelationSpaceParentId(relationInfoMap.get("spaceParentId"));
                    riskSourceDTO.setRelationEquipmentLevelIds(relationInfoMap.get("equipmentLevelIds"));
                } else if ("2".equals(relationTypeStr)) { // 空间 - 作业区域（3级）
                    riskSourceDTO.setRelationType(RiskRelationTypeEnum.space.getCode());
                    riskSourceDTO.setRelationSpaceId(relationInfoMap.get("spaceId"));
                    riskSourceDTO.setRelationSpaceParentId(relationInfoMap.get("spaceParentId"));
                    riskSourceDTO.setRelationSpaceLevelIds(relationInfoMap.get("spaceLevelIds"));
                } else if ("3".equals(relationTypeStr)) { // 空间 - 生产车间（2级）
                    riskSourceDTO.setRelationType(RiskRelationTypeEnum.space.getCode());
                    riskSourceDTO.setRelationSpaceParentId(relationInfoMap.get("spaceParentId"));
                    riskSourceDTO.setRelationSpaceLevelIds(relationInfoMap.get("spaceLevelIds"));
                }

                //进一步管控措施
                if (!StrUtil.isBlank(furtherControlMeasures)) {
                    riskSourceDTO.setFurtherControlMeasures(furtherControlMeasures);
                }

                //是否为重大危险源
                if ("是".equals(isMajor)) {
                    riskSourceDTO.setIsMajor("1");
                    if (StrUtil.isBlank(riskLevelName)) {
                        sbMsg.append("第" + index + "条数据，危险源[" + name + "] 当为重大危险源时请填写危险等级;\n");
                        continue;
                    }
                }
                if ("否".equals(isMajor)) {
                    riskSourceDTO.setIsMajor("0");
                }

                // 危险等级
                if (!StrUtil.isBlank(riskLevelName)) {
                    if (StrUtil.isBlank(riskLevelMap.get(riskLevelName))) {
                        sbMsg.append("第" + index + "条数据，危险源[" + name + "]的管控层级信息错误;\n");
                        continue;
                    }
                    riskSourceDTO.setRiskLevelId(riskLevelMap.get(riskLevelName));
                }

                if (!StrUtil.isBlank(processes)) {
                    riskSourceDTO.setProcesses(processes);
                }

                riskSourceDTO.setName(name);
                riskSourceDTO.setStatus(BizConstants.STATUS_ENABLE);
                riskSourceDTO.setCreateBy(curUser.getUserId());

                LambdaQueryWrapper<SysUser> userQueryWrapper = new LambdaQueryWrapper<>();
                userQueryWrapper.eq(SysUser::getStatus, BizConstants.STATUS_ENABLE)
                        .eq(SysUser::getLoginName, ownerUserAD);
                List<SysUser> sysUserList = userService.list(userQueryWrapper);
                if (sysUserList == null || sysUserList.size() == 0) {
                    sbMsg.append("第" + index + "条数据，危险源[" + name + "]的管控责任人信息错误;\n");
                    continue;
                }
                SysUser ownerUser = sysUserList.get(0);
                riskOwnerDTO = new TSafeRiskOwnerDTO();
                riskOwnerDTO.setType(1);
                riskOwnerDTO.setUserId(ownerUser.getUserId());
                riskOwnerDTO.setOrgId(ownerUser.getOrgId());
                riskOwnerDTO.setDepartmentId(ownerUser.getDeptId());
                List<TSafeRiskOwnerDTO> ownerDTOList = riskSourceDTO.getRiskOwnerList();
                if (ownerDTOList == null) {
                    ownerDTOList = new ArrayList<>();
                }
                ownerDTOList.add(riskOwnerDTO);
                riskSourceDTO.setRiskOwnerList(ownerDTOList);

                sourceListMap.put(sourceMapKey, riskSourceDTO);
            }

            if (sourceListMap == null || sourceListMap.size() == 0) {
                if (sbMsg == null) {
                    return baseResponse;
                } else {
                    baseResponse.setCode(BaseStatusEnum.UNKNOWN.code());
                    baseResponse.setMsg(sbMsg.toString());
                    return baseResponse;
                }
            }

            for (Map.Entry<String, TSafeRiskSourceDTO> entry : sourceListMap.entrySet()) {

                TSafeRiskSourceDTO sourceDTO = entry.getValue();
                List<TSafeRiskOwnerDTO> ownerDTOList = sourceDTO.getRiskOwnerList();
                sourceDTO = riskSourceManageService.save(sourceDTO);
                if (StrUtil.isBlank(sourceDTO.getId())) {
                    throw new BusinessException("导入失败");
                }
                for (TSafeRiskOwnerDTO owner : ownerDTOList) {
                    owner.setRiskId(sourceDTO.getId());
                    riskOwnerManageService.save(owner);
                }

            }

        } catch (Exception e) {
            logger.error("批量导入危险源异常："+e.getMessage(),e);
            baseResponse.setCode(BaseStatusEnum.UNKNOWN.code());
            baseResponse.setData(e.getMessage());
            return baseResponse;
        } finally {
            if (inputStream != null) {
                inputStream.close();
            }
            if (workbook != null) {
                workbook.close();
            }
        }
        baseResponse.setData(sbMsg == null ? "导入成功" : sbMsg.toString());
        return baseResponse;
    }

    public Map<String, String> findDictDataMap(String dictType) {
        if (StrUtil.isBlank(dictType)) {
            return null;
        }
        Map<String, String> dictDataMap = new HashMap<>();

        QueryWrapper<SysDictType> typeQueryWrapper = new QueryWrapper<>();
        typeQueryWrapper.eq("dict_type", dictType);
        SysDictType dictTypeObj = dictTypeService.getOne(typeQueryWrapper);

        LambdaQueryWrapper<SysDictData> dataQueryWrapper = new LambdaQueryWrapper<>();
        dataQueryWrapper.eq(SysDictData::getDictId, dictTypeObj.getDictId())
                .eq(SysDictData::getStatus, BizConstants.STATUS_ENABLE);
        List<SysDictData> dictDataList = dictDataService.list(dataQueryWrapper);
        if (dictDataList == null || dictDataList.size() == 0) {
            return null;
        }
        for (SysDictData dictData : dictDataList) {
            dictDataMap.put(dictData.getDictValue(), dictData.getDictDataId());
        }
        return dictDataMap;
    }

    /**
     * 导入风险点
     *
     * @param file
     * @return
     * @throws IOException
     */
    @Transactional
    public BaseResponse<String> importRiskPoint(MultipartFile file) throws IOException {
        BaseResponse<String> baseResponse = new BaseResponse<>();

        UserInfo curUser = ContextUtils.getLoginUser();
        if (StrUtil.isBlank(curUser.getOrgId())) {
            baseResponse.setCode(BaseStatusEnum.UN_DATA.code());
            baseResponse.setMsg("用户信息错误");
            return baseResponse;
        }
        String curUserOrgId = curUser.getOrgId();
        SysOrg org = orgService.getById(curUserOrgId);
        String curUserOrgCode = org.getOrgCode();

        //判断是否为null
        if (file == null || file.getSize() <= 0) {
            baseResponse.setCode(BaseStatusEnum.UN_DATA.code());
            baseResponse.setMsg("上传文件数据错误");
            return baseResponse;
        }
        InputStream inputStream = null;
        Workbook workbook = null;

        StringBuilder sbMsg = new StringBuilder();

        try {
            inputStream = file.getInputStream();
            // 读取Excel⽂件⼯作表
            workbook = PoiExcelUtils.readFile(inputStream, file.getOriginalFilename());
            //取得第⼀个⼯作表
            Sheet sheet = workbook.getSheetAt(0);
            //报表上传的没条数据
            List<Map<Integer, Object>> dataList = PoiExcelUtils.getBody(sheet, 13, 3);
            System.out.println(JSON.toJSONString(dataList));
            if (dataList == null || dataList.size() == 0) {
                baseResponse.setCode(BaseStatusEnum.UN_DATA.code());
                baseResponse.setMsg("请填写数据");
                return baseResponse;
            }

            List<TSafeRiskPointDTO> riskPointDTOList = new ArrayList<>();
            TSafeRiskPointDTO riskPointDTO;
            TSafeRiskOwnerDTO riskOwnerDTO;
            int index = 0;

            // key departmentName  value orgAllPath
            Map<String, SysOrg> orgAllPathMap = new HashMap<>();

            // 根据导入的excel中的编码 获取 对应 设备或空间信息
            Map<String, Map<String, String>> equipOrSpaceMap = new HashMap<>();

            // 风险分类
            Map<String, String> typeMap = findDictDataMap("risk_type");
            if (typeMap == null || typeMap.size() == 0) {
                baseResponse.setCode(BaseStatusEnum.UN_DATA.code());
                baseResponse.setMsg("风险点分类缺少配置信息");
                return baseResponse;
            }

            //管控层级
            Map<String, String> controlLevelMap = findDictDataMap("control_level");
            if (controlLevelMap == null || controlLevelMap.size() == 0) {
                baseResponse.setCode(BaseStatusEnum.UN_DATA.code());
                baseResponse.setMsg("管控层级缺少配置信息");
                return baseResponse;
            }

            // key: orgId_name   value: riskPointDTO
            Map<String, TSafeRiskPointDTO> pointListMap = new HashMap<>();

            for (Map<Integer, Object> rowData : dataList) {
                index++;
                // 危险源名称、类型编码不为空
                if (rowData.get(3) == null || StrUtil.isBlank(rowData.get(3).toString()) ||
                        rowData.get(4) == null || StrUtil.isBlank(rowData.get(4).toString()) ||
                        rowData.get(5) == null || StrUtil.isBlank(rowData.get(5).toString()) ||
                        rowData.get(8) == null || StrUtil.isBlank(rowData.get(8).toString()) ||
                        rowData.get(9) == null || StrUtil.isBlank(rowData.get(9).toString()) ||
                        rowData.get(10) == null || StrUtil.isBlank(rowData.get(10).toString()) ||
                        rowData.get(12) == null || StrUtil.isBlank(rowData.get(12).toString())
                ) {
                    sbMsg.append("第" + index + "条数据，参数缺失；\n");
                    continue;
                }

                // 判断企业编码与当前用户所属企业编码是否相同
                String orgCode = rowData.get(3).toString();
                //*风险分类
                String typeName = rowData.get(4).toString();
                //*风险点名称
                String name = rowData.get(5).toString().trim();
                //管控部门
                String ownerDepartmentName = rowData.get(6) == null ? null : rowData.get(6).toString();
                //责任人
                String ownerUserName = rowData.get(7) == null ? null : rowData.get(7).toString();
                // *AD账号
                String ownerUserAD = rowData.get(8).toString();
                //*责任部门（监督主体）
                String departmentName = rowData.get(9).toString();
                // *管控层级
                String controlLevelName = rowData.get(10).toString();
                //*关联设备/空间（名称）
                String equipmentSpaceName = rowData.get(11) == null ? null : rowData.get(11).toString();
                //*关联设备/空间（编号）
                String equipmentSpaceCode = rowData.get(12).toString();

                if (StrUtil.isBlank(orgCode)) {
                    orgCode = curUserOrgCode;
                }
                if (!curUserOrgCode.equals(orgCode)) {
                    sbMsg.append("第" + index + "条数据，风险点[" + name + "]当前用户无权操作；\n");
                    continue;
                }

                // 根据 departmentName 、 orgId 获取部门 信息
                // 组装 组织结构全路径
                SysOrg departmentObj;
                if (orgAllPathMap.get(departmentName) == null) {
                    LambdaQueryWrapper<SysOrg> deptQueryWrapper = new LambdaQueryWrapper<>();
                    deptQueryWrapper.eq(SysOrg::getStatus, BizConstants.STATUS_ENABLE)
                            .eq(SysOrg::getParentId, curUserOrgId)
                            .eq(SysOrg::getIsDept, "1") // 加入部门条件
                            .eq(SysOrg::getOrgName, departmentName);
                    List<SysOrg> departmentList = orgService.list(deptQueryWrapper);
                    if (departmentList == null || departmentList.size() != 1) {
                        sbMsg.append("第" + index + "条数据，风险点[" + name + "]所属责任部门信息不正确；\n");
                        continue;
                    }
                    departmentObj = departmentList.get(0);
                    orgAllPathMap.put(departmentName, departmentObj);
                } else {
                    departmentObj = orgAllPathMap.get(departmentName);
                }
                String departmentId = departmentObj.getOrgId();
                String orgAllPath = departmentObj.getParentIds() + "," + departmentId;

                // 根据 设备/空间编号 获取对应信息
                Map<String, String> relationInfoMap;
                if (equipOrSpaceMap.get(equipmentSpaceCode) == null) {
                    relationInfoMap = findEquipmentOrSpace(equipmentSpaceCode);
                    equipOrSpaceMap.put(equipmentSpaceCode, relationInfoMap);
                } else {
                    relationInfoMap = equipOrSpaceMap.get(equipmentSpaceCode);
                }
                if (relationInfoMap == null) {
                    sbMsg.append("第" + index + "条数据，风险点[" + name + "]的关联设备/空间（编号）信息错误;\n");
                    continue;
                }
                String relationTypeStr = relationInfoMap.get("relationType");

                boolean checkResult = riskPointManageService.checkUniqueness(curUserOrgId, null, name);
                if (!checkResult) {
                    sbMsg.append("第" + index + "条数据，风险点[" + name + "]的库中已存在;\n");
                    continue;
                }

                // 初始化
                String sourceMapKey = curUserOrgId + "_" + name;
                if (pointListMap.get(sourceMapKey) == null) {
                    riskPointDTO = new TSafeRiskPointDTO();
                } else {
                    riskPointDTO = pointListMap.get(sourceMapKey);
                }

                // riskPointDTO = new TSafeRiskPointDTO();
                riskPointDTO.setOrgId(curUserOrgId);
                riskPointDTO.setDepartmentId(departmentId);
                riskPointDTO.setOrgAllPath(orgAllPath);
                if(!StrUtil.isBlank(departmentObj.getParentIds())) {
                    String[] orgArr = departmentObj.getParentIds().split(",");
                    if(orgArr.length == 3) {
                        riskPointDTO.setRegionOrgId(orgArr[2]);
                    }
                    if(orgArr.length > 3) {
                        riskPointDTO.setRegionOrgId(orgArr[2]);
                        riskPointDTO.setBasicOrgId(orgArr[orgArr.length-1]);
                    }
                }

                // 危险源分类
                if (StrUtil.isBlank(typeMap.get(typeName))) {
                    sbMsg.append("第" + index + "条数据，风险点[" + name + "]的危险源分类信息错误;\n");
                    continue;
                }
                riskPointDTO.setTypeId(typeMap.get(typeName));

//                // todo 责任部门 要求 同一组织机构下的责任部门的名称是唯一的
//                LambdaQueryWrapper<SysOrg> departmentQuery = new LambdaQueryWrapper<>();
//                departmentQuery.eq(SysOrg::getStatus, BizConstants.STATUS_ENABLE)
//                        .eq(SysOrg::getParentId, curUserOrgId)
//                        .eq(SysOrg::getOrgName, departmentName);
//                List<SysOrg> sysOrgList = orgService.list(departmentQuery);
//                if (sysOrgList == null || sysOrgList.size() == 0) {
//                    sbMsg.append("第" + index + "条数据，风险点[" + name + "]的责任部门信息错误;\n");
//                    continue;
//                }
//                riskPointDTO.setDepartmentId(sysOrgList.get(0).getOrgId());

                // 管控层级
                if (StrUtil.isBlank(controlLevelMap.get(controlLevelName))) {
                    sbMsg.append("第" + index + "条数据，风险点[" + name + "]的管控层级信息错误;\n");
                    continue;
                }
                riskPointDTO.setControlLevelId(controlLevelMap.get(controlLevelName));

                // 关联 设备 或 空间
                if ("1".equals(relationTypeStr)) { // 设备
                    riskPointDTO.setRelationType(RiskRelationTypeEnum.equipment.getCode());
                    riskPointDTO.setRelationEquipmentId(relationInfoMap.get("equipmentId"));
                    riskPointDTO.setRelationSpaceId(relationInfoMap.get("spaceId"));
                    riskPointDTO.setRelationSpaceParentId(relationInfoMap.get("spaceParentId"));
                    riskPointDTO.setRelationEquipmentLevelIds(relationInfoMap.get("equipmentLevelIds"));
                } else if ("2".equals(relationTypeStr)) { // 空间 - 作业区域（3级）
                    riskPointDTO.setRelationType(RiskRelationTypeEnum.space.getCode());
                    riskPointDTO.setRelationSpaceId(relationInfoMap.get("spaceId"));
                    riskPointDTO.setRelationSpaceParentId(relationInfoMap.get("spaceParentId"));
                    riskPointDTO.setRelationSpaceLevelIds(relationInfoMap.get("spaceLevelIds"));
                } else if ("3".equals(relationTypeStr)) { // 空间 - 生产车间（2级）
                    riskPointDTO.setRelationType(RiskRelationTypeEnum.space.getCode());
                    riskPointDTO.setRelationSpaceParentId(relationInfoMap.get("spaceParentId"));
                    riskPointDTO.setRelationSpaceLevelIds(relationInfoMap.get("spaceLevelIds"));
                }

                String id = IdHelper.getId32bit();
                riskPointDTO.setId(id);
                riskPointDTO.setName(name);
                riskPointDTO.setStatus(BizConstants.STATUS_ENABLE);
                riskPointDTO.setCreateBy(curUser.getUserId());

                // 关联危险源
//                relationInfoMap
                // spaceid = workareaId
                // spaceParentId = workshopId

                TSafeRiskPointSourceDTOParam param = new TSafeRiskPointSourceDTOParam();
                param.setRelationType(Integer.parseInt(relationTypeStr));
                if ("1".equals(relationInfoMap.get("relationType"))) {
                    param.setEquipmentId(relationInfoMap.get("equipmentId"));
                }else {
                    param.setWorkareaId(relationInfoMap.get("spaceid"));
                    param.setWorkshopId(relationInfoMap.get("spaceParentId"));
                }


                RiskPointSourceListVO listVO = riskPointSourceManageService.listAll(param);
                if (listVO!=null && !CollectionUtils.isEmpty(listVO.getOptionalList())&&listVO.getOptionalList().size()>0) {
                    List<RiskPointSourceVO> optionalList = listVO.getOptionalList();
                    List<RiskPointSourceVO> collect ;
                    RiskPointSourceVO riskPointSourceVO ;
                    if (optionalList.size() > 0) {
                        collect = optionalList.stream().sorted(Comparator.comparing(RiskPointSourceVO::getInherentLevelKey).reversed()).collect(Collectors.toList());
                        riskPointSourceVO = collect.get(0);
                        riskPointDTO.setInherentLevelId(riskPointSourceVO.getInherentLevelId());
                        collect = optionalList.stream().sorted(Comparator.comparing(RiskPointSourceVO::getRealLevelKey).reversed()).collect(Collectors.toList());
                        riskPointSourceVO = collect.get(0);
                        riskPointDTO.setRealLevelId(riskPointSourceVO.getRealLevelId());
                    }

                    // 风险点和危险源关联关系
                    List<TSafeRiskPointSourceDTO> pointSourceList = new ArrayList<>();
                    for (RiskPointSourceVO pointSourceVO : optionalList) {
                        TSafeRiskPointSourceDTO tSafeRiskPointSourceDTO = new TSafeRiskPointSourceDTO();
                        tSafeRiskPointSourceDTO.setSourceId(pointSourceVO.getSourceId());
                        pointSourceList.add(tSafeRiskPointSourceDTO);
                    }

                    riskPointSourceManageService.saveBatch(curUserOrgId,riskPointDTO.getId() , pointSourceList);
                }

                if(listVO==null || CollectionUtils.isEmpty(listVO.getOptionalList())|| listVO.getOptionalList().size()==0){
                    sbMsg.append("第" + index + "条数据，风险点[" + name + "]关联空间、设备下无可选危险源;\n");
                    continue;
                }

                LambdaQueryWrapper<SysUser> userQueryWrapper = new LambdaQueryWrapper<>();
                userQueryWrapper.eq(SysUser::getStatus, BizConstants.STATUS_ENABLE)
                        .eq(SysUser::getLoginName, ownerUserAD);
                List<SysUser> sysUserList = userService.list(userQueryWrapper);
                if (sysUserList == null || sysUserList.size() == 0) {
                    sbMsg.append("第" + index + "条数据，风险点[" + name + "]的管控责任人信息错误;\n");
                    continue;
                }
                SysUser ownerUser = sysUserList.get(0);
                riskOwnerDTO = new TSafeRiskOwnerDTO();
                riskOwnerDTO.setType(2);
                riskOwnerDTO.setUserId(ownerUser.getUserId());
                riskOwnerDTO.setOrgId(ownerUser.getOrgId());
                // todo 此处 向管控部门负责人 所属的 部门 赋值
                riskOwnerDTO.setDepartmentId(ownerUser.getDeptId());
                List<TSafeRiskOwnerDTO> ownerDTOList = riskPointDTO.getRiskOwnerList();
                if (ownerDTOList == null) {
                    ownerDTOList = new ArrayList<>();
                }
                ownerDTOList.add(riskOwnerDTO);
                riskPointDTO.setRiskOwnerList(ownerDTOList);

                //  riskPointDTOList.add(riskPointDTO);
                pointListMap.put(sourceMapKey, riskPointDTO);
            }

            if (pointListMap == null || pointListMap.size() == 0) {
                if (sbMsg == null) {
                    return baseResponse;
                } else {
                    baseResponse.setCode(BaseStatusEnum.UNKNOWN.code());
                    baseResponse.setMsg(sbMsg.toString());
                    return baseResponse;
                }
            }

            for (Map.Entry<String, TSafeRiskPointDTO> entry : pointListMap.entrySet()) {
                TSafeRiskPointDTO pointDTO = entry.getValue();
                List<TSafeRiskOwnerDTO> ownerDTOList = pointDTO.getRiskOwnerList();
                pointDTO = riskPointManageService.save(pointDTO);
                if (StrUtil.isBlank(pointDTO.getId())) {
                    throw new BusinessException("导入失败");
                }
                for (TSafeRiskOwnerDTO owner : ownerDTOList) {
                    owner.setRiskId(pointDTO.getId());
                    riskOwnerManageService.save(owner);
                }

            }

        } catch (Exception e) {
            logger.error("导入风控点处理异常：" + e.getMessage(), e);
            baseResponse.setCode(BaseStatusEnum.UNKNOWN.code());
            baseResponse.setData(e.getMessage());
            return baseResponse;
        } finally {
            if (inputStream != null) {
                inputStream.close();
            }
            if (workbook != null) {
                workbook.close();
            }
        }
        baseResponse.setData(sbMsg == null ? "导入成功" : sbMsg.toString());
        return baseResponse;
    }

    /**
     * 根据导入的excel中的编码 获取 对应 设备或空间信息
     *
     * @param code
     * @return
     */
    public Map<String, String> findEquipmentOrSpace(String code) {

        if (StrUtil.isBlank(code)) {
            return null;
        }

        Map<String, String> equipOrSpaceMap = new HashMap<>();

        TSafeEquipmentDTOParam equipmentDTOParam = new TSafeEquipmentDTOParam();
        equipmentDTOParam.setStatus(BizConstants.STATUS_ENABLE);
        equipmentDTOParam.setCode(code);
        BaseResponseList<TSafeEquipmentVO> equipmentList = equipmentManageService.listByPage(equipmentDTOParam);
        if (equipmentList.getData() != null && equipmentList.getData().size() > 0) {
            TSafeEquipmentVO equipmentVO = equipmentList.getData().get(0);
            equipOrSpaceMap.put("relationType", "1");
            equipOrSpaceMap.put("equipmentId", equipmentVO.getId());
            equipOrSpaceMap.put("spaceId", equipmentVO.getSpaceAreaId());
            equipOrSpaceMap.put("spaceParentId", equipmentVO.getSpaceId());
            equipOrSpaceMap.put("equipmentLevelIds", equipmentVO.getSysTypeId()+","+equipmentVO.getEquipmentTypeId()+","+equipmentVO.getId());
            return equipOrSpaceMap;
        }

        List<TSafeSpaceVO> spaceList = spaceManageService.listByCode(code);
        if (spaceList == null || spaceList.size() == 0) {
            return null;
        }

        TSafeSpaceVO spaceVO = spaceList.get(0);
        int level = spaceVO.getLevel();
        if (level == 2) { // 作业区域
            equipOrSpaceMap.put("relationType", "2");
            equipOrSpaceMap.put("spaceId", spaceVO.getId());
            equipOrSpaceMap.put("spaceParentId", spaceVO.getSpaceId());
            equipOrSpaceMap.put("spaceLevelIds", spaceVO.getSpaceTypeId()+","+spaceVO.getSpaceId()+","+spaceVO.getId());

        } else { // 车间场所
            equipOrSpaceMap.put("relationType", "3");
            equipOrSpaceMap.put("spaceParentId", spaceVO.getId());
            equipOrSpaceMap.put("spaceLevelIds", spaceVO.getSpaceTypeId()+","+spaceVO.getId());
        }
        return equipOrSpaceMap;
    }
}
