package com.zt.plat.module.qms.business.bus.liteflow.sample.taskassign;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import org.apache.commons.lang3.StringUtils;

import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.yomahub.liteflow.annotation.LiteflowComponent;
import com.yomahub.liteflow.core.NodeComponent;
import com.zt.plat.module.qms.business.bus.controller.vo.BusinessAssayProjectDataExtendRespVO;
import com.zt.plat.module.qms.business.bus.dal.dataobject.BusinessAssayTaskDO;
import com.zt.plat.module.qms.business.bus.dal.dataobject.BusinessAssayTaskDataDO;
import com.zt.plat.module.qms.business.bus.dal.dataobject.BusinessQCCoefficientDataDO;
import com.zt.plat.module.qms.business.bus.dal.dataobject.BusinessQCCoefficientParameterDataDO;
import com.zt.plat.module.qms.business.bus.dal.dataobject.BusinessQCManagementDataDO;
import com.zt.plat.module.qms.business.bus.dal.dataobject.BusinessQCManagementParameterDataDO;
import com.zt.plat.module.qms.business.bus.dal.dataobject.BusinessQCManagementProjectDataDO;
import com.zt.plat.module.qms.business.bus.dal.dataobject.BusinessQCManagementSampleParameterDataDO;
import com.zt.plat.module.qms.business.bus.dal.mapper.BusinessAssayProjectDataMapper;
import com.zt.plat.module.qms.business.bus.dal.mapper.BusinessQCCoefficientDataMapper;
import com.zt.plat.module.qms.business.bus.dal.mapper.BusinessQCCoefficientParameterDataMapper;
import com.zt.plat.module.qms.business.bus.dal.mapper.BusinessQCManagementDataMapper;
import com.zt.plat.module.qms.business.bus.dal.mapper.BusinessQCManagementParameterDataMapper;
import com.zt.plat.module.qms.business.bus.dal.mapper.BusinessQCManagementProjectDataMapper;
import com.zt.plat.module.qms.business.bus.liteflow.slot.SampleTaskAssignContext;
import com.zt.plat.module.qms.business.config.controller.vo.ConfigAssayMethodProjectExtendRespVO;
import com.zt.plat.module.qms.business.config.controller.vo.ConfigQCSampleMethodExtendRespVO;
import com.zt.plat.module.qms.business.config.controller.vo.ConfigQCSampleMethodParameterExtendRespVO;
import com.zt.plat.module.qms.business.config.dal.dataobject.ConfigAssayMethodDO;
import com.zt.plat.module.qms.business.config.dal.dataobject.ConfigAssayMethodParameterDO;
import com.zt.plat.module.qms.business.config.dal.dataobject.ConfigAssayMethodProjectParameterDO;
import com.zt.plat.module.qms.business.config.dal.mapper.ConfigAssayMethodMapper;
import com.zt.plat.module.qms.business.config.dal.mapper.ConfigAssayMethodParameterMapper;
import com.zt.plat.module.qms.business.config.dal.mapper.ConfigAssayMethodProjectMapper;
import com.zt.plat.module.qms.business.config.dal.mapper.ConfigAssayMethodProjectParameterMapper;
import com.zt.plat.module.qms.business.config.dal.mapper.ConfigQCSampleMethodMapper;
import com.zt.plat.module.qms.business.config.dal.mapper.ConfigQCSampleMethodParameterMapper;
import com.zt.plat.module.qms.core.code.SequenceUtil;
import com.zt.plat.module.qms.enums.QmsCommonConstant;

import cn.hutool.core.collection.CollUtil;
import jakarta.annotation.Resource;

@LiteflowComponent(id = "sampleTaskAssignQCSampleCmp", name = "任务分配质量控制样品")
public class SampleTaskAssignQCSampleCmp extends NodeComponent {

	@Resource
	private SequenceUtil sequenceUtil;
	
	@Resource
	private ConfigAssayMethodMapper configAssayMethodMapper;
	
	@Resource
	private ConfigAssayMethodParameterMapper configAssayMethodParameterMapper;
	
	@Resource
	private ConfigQCSampleMethodMapper configQCSampleMethodMapper;
	
	@Resource
	private ConfigQCSampleMethodParameterMapper configQCSampleMethodParameterMapper;
	
	@Resource
	private ConfigAssayMethodProjectMapper configAssayMethodProjectMapper;
	
	@Resource
	private ConfigAssayMethodProjectParameterMapper configAssayMethodProjectParameterMapper;
	
	@Resource
	private BusinessAssayProjectDataMapper businessAssayProjectDataMapper;
		
	@Resource
	private BusinessQCCoefficientDataMapper businessQCCoefficientDataMapper;
	
