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

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.EasyExcelFactory;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.fill.FillConfig;
import com.alibaba.fastjson.JSON;
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.service.SysDictTypeService;
import com.testor.biz.sys.org.model.domain.SysOrg;
import com.testor.biz.sys.org.service.SysOrgService;
import com.testor.common.core.utils.StringUtils;
import com.testor.ddd.safetyControl.application.service.equipmentManage.EquipmentManageService;
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.riskSourceManage.RiskSourceManageService;
import com.testor.ddd.safetyControl.application.service.spaceManage.SpaceManageService;
import com.testor.ddd.safetyControl.domain.riskSource.entity.TSafeRiskSourceRepo;
import com.testor.ddd.safetyControl.domain.riskSource.service.RiskSourceService;
import com.testor.ddd.safetyControl.enums.RiskSourceIsMajorEnum;
import com.testor.ddd.safetyControl.infrastructure.uitls.SpaceLevelEnum;
import com.testor.ddd.safetyControl.interfaces.model.dto.riskOwner.TSafeRiskOwnerDTO;
import com.testor.ddd.safetyControl.interfaces.model.dto.riskOwner.TSafeRiskOwnerDTOParam;
import com.testor.ddd.safetyControl.interfaces.model.dto.riskPoint.TSafeRiskPointDTO;
import com.testor.ddd.safetyControl.interfaces.model.dto.riskSource.TSafeRiskSourceDTO;
import com.testor.ddd.safetyControl.interfaces.model.dto.riskSource.TSafeRiskSourceDTOParam;
import com.testor.ddd.safetyControl.interfaces.model.dto.space.TSafeSpaceDTOParam;
import com.testor.ddd.safetyControl.interfaces.model.vo.riskOwner.TSafeRiskOwnerExportVO;
import com.testor.ddd.safetyControl.interfaces.model.vo.riskOwner.TSafeRiskOwnerVO;
import com.testor.ddd.safetyControl.interfaces.model.vo.riskSource.RiskSourceReportVO;
import com.testor.ddd.safetyControl.interfaces.model.vo.riskSource.TSafeRiskSourceExportVO;
import com.testor.ddd.safetyControl.interfaces.model.vo.riskSource.TSafeRiskSourceVO;
import com.testor.ddd.safetyControl.interfaces.model.vo.space.TSafeSpaceVO;
import com.testor.module.duty.util.CustomMergeStrategy;
import com.testor.module.duty.util.ExcelWidthStyleStrategy;
import com.testor.module.sys.model.domian.NewSysOrg;
import com.testor.module.sys.model.vo.SysOrgVo;
import com.testor.module.sys.service.NewSysOrgService;
import com.testor.module.video.util.Beans;
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.models.sys.UserInfo;
import org.slf4j.Logger;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.*;
import java.util.stream.Collectors;

@Service("riskSourceManageService")
public class RiskSourceManageServiceImpl implements RiskSourceManageService {

    Logger logger = org.slf4j.LoggerFactory.getLogger(RiskSourceManageServiceImpl.class);
    @Resource
    private SysOrgService orgService;

    @Resource
    private NewSysOrgService newSysOrgService;

    @Resource
    private RiskSourceService riskSourceService;

    @Resource
    private TSafeRiskSourceRepo tSafeRiskSourceRepo;
    
    @Resource
    private RiskOwnerManageService riskOwnerManageService;

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

    @Resource
    private SpaceManageService spaceManageService;

    @Resource
    private EquipmentManageService equipmentManageService;

    @Resource
    private RiskPointManageService riskPointManageService;



