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

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.testor.ddd.safetyControl.application.service.riskPointSource.RiskPointSourceManageService;
import com.testor.ddd.safetyControl.application.service.riskSourceManage.RiskSourceManageService;
import com.testor.ddd.safetyControl.domain.riskPointSource.entity.TSafeRiskPointSourceRepo;
import com.testor.ddd.safetyControl.domain.riskPointSource.service.RiskPointSourceService;
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.TSafeRiskSourceDTOParam;
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.riskSource.TSafeRiskSourceVO;
import com.tongtech.tfw.backend.common.biz.constants.BizConstants;
import com.tongtech.tfw.backend.common.biz.models.BaseResponseList;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class RiskPointSourceManageServiceImpl implements RiskPointSourceManageService {
    @Resource
    private RiskPointSourceService riskPointSourceService;

    @Resource
    private TSafeRiskPointSourceRepo riskPointSourceRepo;

    @Resource
    private RiskSourceManageService riskSourceManageService;

    public boolean saveBatch(String orgId, String pointId, List<TSafeRiskPointSourceDTO> riskPointSourceDTOList){
        if(riskPointSourceDTOList == null || riskPointSourceDTOList.size() == 0) {
            return false;
        }

        return riskPointSourceService.saveBatch(orgId, pointId, riskPointSourceDTOList);
    }

    /**
     * 获取 可选危险源、 已选风险源、 禁选风险源
     * @param param
     * @return
     */
    public RiskPointSourceListVO listAll(TSafeRiskPointSourceDTOParam param) {
        TSafeRiskSourceDTOParam sourceParam = new TSafeRiskSourceDTOParam();
        sourceParam.setStatus(BizConstants.STATUS_ENABLE);
        sourceParam.setRelationEquipmentId(param.getEquipmentId());
        sourceParam.setRelationSpaceId(param.getWorkareaId());
        sourceParam.setRelationSpaceParentId(param.getWorkshopId());
        sourceParam.setRelationType(param.getRelationType());
        sourceParam.setLimit("99999");
        BaseResponseList<TSafeRiskSourceVO> riskSourceList = riskSourceManageService.listByPage(sourceParam);
        if(riskSourceList == null || riskSourceList.getData() == null || riskSourceList.getData().size() == 0) {
            return null;
        }

        // 空间、设备下所有的 危险源
        List<RiskPointSourceVO> allList = new ArrayList<>();
        RiskPointSourceVO riskPointSourceVO;
        for(TSafeRiskSourceVO sourceVO : riskSourceList.getData()) {
            riskPointSourceVO = new RiskPointSourceVO();
            riskPointSourceVO.setSourceId(sourceVO.getId());
            riskPointSourceVO.setSourceName(sourceVO.getName());
            riskPointSourceVO.setInherentLevelId(sourceVO.getInherentLevelId());
            riskPointSourceVO.setInherentLevelName(sourceVO.getInherentLevelName());
            riskPointSourceVO.setInherentLevelKey(sourceVO.getInherentLevelKey());
            riskPointSourceVO.setRealLevelId(sourceVO.getRealLevelId());
            riskPointSourceVO.setRealLevelName(sourceVO.getRealLevelName());
            riskPointSourceVO.setRealLevelKey(sourceVO.getRealLevelKey());
            riskPointSourceVO.setControlLevelId(sourceVO.getControlLevelId());
            riskPointSourceVO.setControlLevelName(sourceVO.getControlLevelName());
            riskPointSourceVO.setControlLevelKey(sourceVO.getControlLevelKey());
            allList.add(riskPointSourceVO);
        }

        TSafeRiskPointSourceDTOParam allSelectedParam = BeanUtil.copyProperties(param, TSafeRiskPointSourceDTOParam.class);
        String pointId = param.getPointId();
        if(!StrUtil.isBlank(pointId)) {
            allSelectedParam.setPointId(null);
        }

        RiskPointSourceListVO riskPointSourceListVO = new RiskPointSourceListVO();

        // 空间、设备下所有已被选择的 危险源
        List<RiskPointSourceVO> allSelectedList = riskPointSourceRepo.listAll(allSelectedParam);
        // 无 禁选
        if(allSelectedList == null || allSelectedList.size() == 0) {
            riskPointSourceListVO.setOptionalList(allList);
            return riskPointSourceListVO;
        }

        // 当前风险点 为新建 暂无id
        if(StrUtil.isBlank(pointId)) {
            // 从 所有的危险源中 减掉 其它设备已选的危险源 为 可选危险源
            List<RiskPointSourceVO> reduceList = allList.stream().filter(item -> !allSelectedList.contains(item)).collect(Collectors.toList());
            riskPointSourceListVO.setOptionalList(reduceList);
            riskPointSourceListVO.setForbiddenList(allSelectedList);
            return riskPointSourceListVO;
        }

        // 空间、设备下 当前风险点已选择的 危险源
        List<RiskPointSourceVO> selectedList = riskPointSourceRepo.listAll(param);
        // 当前 风险点 暂未选择 危险源
        if(selectedList == null || selectedList.size() == 0) {
            List<RiskPointSourceVO> reduceList = allList.stream().filter(item -> !allSelectedList.contains(item)).collect(Collectors.toList());
            riskPointSourceListVO.setOptionalList(reduceList);
            riskPointSourceListVO.setForbiddenList(allSelectedList);
            return riskPointSourceListVO;
       }

        // 从已选择的危险源中 减掉 当前风险点的选择  为 禁选的危险源
        List<RiskPointSourceVO> selectedReduceList = allSelectedList.stream().filter(item -> !selectedList.contains(item)).collect(Collectors.toList());
        // 从 所有的危险源中 减掉 禁选的危险源 为 可选危险源
        List<RiskPointSourceVO> optionalList = allList.stream().filter(item -> !selectedReduceList.contains(item)).collect(Collectors.toList());

        riskPointSourceListVO.setForbiddenList(selectedReduceList);
        riskPointSourceListVO.setOptionalList(optionalList);
        riskPointSourceListVO.setSelectedList(selectedList);
        return riskPointSourceListVO;
    }

    /**
     * 获取风险点关联的危险源
     * @param param
     * @return
     */
    public List<RiskPointSourceVO> listByPoint(TSafeRiskPointSourceDTOParam param){
        return riskPointSourceRepo.listAll(param);
    }
}