	@Resource
	private BusinessQCCoefficientParameterDataMapper businessQCCoefficientParameterDataMapper;
	
	@Resource
	private BusinessQCManagementDataMapper businessQCManagementDataMapper;
	
	@Resource
	private BusinessQCManagementProjectDataMapper businessQCManagementProjectDataMapper;
	
	@Resource
	private BusinessQCManagementParameterDataMapper businessQCManagementParameterDataMapper;
	
	@Override
	public void process() throws Exception {
		SampleTaskAssignContext sampleTaskAssignContext = this.getContextBean(SampleTaskAssignContext.class);
		
		List<BusinessQCCoefficientDataDO> businessQCCoefficientDataDOList = new ArrayList<>();
		List<BusinessQCCoefficientParameterDataDO> businessQCCoefficientParameterDataDOList = new ArrayList<>();
		
	    List<BusinessQCManagementDataDO> businessQCManagementDataDOList = new ArrayList<>();
	    List<BusinessQCManagementSampleParameterDataDO> businessQCManagementSampleParameterDataDOList = new ArrayList<>();
	    List<BusinessQCManagementProjectDataDO> businessQCManagementProjectDataDOList = new ArrayList<>();
	    List<BusinessQCManagementParameterDataDO> businessQCManagementParameterDataDOList = new ArrayList<>();
		
		//分配任务
		List<BusinessAssayTaskDO> businessAssayTaskList = new ArrayList<>();
		//获取需要保存的分配任务
		List<BusinessAssayTaskDO> saveBusinessAssayTaskList = sampleTaskAssignContext.getSaveBusinessAssayTaskList();
		//获取需要修改的分配任务
		List<BusinessAssayTaskDO> updateBusinessAssayTaskList = sampleTaskAssignContext.getUpdateBusinessAssayTaskList();
		businessAssayTaskList.addAll(saveBusinessAssayTaskList);
		businessAssayTaskList.addAll(updateBusinessAssayTaskList);
		
		//检测任务
		List<BusinessAssayTaskDataDO> businessAssayTaskDataList = sampleTaskAssignContext.getBusinessAssayTaskDataList();
		
		//获取分配任务的分析方法id列表
		List<Long> configAssayMethodIdList = businessAssayTaskList.stream().map(m -> m.getConfigAssayMethodId()).distinct().collect(Collectors.toList());
		
		//获取分析方法对应的质控分析配置
		List<ConfigQCSampleMethodExtendRespVO> configQCSampleMethodList = configQCSampleMethodMapper.selectByConfigAssayMethodIds(configAssayMethodIdList);
		if (CollUtil.isEmpty(configQCSampleMethodList)) {//如果未配置质控样品方法，则直接返回
			return;
		}
		//质控id
		List<Long> configQCSampleMethodIdList = configQCSampleMethodList.stream().map(m -> m.getId()).collect(Collectors.toList());
		//质控样分析参数
		List<ConfigQCSampleMethodParameterExtendRespVO> configQcSampleMethodParameterList = configQCSampleMethodParameterMapper.selectByConfigQCSampleMethodIds(configQCSampleMethodIdList);

		//循环分配任务
		for (BusinessAssayTaskDO businessAssayTaskDO : businessAssayTaskList) {
			ConfigQCSampleMethodExtendRespVO configQCSampleMethodExtendRespVO = configQCSampleMethodList.stream().filter(f -> f.getConfigAssayMethodId().equals(businessAssayTaskDO.getConfigAssayMethodId()) && ("kby".equals(f.getDictionaryBusinessKey()) || "zkkby".equals(f.getDictionaryBusinessKey()))).findFirst().orElse(null);
			//不存在空白样，直接跳出
			if (configQCSampleMethodExtendRespVO == null) {
				continue;
			}
			
			ConfigAssayMethodDO configAssayMethodDO = configAssayMethodMapper.selectById(businessAssayTaskDO.getConfigAssayMethodId());
			
			if ("kby".equals(configQCSampleMethodExtendRespVO.getDictionaryBusinessKey())) { //普通空白样

				//查询下质控数据，如果存在则跳出循环
				List<BusinessQCCoefficientDataDO> businessQCCoefficientDataList = businessQCCoefficientDataMapper.selectByBusinessAssayTaskId(businessAssayTaskDO.getId());
				//如果存在则跳出循环
				if (CollUtil.isNotEmpty(businessQCCoefficientDataList)) {
					continue;
				}
				
				//根据默认配置的个数生成空白样
				for (int i = 0; i < configQCSampleMethodExtendRespVO.getDefaultCount(); i++) {

					BusinessQCCoefficientDataDO businessQCCoefficientDataDO = new BusinessQCCoefficientDataDO();
					businessQCCoefficientDataDO.setId(IdWorker.getId());
					businessQCCoefficientDataDO.setBusinessAssayTaskId(businessAssayTaskDO.getId());
					businessQCCoefficientDataDO.setConfigAssayMethodId(configQCSampleMethodExtendRespVO.getConfigAssayMethodId());
					businessQCCoefficientDataDO.setSampleName(configQCSampleMethodExtendRespVO.getDictionaryBusinessName());
					if (StringUtils.isNotBlank(configQCSampleMethodExtendRespVO.getCodeRule())) {
						String codeSample = sequenceUtil.genCode(configQCSampleMethodExtendRespVO.getCodeRule());
						businessQCCoefficientDataDO.setSampleCode(codeSample);
					}
					businessQCCoefficientDataDO.setDictionaryBusinessId(configQCSampleMethodExtendRespVO.getDictionaryBusinessId());
					businessQCCoefficientDataDO.setDictionaryBusinessKey(configQCSampleMethodExtendRespVO.getDictionaryBusinessKey());
					businessQCCoefficientDataDO.setAssayDepartmentId(configAssayMethodDO.getAssayDepartmentId());
					businessQCCoefficientDataDO.setAssayDepartmentName(configAssayMethodDO.getAssayDepartmentName());
					businessQCCoefficientDataDO.setAssayOperator(businessAssayTaskDO.getAssayOperator());
					businessQCCoefficientDataDO.setAssayOperatorId(businessAssayTaskDO.getAssayOperatorId());
					businessQCCoefficientDataDO.setAssayProject("");
					businessQCCoefficientDataDO.setAssignTaskTime(businessAssayTaskDO.getTaskAssignTime());
					businessQCCoefficientDataDO.setIsAssignTasked(QmsCommonConstant.YES);
					businessQCCoefficientDataDO.setIsReported(QmsCommonConstant.NO);
					
					businessQCCoefficientDataDOList.add(businessQCCoefficientDataDO);
					
					List<ConfigQCSampleMethodParameterExtendRespVO> configQCSampleMethodParameterExtendRespVOs = configQcSampleMethodParameterList.stream().filter(f -> f.getConfigQCSampleMethodId().equals(configQCSampleMethodExtendRespVO.getId())).collect(Collectors.toList());
					for (ConfigQCSampleMethodParameterExtendRespVO configQCSampleMethodParameterExtendRespVO : configQCSampleMethodParameterExtendRespVOs) {
						BusinessQCCoefficientParameterDataDO businessQCCoefficientParameterDataDO = new BusinessQCCoefficientParameterDataDO();
						businessQCCoefficientParameterDataDO.setBusinessQCCoefficientDataId(businessQCCoefficientDataDO.getId());
						businessQCCoefficientParameterDataDO.setConfigQCSampleMethodParameterId(configQCSampleMethodParameterExtendRespVO.getId());
						businessQCCoefficientParameterDataDO.setDictionaryParameterId(configQCSampleMethodParameterExtendRespVO.getDictionaryParameterId());
						businessQCCoefficientParameterDataDO.setDataType(configQCSampleMethodParameterExtendRespVO.getDataType());
						businessQCCoefficientParameterDataDO.setDecimalPosition(configQCSampleMethodParameterExtendRespVO.getDecimalPosition());
						businessQCCoefficientParameterDataDO.setValue(configQCSampleMethodParameterExtendRespVO.getDefaultValue());					
						
						businessQCCoefficientParameterDataDOList.add(businessQCCoefficientParameterDataDO);
					}
				}
				
			} else if ("zkkby".equals(configQCSampleMethodExtendRespVO.getDictionaryBusinessKey())) {//质控空白样
				//查询质控数据，如果存在则跳出循环
				List<BusinessQCManagementDataDO> businessQCManagementDataList = businessQCManagementDataMapper.selectByBusinessAssayTaskId(businessAssayTaskDO.getId());
				if (CollUtil.isNotEmpty(businessQCManagementDataList)) {
					continue;
				}
				//分析项目
				List<ConfigAssayMethodProjectExtendRespVO> configAssayMethodProjectExtendRespList = configAssayMethodProjectMapper.selectByConfigAssayMethodId(businessAssayTaskDO.getConfigAssayMethodId());
				
				List<Long> businessAssayTaskDataIdList = businessAssayTaskDataList.stream().filter(f -> f.getBusinessAssayTaskId().equals(businessAssayTaskDO.getId())).map(m -> m.getId()).collect(Collectors.toList());
				List<BusinessAssayProjectDataExtendRespVO> businessAssayProjectDataList = businessAssayProjectDataMapper.selectByBusinessAssayTaskDataIds(businessAssayTaskDataIdList);
				//检测项目id
				List<Long> dictionaryProjectIdList = new ArrayList<>();
				//必须要检测的项目
				String mustProject = configQCSampleMethodExtendRespVO.getMustProject();
				if (StringUtils.isNotBlank(mustProject)) {
					String[] mustProjects = mustProject.split(",");
					for (String dicProjectId : mustProjects) {
						dictionaryProjectIdList.add(Long.parseLong(dicProjectId));
					}
				}

				//获取当前任务的检测项目id列表
				List<Long> busTaskDictionaryProjectIdList = businessAssayProjectDataList.stream().map(m -> m.getDictionaryProjectId()).distinct().collect(Collectors.toList());
				dictionaryProjectIdList.addAll(busTaskDictionaryProjectIdList);
				//获取需要创建的检测项目id
				List<Long> configAssayMethodProjectIds = configAssayMethodProjectExtendRespList.stream().filter(f -> dictionaryProjectIdList.contains(f.getDictionaryProjectId())).map(m -> m.getId()).collect(Collectors.toList());
				
				//分析项目参数
				List<ConfigAssayMethodProjectParameterDO> configAssayMethodProjectParameterList = configAssayMethodProjectParameterMapper.selectByConfigAssayMethodProjectIds(configAssayMethodProjectIds);
				//分析项目
				String assayProject = configAssayMethodProjectExtendRespList.stream().map(m -> m.getShowName()).collect(Collectors.joining(","));
				

				//分析方法参数配置
				List<ConfigAssayMethodParameterDO> configAssayMethodParameterDOList = configAssayMethodParameterMapper.selectByConfigAssayMethodId(businessAssayTaskDO.getConfigAssayMethodId());
				
				for (int i = 0; i < configQCSampleMethodExtendRespVO.getDefaultCount(); i++) {
					
					BusinessQCManagementDataDO businessQCManagementDataDO = new BusinessQCManagementDataDO();
					businessQCManagementDataDO.setId(IdWorker.getId());
					businessQCManagementDataDO.setBusinessAssayTaskId(businessAssayTaskDO.getId());
					businessQCManagementDataDO.setConfigAssayMethodId(businessAssayTaskDO.getConfigAssayMethodId());
					businessQCManagementDataDO.setSampleName(configQCSampleMethodExtendRespVO.getDictionaryBusinessName());
					if (StringUtils.isNotBlank(configQCSampleMethodExtendRespVO.getCodeRule())) {
						String codeSample = sequenceUtil.genCode(configQCSampleMethodExtendRespVO.getCodeRule());
						businessQCManagementDataDO.setSampleCode(codeSample);
					}
					businessQCManagementDataDO.setBusinessStandardSampleId(null);//特殊空白样无定值样
					businessQCManagementDataDO.setDictionaryBusinessId(configQCSampleMethodExtendRespVO.getDictionaryBusinessId());
					businessQCManagementDataDO.setDictionaryBusinessKey(configQCSampleMethodExtendRespVO.getDictionaryBusinessKey());
					businessQCManagementDataDO.setAssayDepartmentId(configAssayMethodDO.getAssayDepartmentId());
					businessQCManagementDataDO.setAssayDepartmentName(configAssayMethodDO.getAssayDepartmentName());
					businessQCManagementDataDO.setAssayOperator(businessAssayTaskDO.getAssayOperator());
					businessQCManagementDataDO.setAssayOperatorId(businessAssayTaskDO.getAssayOperatorId());
					businessQCManagementDataDO.setAssayProject(assayProject);
					businessQCManagementDataDO.setAssignTaskTime(businessAssayTaskDO.getTaskAssignTime());
					businessQCManagementDataDO.setIsAssignTasked(QmsCommonConstant.YES);
					businessQCManagementDataDO.setIsReported(QmsCommonConstant.NO);
					
					businessQCManagementDataDOList.add(businessQCManagementDataDO);
					
					BusinessQCManagementSampleParameterDataDO businessQCManagementSampleParameterDataDO = null;
					for (ConfigAssayMethodParameterDO configAssayMethodParameterDO : configAssayMethodParameterDOList) {
						businessQCManagementSampleParameterDataDO = new BusinessQCManagementSampleParameterDataDO();
						businessQCManagementSampleParameterDataDO.setId(IdWorker.getId());
						businessQCManagementSampleParameterDataDO.setBusinessQCManagementDataId(businessQCManagementDataDO.getId());
						businessQCManagementSampleParameterDataDO.setConfigAssayMethodParameterId(configAssayMethodParameterDO.getId());
						businessQCManagementSampleParameterDataDO.setDataType(configAssayMethodParameterDO.getDataType());
						businessQCManagementSampleParameterDataDO.setDecimalPosition(configAssayMethodParameterDO.getDecimalPosition());
						if (StringUtils.isNotBlank(configAssayMethodParameterDO.getDefaultValue())) {
							businessQCManagementSampleParameterDataDO.setValue(configAssayMethodParameterDO.getDefaultValue());
						}
						
						businessQCManagementSampleParameterDataDOList.add(businessQCManagementSampleParameterDataDO);
					}

					for (ConfigAssayMethodProjectExtendRespVO configAssayMethodProjectExtendRespVO : configAssayMethodProjectExtendRespList) {
						if (!dictionaryProjectIdList.contains(configAssayMethodProjectExtendRespVO.getDictionaryProjectId())) {//不存在则跳过
							continue;
						}
						BusinessQCManagementProjectDataDO businessQCManagementProjectDataDO = new BusinessQCManagementProjectDataDO();
						businessQCManagementProjectDataDO.setId(IdWorker.getId());
						businessQCManagementProjectDataDO.setBusinessQCManagementDataId(businessQCManagementDataDO.getId());
						businessQCManagementProjectDataDO.setConfigAssayMethodProjectId(configAssayMethodProjectExtendRespVO.getId());
						businessQCManagementProjectDataDO.setDictionaryProjectId(configAssayMethodProjectExtendRespVO.getDictionaryProjectId());
						businessQCManagementProjectDataDO.setUsage(QmsCommonConstant.ASSAY_PROJECT_USAGE_QUALITY_CONTROL);
						businessQCManagementProjectDataDO.setSymbol("=");
						businessQCManagementProjectDataDO.setDataType(configAssayMethodProjectExtendRespVO.getDataType());
						businessQCManagementProjectDataDO.setDecimalPosition(configAssayMethodProjectExtendRespVO.getDecimalPosition());
						businessQCManagementProjectDataDO.setEffectiveDigit(configAssayMethodProjectExtendRespVO.getEffectiveDigit());
						businessQCManagementProjectDataDO.setIsEnabled(configAssayMethodProjectExtendRespVO.getIsDefaultEnabled());
						
						businessQCManagementProjectDataDOList.add(businessQCManagementProjectDataDO);
						
						List<ConfigAssayMethodProjectParameterDO> configAssayMethodProjectParameterDoList = configAssayMethodProjectParameterList.stream().filter(f -> f.getConfigAssayMethodProjectId().equals(configAssayMethodProjectExtendRespVO.getId())).collect(Collectors.toList());
						for (ConfigAssayMethodProjectParameterDO configAssayMethodProjectParameterDO : configAssayMethodProjectParameterDoList) {
							BusinessQCManagementParameterDataDO businessQCManagementParameterDataDO = new BusinessQCManagementParameterDataDO();
							businessQCManagementParameterDataDO.setBusinessQCManagementProjectDataId(businessQCManagementProjectDataDO.getId());
							businessQCManagementParameterDataDO.setConfigAssayMethodProjectParameterId(configAssayMethodProjectParameterDO.getId());
							businessQCManagementParameterDataDO.setDictionaryParameterId(configAssayMethodProjectParameterDO.getDictionaryParameterId());
							businessQCManagementParameterDataDO.setDataType(configAssayMethodProjectParameterDO.getDataType());
							businessQCManagementParameterDataDO.setDecimalPosition(configAssayMethodProjectParameterDO.getDecimalPosition());
							if (StringUtils.isNotBlank(configAssayMethodProjectParameterDO.getDefaultValue())) {
								businessQCManagementParameterDataDO.setValue(configAssayMethodProjectParameterDO.getDefaultValue());
							}
							
							businessQCManagementParameterDataDOList.add(businessQCManagementParameterDataDO);
						}
						
					}
				}
				
			}
			
		}
		sampleTaskAssignContext.setBusinessQCCoefficientDataList(businessQCCoefficientDataDOList);
		sampleTaskAssignContext.setBusinessQCCoefficientParameterDataList(businessQCCoefficientParameterDataDOList);
		
		sampleTaskAssignContext.setBusinessQCManagementDataDOList(businessQCManagementDataDOList);
		sampleTaskAssignContext.setBusinessQCManagementProjectDataDOList(businessQCManagementProjectDataDOList);
		sampleTaskAssignContext.setBusinessQCManagementParameterDataDOList(businessQCManagementParameterDataDOList);
	}

}