    /**
     * 编辑空间
     *
     * @param riskSourceDto
     * @return
     */
    @Transactional
    public BaseResponse<TSafeRiskSourceDTO> editRiskSource(TSafeRiskSourceDTO riskSourceDto) throws RuntimeException {
        BaseResponse<TSafeRiskSourceDTO> baseResponse = new BaseResponse<>();

        UserInfo curUser = ContextUtils.getLoginUser();
        System.out.println("************curUser:"+curUser.getOrgId());
        if (StrUtil.isBlank(curUser.getOrgId())) {
            baseResponse.setCode(BaseStatusEnum.UN_DATA.code());
            baseResponse.setMsg("用户信息错误");
            return baseResponse;
        }
        String curUserOrgId = curUser.getOrgId();
        riskSourceDto.setOrgId(curUserOrgId);

        // 检验管控状态： 若为 该危险源请转隐患清单 turnHazardList ，则创建失败 提示 “该危险源请转隐患清单”
        String controlStatusId = riskSourceDto.getControlStatusId();
        SysDictData controlStatusData = dictDataService.getById(controlStatusId);
        if(controlStatusData != null) {
            if("turnHazardList".equals(controlStatusData.getDictKey())) {
                baseResponse.setCode(BaseStatusEnum.UN_DATA.code());
                baseResponse.setMsg("该危险源请转隐患清单");
                return baseResponse;
            }
        }

        // 处理区域公司 、 基层单位
        String orgStrs = orgAllPath(curUserOrgId);
        if(!StrUtil.isBlank(orgStrs)) {
            String[] orgArr = orgStrs.split(",");
            if(orgArr.length == 3) {
                riskSourceDto.setRegionOrgId(orgArr[2]);
            }
            if(orgArr.length > 3) {
                riskSourceDto.setRegionOrgId(orgArr[2]);
                riskSourceDto.setBasicOrgId(orgArr[orgArr.length-1]);
            }
        }

        // 组装 组装机构全路径
        String departmentId = riskSourceDto.getDepartmentId();
        //String orgAllPath = orgAllPath(departmentId);
        String orgAllPath = orgStrs + ","+departmentId;
        riskSourceDto.setOrgAllPath(orgAllPath);



        List<TSafeRiskOwnerDTO> riskOwnerDTOList = riskSourceDto.getRiskOwnerList();
        baseResponse = riskSourceService.editRiskSource(curUser.getUserId(), curUserOrgId, riskSourceDto);
        if (baseResponse.getCode() != 200) {
            return baseResponse;
        }

        riskOwnerManageService.editRiskOwner(1, baseResponse.getData().getId(), riskOwnerDTOList);
        return baseResponse;
    }

    public BaseResponseList<TSafeRiskSourceVO> listByPage(TSafeRiskSourceDTOParam param) {

        if (StrUtil.isBlank(param.getOrgId())) {
            UserInfo curUser = ContextUtils.getLoginUser();
            String curUserOrgId = curUser.getOrgId();
            param.setOrgId(curUserOrgId);
        }

        BaseResponseList<TSafeRiskSourceVO> responseList = riskSourceService.listByPage(param);
        List<TSafeRiskSourceVO> riskSourceVOList = responseList.getData();
        if (riskSourceVOList == null || riskSourceVOList.size() == 0) {
            return responseList;
        }
        
        List<TSafeRiskSourceVO> finalRiskSourceVOList = riskSourceVOList.stream().map(vo -> {
            SysOrgVo sysOrgVo = newSysOrgService.lookOrg(vo.getOrgId());
            vo.setOrgName(sysOrgVo.getPath());
            generateDictData(vo);
            generateRiskPoint(vo);
            return generateSpace(vo);

        }).collect(Collectors.toList());
        responseList.setData(finalRiskSourceVOList);
        return responseList;
    }

    public TSafeRiskSourceDTO findById(String id) {
        return tSafeRiskSourceRepo.findById(id);
    }

    public TSafeRiskSourceVO findDetailById(String id) {
        TSafeRiskSourceVO riskSourceVO = tSafeRiskSourceRepo.findDetailById(id);
        if (riskSourceVO == null) {
            return null;
        }
        riskSourceVO = generateDictData(riskSourceVO);
        riskSourceVO = generateRiskOwner(riskSourceVO);
        riskSourceVO = generateSpace(riskSourceVO);
        riskSourceVO = generateRiskPoint(riskSourceVO);
        return riskSourceVO;
    }

    @Transactional
    public BaseResponse deleteById(String id) throws RuntimeException {
        BaseResponse 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();
        TSafeRiskSourceDTO oldRiskSourceDto = tSafeRiskSourceRepo.findById(id);
        if (!curUserOrgId.equals(oldRiskSourceDto.getOrgId())) {
            baseResponse.setCode(BaseStatusEnum.UNAUTHORIZED.code());
            baseResponse.setMsg("无权限操作");
            return baseResponse;
        }

        tSafeRiskSourceRepo.deleteById(id);
        riskOwnerManageService.deleteByRiskBizId(id);
        return baseResponse;
    }

    // 组装 实体中的 数据字典
    public TSafeRiskSourceVO generateDictData(TSafeRiskSourceVO riskSourceVO) {
        if (StrUtil.isBlank(riskSourceVO.getId())) {
            return null;
        }

        // 可能后果
        String consequenceIdArr [] = riskSourceVO.getConsequenceId().split(",");
        StringBuilder consequenceStr = new StringBuilder();
        for(String consequenceIdStr : consequenceIdArr) {
            SysDictData consequence = dictDataService.getById(consequenceIdStr);
            if (consequence != null) {
                consequenceStr.append(consequence.getDictValue());
                consequenceStr.append(",");
            }
        }
        String consequence = consequenceStr.toString();
        if(!StrUtil.isBlank(consequence)) {
            riskSourceVO.setConsequenceName(consequence.substring(0, consequence.length()-1));
        }

        // 危险类型
        SysDictData riskType = dictDataService.getById(riskSourceVO.getTypeId());
        if (riskType != null) {
            riskSourceVO.setTypeName(riskType.getDictValue());
        }
        // 危险等级
        if (!StrUtil.isBlank(riskSourceVO.getRiskLevelId())) {
            SysDictData riskLevel = dictDataService.getById(riskSourceVO.getRiskLevelId());
            if (riskLevel != null) {
                riskSourceVO.setRiskLevelName(riskLevel.getDictValue());
            }
        }
        // 固有风险
        SysDictData inherentLevel = dictDataService.getById(riskSourceVO.getInherentLevelId());
        if (inherentLevel != null) {
            riskSourceVO.setInherentLevelName(inherentLevel.getDictValue());
            riskSourceVO.setInherentLevelKey(inherentLevel.getDictKey());
        }
        //现实风险
        SysDictData realType = dictDataService.getById(riskSourceVO.getRealLevelId());
        if (realType != null) {
            riskSourceVO.setRealLevelName(realType.getDictValue());
            riskSourceVO.setRealLevelKey(realType.getDictKey());
        }

        // 管控层级
        SysDictData controlLevel = dictDataService.getById(riskSourceVO.getControlLevelId());
        if (controlLevel != null) {
            riskSourceVO.setControlLevelName(controlLevel.getDictValue());
        }

        // 管控状态
        SysDictData controlStatus = dictDataService.getById(riskSourceVO.getControlStatusId());
        if (controlStatus != null) {
            riskSourceVO.setControlStatusName(controlStatus.getDictValue());
            riskSourceVO.setControlLevelKey(controlStatus.getDictKey());
        }

        // 检查频次
        SysDictData checkFrequency = dictDataService.getById(riskSourceVO.getCheckFrequencyId());
        if (checkFrequency != null) {
            riskSourceVO.setCheckFrequencyName(checkFrequency.getDictValue());
        }

        return riskSourceVO;
    }

    // 组装 实体中的 风险部门负责人
    public TSafeRiskSourceVO generateRiskOwner(TSafeRiskSourceVO riskSourceVO) {
        if (StrUtil.isBlank(riskSourceVO.getId())) {
            return null;
        }

        // 危险类型
        TSafeRiskOwnerDTOParam param = new TSafeRiskOwnerDTOParam();
        param.setStatus(BizConstants.STATUS_ENABLE);
        param.setRiskId(riskSourceVO.getId());
        List<TSafeRiskOwnerVO> riskOwnerVOList = riskOwnerManageService.listAll(param);
        riskSourceVO.setRiskOwnerList(riskOwnerVOList);
        return riskSourceVO;
    }

    // 组装 实体中的 空间
    public TSafeRiskSourceVO generateSpace(TSafeRiskSourceVO riskSourceVO) {
        if (StrUtil.isBlank(riskSourceVO.getId())) {
            return null;
        }

        int spaceLevel = 0;
        // 危险类型
        TSafeSpaceDTOParam param = new TSafeSpaceDTOParam();
       // param.setStatus(BizConstants.STATUS_ENABLE);
        if(!StrUtil.isBlank(riskSourceVO.getRelationSpaceId())) {
            spaceLevel = SpaceLevelEnum.workarea.getCode();
            param.setId(riskSourceVO.getRelationSpaceId());

        } else if(!StrUtil.isBlank(riskSourceVO.getRelationSpaceParentId())){
            spaceLevel = SpaceLevelEnum.workshop.getCode();
            param.setId(riskSourceVO.getRelationSpaceParentId());
        } else {
            return riskSourceVO;
        }
        param.setLevel(spaceLevel);
        List<TSafeSpaceVO> riskOwnerVOList = spaceManageService.listByPage(param).getData();
        if(riskOwnerVOList != null && riskOwnerVOList.size() > 0) {
            TSafeSpaceVO spaceVo = riskOwnerVOList.get(0);
            riskSourceVO.setSpaceVO(spaceVo);
            if(spaceLevel == SpaceLevelEnum.workarea.getCode()) {
                riskSourceVO.setRelationSpaceId(spaceVo.getId());
                riskSourceVO.setRelationSpaceCode(spaceVo.getCode());
                riskSourceVO.setSpaceLocation(spaceVo.getSpaceTypeName()
                                +spaceVo.getSpaceName()+spaceVo.getName());
                riskSourceVO.setRelationSpaceParentId(spaceVo.getSpaceId());
            }
            if(spaceLevel == SpaceLevelEnum.workshop.getCode()) {
             //   riskSourceVO.setRelationSpaceId(spaceVo.getId());
                riskSourceVO.setRelationSpaceCode(spaceVo.getCode());
                riskSourceVO.setSpaceLocation(spaceVo.getSpaceTypeName()
                        +spaceVo.getName());
                riskSourceVO.setRelationSpaceParentId(spaceVo.getId());
            }
        }
        return riskSourceVO;
    }

    // 组装 实体中的 风险点
    public TSafeRiskSourceVO generateRiskPoint(TSafeRiskSourceVO riskSourceVO) {
        if (StrUtil.isBlank(riskSourceVO.getId())) {
            return null;
        }

        TSafeRiskPointDTO point = riskPointManageService.findBySource(riskSourceVO.getId());

        if(point == null) {
            return riskSourceVO;
        }
        riskSourceVO.setPointId(point.getId());
        riskSourceVO.setPointName(point.getName());
        return riskSourceVO;
    }

    /**
     * 列表不分页
     *
     * @param param
     * @return
     */
    public List<TSafeRiskSourceDTO> listAll(TSafeRiskSourceDTOParam param) {
        return tSafeRiskSourceRepo.listAll(param);
    }

    /**
     * @param type  1-设备; 2-空间(作业区域)；  3-空间(危险源)；
     * @param bizId type=1-设备id; 2-空间(作业区域)id；  3-空间(危险源)id；
     * @return
     */
    @Transactional
    public boolean deleteBySpaceOrEquipment(Integer type, String bizId) {
        return tSafeRiskSourceRepo.deleteBySpaceOrEquipment(type, bizId);
    }

    public String orgAllPath(String orgId){
        if(StrUtil.isBlank(orgId)) {
            return null;
        }
        // 组装 组装机构全路径
        SysOrg org = orgService.getById(orgId);
        String orgAllPath = org.getParentIds() + "," + orgId;
        return orgAllPath;
    }

//    public boolean saveBatch(List<TSafeRiskSourceDTO> riskSourceDTOList){
//        return tSafeRiskSourceRepo.saveBatch(riskSourceDTOList);
//    }

    /**
     * 获取 导出危险源的 数据源
     *
     * @return
     */
    public List<RiskSourceReportVO> exportRiskData(String dsName, String datasetName, Map<String, Object> parameters) {
        TSafeRiskSourceDTOParam param = new TSafeRiskSourceDTOParam();
        param.setStatus(BizConstants.STATUS_ENABLE);
        param.setLimit("999999");
        BaseResponseList<TSafeRiskSourceVO> responseList = listByPage(param);
        if(responseList == null || responseList.getData() == null || responseList.getData().size() == 0) {
            return null;
        }

        List<TSafeRiskSourceVO> riskSourceVOList = responseList.getData().stream().map(vo -> {
            return generateRiskOwner(vo);
        }).collect(Collectors.toList());

        List<RiskSourceReportVO> sourceReportVOList = new ArrayList<>();
        RiskSourceReportVO sourceReportVO;
        for(TSafeRiskSourceVO riskSourceVO : riskSourceVOList) {
            List<TSafeRiskOwnerVO> riskOwnerVOList = riskSourceVO.getRiskOwnerList();

            RiskSourceReportVO sourceReportVOTemp = BeanUtil.toBean(riskSourceVO, RiskSourceReportVO.class);
            if(riskSourceVO.getSpaceVO() != null) {
                TSafeSpaceVO spaceVo = riskSourceVO.getSpaceVO();
                sourceReportVOTemp.setRelationSpaceTypeId(spaceVo.getSpaceTypeId());
                sourceReportVOTemp.setRelationSpaceTypeName(spaceVo.getSpaceTypeName());
                if(spaceVo.getLevel() == SpaceLevelEnum.workshop.getCode().intValue()) {
                    sourceReportVOTemp.setRelationWorkshopId(spaceVo.getId());
                    sourceReportVOTemp.setRelationWorkshopName(spaceVo.getName());
                    sourceReportVOTemp.setRelationSpaceCode(spaceVo.getCode());

                } else {
                    sourceReportVOTemp.setRelationWorkshopId(spaceVo.getSpaceId());
                    sourceReportVOTemp.setRelationWorkshopName(spaceVo.getSpaceName());
                    sourceReportVOTemp.setRelationSpaceId(spaceVo.getId());
                    sourceReportVOTemp.setRelationSpaceCode(spaceVo.getCode());
                    sourceReportVOTemp.setSpaceLocation(spaceVo.getName());
                }

            }

            if(riskOwnerVOList == null || riskOwnerVOList.size() == 0) {
                sourceReportVO = BeanUtil.toBean(sourceReportVOTemp, RiskSourceReportVO.class);
                sourceReportVOList.add(sourceReportVO);
                continue;
            }

            for (TSafeRiskOwnerVO riskOwnerVO : riskOwnerVOList) {
                sourceReportVO = BeanUtil.toBean(sourceReportVOTemp, RiskSourceReportVO.class);
                sourceReportVO.setOwnerDepartment(riskOwnerVO.getDepartmentName());
                sourceReportVO.setOwnerUserName(riskOwnerVO.getUserName());
                sourceReportVOList.add(sourceReportVO);
            }
        }

        return sourceReportVOList;

    }

    /**
     * 检测 名称 是否都唯一
     * @return true - 唯一； false - 不唯一
     */
    public boolean checkUniqueness(String orgId, String sourceId, String name) {
        return riskSourceService.checkUniqueness(orgId, sourceId, name);
    }

    public TSafeRiskSourceDTO save(TSafeRiskSourceDTO sourceDTO){
        return tSafeRiskSourceRepo.insert(sourceDTO);
    }

    // 查询指定空间 下的 最大 固有风险等级、现实风险等级
    public Map findMaxRiskLevel(String spaceId, Integer level){
        if(StrUtil.isBlank(spaceId) || level == null) {
            return null;
        }

        TSafeRiskSourceDTOParam sourceParam = new TSafeRiskSourceDTOParam();
        sourceParam.setStatus(BizConstants.STATUS_ENABLE);
        if(level == 1) { // 车间场所
            sourceParam.setRelationSpaceParentId(spaceId);
        } else if(level == 2) { // 作业区域
            sourceParam.setRelationSpaceId(spaceId);
        }else {
            return null;
        }

        sourceParam.setLimit("99999");
        BaseResponseList<TSafeRiskSourceVO> riskSourceList = listByPage(sourceParam);
        if(riskSourceList == null || riskSourceList.getData() == null || riskSourceList.getData().size() == 0) {
            return null;
        }
        List<TSafeRiskSourceVO> list = riskSourceList.getData();
        String inherentLevel = list.stream().max(Comparator.comparing(TSafeRiskSourceVO::getInherentLevelKey)).get().getInherentLevelKey();
        String realLevel = list.stream().max(Comparator.comparing(TSafeRiskSourceVO::getRealLevelKey)).get().getRealLevelKey();

        Map<String, String> riskLevelMap = new HashMap<>();
        riskLevelMap.put("inherentLevel", inherentLevel);
        riskLevelMap.put("realLevel", realLevel);
        return riskLevelMap;
    }

    @Override
    public void downloadFile(HttpServletRequest request, HttpServletResponse response, List<String> collect) {
        //ToDo 参数校验  查询危险源台账列表
        List<TSafeRiskSourceVO>list=new ArrayList<>();
        //ToDo 管控责任主体集合
        List<TSafeRiskOwnerExportVO>list002=new ArrayList<>();
        TSafeRiskSourceVO detailById =new TSafeRiskSourceVO();
        if (!CollectionUtils.isEmpty(collect)) {
            for (String s : collect) {
                 detailById = this.findDetailById(s);
                 //todo 管控责任主体集合
                List<TSafeRiskOwnerVO> riskOwnerList = detailById.getRiskOwnerList();
                //todo 组装参数
                List<TSafeRiskOwnerExportVO> tSafeRiskOwnerExportVOS =
                        Beans.listToBean(riskOwnerList, TSafeRiskOwnerExportVO.class);
                list002.addAll(tSafeRiskOwnerExportVOS);
                list.add(detailById);
            }
        }

        List<TSafeRiskSourceExportVO> tSafeRiskSourceExportVOS = new ArrayList<>();
        List<TSafeRiskSourceExportVO> tSafeRiskSourceExportVOS002 = new ArrayList<>();
        //ToDo 数据校验 填充单元信息
        if (!CollectionUtils.isEmpty(list)&&list.size()>0) {
            tSafeRiskSourceExportVOS=Beans.listToBean(list, TSafeRiskSourceExportVO.class);
            for (TSafeRiskSourceExportVO one : tSafeRiskSourceExportVOS) {
                for (TSafeRiskSourceVO two : list) {
                    if (two.getSpaceVO()!=null) {
                        if (one.getId().equals(two.getId())) {
                            one.setSpaceName(two.getSpaceVO().getSpaceName());
                            one.setSpaceTypeName(two.getSpaceVO().getSpaceTypeName());
                            one.setSpaceLocationZ(two.getSpaceVO().getName());
                        }
                    }
                    continue;
                }
            }
        }
        for (int i = 0; i < tSafeRiskSourceExportVOS.size(); i++) {
            for (int i1 = 0; i1 < list002.size(); i1++) {
                if (tSafeRiskSourceExportVOS.get(i).getId().equals(list002.get(i1).getRiskId())) {
                    TSafeRiskSourceExportVO tSafeRiskSourceExportVO = Beans.objectToBean(tSafeRiskSourceExportVOS.get(i), TSafeRiskSourceExportVO.class);
                    tSafeRiskSourceExportVO.setUserName(list002.get(i1).getUserName());
                    tSafeRiskSourceExportVO.setUserDepartmentName(list002.get(i1).getDepartmentName());
                    tSafeRiskSourceExportVOS002.add(tSafeRiskSourceExportVO);
                }
            }
        }


        ArrayList<TSafeRiskSourceExportVO> collect2 = tSafeRiskSourceExportVOS002.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() ->
                new TreeSet<>(Comparator.comparing(o -> o.getId()))), ArrayList::new));
        List<String> ids = collect2.stream()
                .map(TSafeRiskSourceExportVO::getId).collect(Collectors.toList());

            List<TSafeRiskSourceExportVO>three=new ArrayList<>();
        for (TSafeRiskSourceExportVO tSafeRiskSourceExportVO : tSafeRiskSourceExportVOS) {
            for (String id : ids) {
                if (id.equals(tSafeRiskSourceExportVO.getId())) {
                    three.add(tSafeRiskSourceExportVO);
                }
            }
        }
        for (int i = 0; i < three.size(); i++) {
            tSafeRiskSourceExportVOS.remove(three.get(i));

        }
        tSafeRiskSourceExportVOS.addAll(tSafeRiskSourceExportVOS002);


        //ToDo 导出
        try (OutputStream out = response.getOutputStream()) {
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setCharacterEncoding("utf-8");
            String fileName = URLEncoder.encode("危险源台账", "UTF-8").replaceAll("\\+", "%20");
            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
            WriteSheet dealerSheet = EasyExcel.writerSheet(0, "危险源台账")
                    .registerWriteHandler(new ExcelWidthStyleStrategy())
                    .head(TSafeRiskSourceExportVO.class)
//                    .registerWriteHandler(new AutoHeadColumnWidthStyleStrategy()).head(TSafeRiskSourceExportVO.class).build();
                    .registerWriteHandler(new CustomMergeStrategy(tSafeRiskSourceExportVOS.stream().map(TSafeRiskSourceExportVO::getRelationSpaceCode).collect(Collectors.toList()), 0))
//                    .registerWriteHandler(new CustomMergeStrategy(tSafeRiskSourceExportVOS.stream().map(TSafeRiskSourceExportVO::getRegionOrgName).collect(Collectors.toList()), 1))
//                    .registerWriteHandler(new CustomMergeStrategy(tSafeRiskSourceExportVOS.stream().map(TSafeRiskSourceExportVO::getOrgName).collect(Collectors.toList()), 2))
//                    .registerWriteHandler(new CustomMergeStrategy(tSafeRiskSourceExportVOS.stream().map(TSafeRiskSourceExportVO::getSpaceTypeName).collect(Collectors.toList()), 3))
//                    .registerWriteHandler(new CustomMergeStrategy(tSafeRiskSourceExportVOS.stream().map(TSafeRiskSourceExportVO::getSpaceName).collect(Collectors.toList()), 4))
//                    .registerWriteHandler(new CustomMergeStrategy(tSafeRiskSourceExportVOS.stream().map(TSafeRiskSourceExportVO::getSpaceLocationZ).collect(Collectors.toList()), 5))
                    .registerWriteHandler(new CustomMergeStrategy(tSafeRiskSourceExportVOS.stream().map(TSafeRiskSourceExportVO::getPointName).collect(Collectors.toList()), 6))
                    .registerWriteHandler(new CustomMergeStrategy(tSafeRiskSourceExportVOS.stream().map(TSafeRiskSourceExportVO::getTypeName).collect(Collectors.toList()), 7))
                    .registerWriteHandler(new CustomMergeStrategy(tSafeRiskSourceExportVOS.stream().map(TSafeRiskSourceExportVO::getName).collect(Collectors.toList()), 8))
                    .registerWriteHandler(new CustomMergeStrategy(tSafeRiskSourceExportVOS.stream().map(TSafeRiskSourceExportVO::getInherentLevelName).collect(Collectors.toList()), 9))
                    .registerWriteHandler(new CustomMergeStrategy(tSafeRiskSourceExportVOS.stream().map(TSafeRiskSourceExportVO::getConsequenceName).collect(Collectors.toList()), 10))
                    .registerWriteHandler(new CustomMergeStrategy(tSafeRiskSourceExportVOS.stream().map(TSafeRiskSourceExportVO::getControlBasis).collect(Collectors.toList()), 11))
                    .registerWriteHandler(new CustomMergeStrategy(tSafeRiskSourceExportVOS.stream().map(TSafeRiskSourceExportVO::getControlMeasures).collect(Collectors.toList()), 12))
                    .registerWriteHandler(new CustomMergeStrategy(tSafeRiskSourceExportVOS.stream().map(TSafeRiskSourceExportVO::getImprovementPlan).collect(Collectors.toList()), 13))
//                    .registerWriteHandler(new CustomMergeStrategy(tSafeRiskSourceExportVOS.stream().map(t->t.getLecL().toString()).collect(Collectors.toList()), 14))
//                    .registerWriteHandler(new CustomMergeStrategy(tSafeRiskSourceExportVOS.stream().map(t->t.getLecE().toString()).collect(Collectors.toList()), 15))
//                    .registerWriteHandler(new CustomMergeStrategy(tSafeRiskSourceExportVOS.stream().map(t->t.getLecC().toString()).collect(Collectors.toList()), 16))
//                    .registerWriteHandler(new CustomMergeStrategy(tSafeRiskSourceExportVOS.stream().map(t->t.getLsL().toString()).collect(Collectors.toList()), 17))
//                    .registerWriteHandler(new CustomMergeStrategy(tSafeRiskSourceExportVOS.stream().map(t->t.getLsS().toString()).collect(Collectors.toList()), 18))
                    .registerWriteHandler(new CustomMergeStrategy(tSafeRiskSourceExportVOS.stream().map(TSafeRiskSourceExportVO::getRiskLevelName).collect(Collectors.toList()), 19))
                    .registerWriteHandler(new CustomMergeStrategy(tSafeRiskSourceExportVOS.stream().map(TSafeRiskSourceExportVO::getCheckFrequencyName).collect(Collectors.toList()), 20))
                    .registerWriteHandler(new CustomMergeStrategy(tSafeRiskSourceExportVOS.stream().map(TSafeRiskSourceExportVO::getUserDepartmentName).collect(Collectors.toList()), 21))
                    .build();
            ExcelWriter build = EasyExcelFactory.write(out).build();
//            EasyExcel.write(fileName, User.class).sheet("用户表").doWrite(data());
//            build.write(accidentExports,dealerSheet);
            build.write(tSafeRiskSourceExportVOS,dealerSheet);
            build.finish();
            out.flush();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 批量导出危险源数据
     *
     * @param request
     * @param response
     * @param param
     */
    @Override
    public void exportRiskResource(HttpServletRequest request, HttpServletResponse response, TSafeRiskSourceDTOParam param) {

        logger.info("查询危险源信息统计表开始：param={}，time={}", JSON.toJSONString(param), DateUtil.now());
        List<TSafeRiskSourceVO> riskSourceVOList = riskSourceService.listExpData(param);
        if(riskSourceVOList == null || riskSourceVOList.size() == 0){
            return;
        }
        logger.info("查询危险源信息统计表结束：time={}", DateUtil.now());

        List<NewSysOrg> sysOrgList = newSysOrgService.lambdaQuery().list();
        //赋值部门名称
        Map<String, String> sysOrgMap = sysOrgList.stream().collect(Collectors.toMap(SysOrg::getOrgId, SysOrg::getOrgName));

        List<TSafeSpaceVO> safeSpaceVOList = spaceManageService.listSafeSpaceAll(new TSafeSpaceDTOParam());
        Map<String, TSafeSpaceVO> spaceVOMap = safeSpaceVOList.stream().collect(Collectors.toMap(TSafeSpaceVO::getId, spaceVo -> spaceVo));

        List<RiskSourceReportVO> sourceReportVOList = riskSourceVOList.parallelStream().flatMap(riskSourceVO -> this.sourceReportVOList(riskSourceVO,spaceVOMap,sysOrgMap).stream()).collect(Collectors.toList());

        String fileName = "危险源信息统计表";
        InputStream templatePathName = null;
        OutputStream outputStream = null;
        ExcelWriter excelWriter = null;
        try {
            response.setCharacterEncoding("UTF-8");
            //mime类型
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8") + ".xlsx");
            response.setHeader("Pragma", "No-cache");
            templatePathName = this.getClass().getClassLoader().getResourceAsStream("excel/wxydcmb.xlsx");
            outputStream = response.getOutputStream();
            excelWriter = EasyExcel.write(outputStream).withTemplate(templatePathName).build();
            WriteSheet writeSheet = EasyExcel.writerSheet().build();
            excelWriter.fill(sourceReportVOList, writeSheet);
        } catch (IOException e) {
            logger.error("导出危险源信息统计表异常：" + e.getMessage(),e);
        } finally {
            if (excelWriter != null) {
                excelWriter.finish();
            }
            if (templatePathName != null) {
                try {
                    templatePathName.close();
                } catch (IOException e) {
                    logger.error("关闭模板文件流异常：" + e.getMessage(), e);
                }
            }
        }

    }

    private TSafeRiskSourceVO generateRiskOrg(TSafeRiskSourceVO vo, Map<String, String> sysOrgMap){
        String parentIdsString = vo.getOrgAllPath();
        //截取0后的父级id
        String[] parentIds = parentIdsString.substring(2).split(",");

        if(parentIds.length > 2){
            String regionOrgName = sysOrgMap.get(parentIds[1]);
            String basicOrgName = sysOrgMap.get(parentIds[2]);
            vo.setRegionOrgName(regionOrgName);
            if(!basicOrgName.equals(vo.getOrgName())){
                vo.setBasicOrgName(basicOrgName);
            } else {
                vo.setBasicOrgName("");
            }
        }
        return vo;
    }

    private TSafeRiskSourceVO generateSpace2(TSafeRiskSourceVO riskSourceVO, Map<String, TSafeSpaceVO> spaceVOMap){
        if (StrUtil.isBlank(riskSourceVO.getId())) {
            return null;
        }

        int spaceLevel = 0;
        String spaceId = "";
        // 危险类型
        if(!StrUtil.isBlank(riskSourceVO.getRelationSpaceId())) {
            spaceId = riskSourceVO.getRelationSpaceId();

        } else if(!StrUtil.isBlank(riskSourceVO.getRelationSpaceParentId())){
            spaceId = riskSourceVO.getRelationSpaceParentId();
        } else {
            return riskSourceVO;
        }
        TSafeSpaceVO spaceVo = spaceVOMap.get(spaceId);
        if(spaceVo != null) {
            riskSourceVO.setSpaceVO(spaceVo);
            if(spaceLevel == SpaceLevelEnum.workarea.getCode()) {
                riskSourceVO.setRelationSpaceId(spaceVo.getId());
                riskSourceVO.setRelationSpaceCode(spaceVo.getCode());
                riskSourceVO.setSpaceLocation(spaceVo.getSpaceTypeName()
                        +spaceVo.getSpaceName()+spaceVo.getName());
                riskSourceVO.setRelationSpaceParentId(spaceVo.getSpaceId());
            }
            if(spaceLevel == SpaceLevelEnum.workshop.getCode()) {
                riskSourceVO.setRelationSpaceCode(spaceVo.getCode());
                riskSourceVO.setSpaceLocation(spaceVo.getSpaceTypeName()
                        +spaceVo.getName());
                riskSourceVO.setRelationSpaceParentId(spaceVo.getId());
            }
        }
        return riskSourceVO;

    }

    private List<RiskSourceReportVO> sourceReportVOList(TSafeRiskSourceVO vo, Map<String, TSafeSpaceVO> spaceVOMap, Map<String, String> sysOrgMap){
        List<RiskSourceReportVO> sourceReportVOList = new ArrayList<>();
        TSafeRiskSourceVO riskSourceVO = BeanUtil.toBean(vo, TSafeRiskSourceVO.class);
        String isMajor = RiskSourceIsMajorEnum.NO.getValue().equals(riskSourceVO.getIsMajor()) ? "否" :"是";
        riskSourceVO.setIsMajor(isMajor);
        // 组装 组装机构全路径
        generateRiskOrg(riskSourceVO, sysOrgMap);
//            generateRiskPoint(riskSourceVO);
        generateRiskOwner(riskSourceVO);
        generateSpace2(riskSourceVO, spaceVOMap);
        List<TSafeRiskOwnerVO> riskOwnerVOList = riskSourceVO.getRiskOwnerList();
        RiskSourceReportVO sourceReportVOTemp = BeanUtil.toBean(riskSourceVO, RiskSourceReportVO.class);
        if(riskSourceVO.getSpaceVO() != null) {
            TSafeSpaceVO spaceVo = riskSourceVO.getSpaceVO();
            sourceReportVOTemp.setRelationSpaceTypeId(spaceVo.getSpaceTypeId());
            sourceReportVOTemp.setRelationSpaceTypeName(spaceVo.getSpaceTypeName());
            if(spaceVo.getLevel() == SpaceLevelEnum.workshop.getCode().intValue()) {
                sourceReportVOTemp.setRelationWorkshopId(spaceVo.getId());
                sourceReportVOTemp.setRelationWorkshopName(spaceVo.getName());
                sourceReportVOTemp.setRelationSpaceCode(spaceVo.getCode());

            } else {
                sourceReportVOTemp.setRelationWorkshopId(spaceVo.getSpaceId());
                sourceReportVOTemp.setRelationWorkshopName(spaceVo.getSpaceName());
                sourceReportVOTemp.setRelationSpaceId(spaceVo.getId());
                sourceReportVOTemp.setRelationSpaceCode(spaceVo.getCode());
                sourceReportVOTemp.setSpaceLocation(spaceVo.getName());
            }

        }
        RiskSourceReportVO sourceReportVO = BeanUtil.toBean(sourceReportVOTemp, RiskSourceReportVO.class);
        if(riskOwnerVOList == null || riskOwnerVOList.size() == 0) {
            sourceReportVOList.add(sourceReportVO);

        } else {
            for (TSafeRiskOwnerVO riskOwnerVO : riskOwnerVOList) {
                sourceReportVO.setOwnerDepartment(riskOwnerVO.getDepartmentName());
                sourceReportVO.setOwnerUserName(riskOwnerVO.getUserName());
                sourceReportVOList.add(sourceReportVO);
            }
        }
        return sourceReportVOList;
    }
}
