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

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

import org.apache.commons.lang3.StringUtils;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
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.dal.dataobject.BusinessAssayReportDataDO;
import com.zt.plat.module.qms.business.bus.dal.dataobject.BusinessBaseSampleDO;
import com.zt.plat.module.qms.business.bus.dal.dataobject.BusinessSampleAssayResultDO;
import com.zt.plat.module.qms.business.bus.dal.dataobject.BusinessSampleEntrustDetailDO;
import com.zt.plat.module.qms.business.bus.dal.dataobject.BusinessSampleEntrustRegistrationDO;
import com.zt.plat.module.qms.business.bus.dal.dataobject.BusinessSubParentSampleDO;
import com.zt.plat.module.qms.business.bus.dal.dataobject.BusinessSubSampleDO;
import com.zt.plat.module.qms.business.bus.dal.mapper.BusinessAssayReportDataMapper;
import com.zt.plat.module.qms.business.bus.dal.mapper.BusinessBaseSampleMapper;
import com.zt.plat.module.qms.business.bus.dal.mapper.BusinessSampleAssayResultMapper;
import com.zt.plat.module.qms.business.bus.dal.mapper.BusinessSampleEntrustDetailMapper;
import com.zt.plat.module.qms.business.bus.dal.mapper.BusinessSampleEntrustRegistrationMapper;
import com.zt.plat.module.qms.business.bus.dal.mapper.BusinessSubParentSampleMapper;
import com.zt.plat.module.qms.business.bus.dal.mapper.BusinessSubSampleMapper;
import com.zt.plat.module.qms.business.bus.liteflow.param.SampleFlowInfo;
import com.zt.plat.module.qms.business.bus.liteflow.slot.SampleEntrustContext;
import com.zt.plat.module.qms.business.config.dal.dataobject.BaseSampleDO;
import com.zt.plat.module.qms.business.config.dal.dataobject.ConfigBaseSampleDO;
import com.zt.plat.module.qms.business.config.dal.dataobject.ConfigSampleFlowDO;
import com.zt.plat.module.qms.business.config.dal.dataobject.ConfigSampleReportDO;
import com.zt.plat.module.qms.business.config.dal.dataobject.ConfigSubSampleDO;
import com.zt.plat.module.qms.business.config.dal.dataobject.ConfigSubSampleParentDO;
import com.zt.plat.module.qms.business.config.dal.mapper.BaseSampleMapper;
import com.zt.plat.module.qms.business.config.dal.mapper.ConfigBaseSampleMapper;
import com.zt.plat.module.qms.business.config.dal.mapper.ConfigSampleFlowMapper;
import com.zt.plat.module.qms.business.config.dal.mapper.ConfigSampleReportMapper;
import com.zt.plat.module.qms.business.config.dal.mapper.ConfigSubSampleMapper;
import com.zt.plat.module.qms.business.config.dal.mapper.ConfigSubSampleParentMapper;
import com.zt.plat.module.qms.core.code.SequenceUtil;
import com.zt.plat.module.qms.core.sampleflow.SampleFlowDefinition;
import com.zt.plat.module.qms.core.sampleflow.SampleFlowNode;
import com.zt.plat.module.qms.enums.QmsCommonConstant;

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

/**
 * <b>SampleEntrustUnStandardGenSampleDataCmp</b>
 * 非标分析样品生成
 */
@LiteflowComponent(id = "sampleEntrustUnStandardGenSampleDataCmp", name = "非标样品委托生成系统样品数据")
public class SampleEntrustUnStandardGenSampleDataCmp extends NodeComponent {

	@Resource
	private SequenceUtil sequenceUtil;
	
	@Resource
	private BaseSampleMapper baseSampleMapper;
	
	@Resource
	private BusinessSampleEntrustRegistrationMapper businessSampleEntrustRegistrationMapper;
	
	@Resource
	private BusinessSampleEntrustDetailMapper businessSampleEntrustDetailMapper;
		
	@Resource
	private BusinessSampleAssayResultMapper businessSampleAssayResultMapper;
	
	@Resource
	private ConfigBaseSampleMapper configBaseSampleMapper;
	
	@Resource
	private BusinessBaseSampleMapper businessBaseSampleMapper;
	
	@Resource
	private ConfigSubSampleParentMapper configSubSampleParentMapper;
		
	@Resource
	private BusinessSubParentSampleMapper businessSubParentSampleMapper;
	
	@Resource
	private ConfigSubSampleMapper configSubSampleMapper;
	
	@Resource
	private BusinessSubSampleMapper businessSubSampleMapper;
	
	@Resource
	private ConfigSampleFlowMapper configSampleFlowMapper;
	
	@Resource
	private BusinessAssayReportDataMapper businessAssayReportDataMapper;
	
	@Resource
	private ConfigSampleReportMapper configSampleReportMapper;
	
	@Override
	public void process() throws Exception {
		//获取样品委托上下文
		SampleEntrustContext sampleEntrustContext = this.getContextBean(SampleEntrustContext.class);
		
		//当前登录用户
		String loginRealname = sampleEntrustContext.getLoginRealname();
		
		LocalDateTime currentDateTime = sampleEntrustContext.getCurrentDateTime();
		//样品委托登记
		BusinessSampleEntrustRegistrationDO sampleEntrustRegistration = sampleEntrustContext.getSampleEntrustRegistration();
		//扩展信息
		String sampleEntrustRegistrationExtInfo = sampleEntrustRegistration.getExternalInfomation();
		JSONObject sampleEntrustRegistrationJsonObject = new JSONObject();
		if (StringUtils.isNotBlank(sampleEntrustRegistrationExtInfo)) {
			sampleEntrustRegistrationJsonObject = JSON.parseObject(sampleEntrustRegistrationExtInfo);
		}
		
		//样品委托登记明细
		List<BusinessSampleEntrustDetailDO> sampleEntrustDetailList = sampleEntrustContext.getSampleEntrustDetailList();
		//样品来样品位
		List<BusinessSampleAssayResultDO> sampleAssayResultList = sampleEntrustContext.getSampleAssayResultList();
		
		List<Long> baseSampleIdList = sampleEntrustDetailList.stream().map(m -> m.getBaseSampleId()).distinct().collect(Collectors.toList());
		
		//样品大类列表
		List<BaseSampleDO> baseSampleList = sampleEntrustContext.getBaseSampleList();
		
		//主样配置
		List<ConfigBaseSampleDO> configBaseSampleList = configBaseSampleMapper.selectByBaseSampleIds(baseSampleIdList);
		List<Long> configBaseSampleIdList = configBaseSampleList.stream().map(m -> m.getId()).collect(Collectors.toList());
		//分样配置
		List<ConfigSubSampleParentDO> configSubSampleParentList = configSubSampleParentMapper.selectByBaseSampleIds(baseSampleIdList);
		//子样配置
		List<ConfigSubSampleDO> configSubSampleList = configSubSampleMapper.selectByBaseSampleIds(baseSampleIdList);
		
		//主样报表配置
		List<ConfigSampleReportDO> configSampleReportList = configSampleReportMapper.selectByConfigBaseSampleIds(configBaseSampleIdList);
		
		//样品流程配置
		List<String> configSampleFlowKeyList = new ArrayList<>();
		List<String> configBaseSampleFlowKeyList = configBaseSampleList.stream().map(m -> m.getFlowKey()).distinct().collect(Collectors.toList());
		configSampleFlowKeyList.addAll(configBaseSampleFlowKeyList);
		List<String> configSubSampleFlowKeyList = configSubSampleList.stream().map(m -> m.getFlowKey()).distinct().collect(Collectors.toList());
		configSampleFlowKeyList.addAll(configSubSampleFlowKeyList);
		List<ConfigSampleFlowDO> configSampleFlowList = configSampleFlowMapper.selectLatestConfigSampleFlowListByKeys(configSampleFlowKeyList);
		
		//主样
		List<BusinessBaseSampleDO> businessBaseSampleDOList = new ArrayList<>();
		//分样
		List<BusinessSubParentSampleDO> businessSubParentSampleDOList = new ArrayList<>();
		//分样子样
		List<BusinessSubSampleDO> businessSubSampleDOList = new ArrayList<>();
		//分析报表数据
		List<BusinessAssayReportDataDO> businessAssayReportDataDOList = new ArrayList<>();
		
		//子样流转信息列表
		List<SampleFlowInfo> sampleFlowInfoList = new ArrayList<>();

		//委托明细排序
		List<BusinessSampleEntrustDetailDO> sampleEntrustDetailListSort = sampleEntrustDetailList.stream().sorted(Comparator.comparingInt(BusinessSampleEntrustDetailDO::getSort)).collect(Collectors.toList());
		//主样
		BusinessBaseSampleDO businessBaseSampleDO = null;
		for (BusinessSampleEntrustDetailDO businessSampleEntrustDetailDO : sampleEntrustDetailListSort) {//委托样品明细
			
			//样品大类
			BaseSampleDO baseSampleDO = baseSampleList.stream().filter(f -> f.getId().equals(businessSampleEntrustDetailDO.getBaseSampleId())).findFirst().orElse(null);
			
			//获取到主样配置
			ConfigBaseSampleDO currConfigBaseSample = configBaseSampleList.stream().filter(f -> businessSampleEntrustDetailDO.getBaseSampleId().equals(f.getBaseSampleId())).findFirst().orElse(null);
			//获取分样配置列表
			List<ConfigSubSampleParentDO> currConfigSubSampleParentList = configSubSampleParentList.stream().filter(f -> f.getConfigBaseSampleId().equals(currConfigBaseSample.getId())).collect(Collectors.toList());
				
			
			//主样流程
			ConfigSampleFlowDO configSampleFlowBase = configSampleFlowList.stream().filter(f -> f.getKey().equals(currConfigBaseSample.getFlowKey())).findFirst().orElse(null);
			//样品流程定义
			SampleFlowDefinition sampleFlowDefinitionBase = JSON.parseObject(configSampleFlowBase.getContent(), SampleFlowDefinition.class);
			List<SampleFlowNode> flowNodeBaseList = sampleFlowDefinitionBase.getFlowNodeList().stream().sorted(Comparator.comparing(SampleFlowNode::getSort)).collect(Collectors.toList());
			SampleFlowNode sampleFlowNodeBase = flowNodeBaseList.get(0);
			
			//=======================主样==========================
			businessBaseSampleDO = new BusinessBaseSampleDO();
			businessBaseSampleDO.setId(IdWorker.getId());
			//设置配置id
			businessBaseSampleDO.setConfigBaseSampleId(currConfigBaseSample.getId());
			//样品名称为委托登记来的样品名称
			businessBaseSampleDO.setSampleName(businessSampleEntrustDetailDO.getSampleName());
			//样品大类名称
			businessBaseSampleDO.setBaseSampleName(baseSampleDO.getName());
			//样品类型字典与委托一致
			businessBaseSampleDO.setDictionaryBusinessId(businessSampleEntrustDetailDO.getSampleTypeDictionaryBusinessId());
			//生成样品编号
			String sampleCode = businessSampleEntrustDetailDO.getEntrustSampleCode();//默认取来样编号
			if (StringUtils.isNotBlank(businessSampleEntrustDetailDO.getSampleCode())) {//如果已经提前生成，
				sampleCode = businessSampleEntrustDetailDO.getSampleCode();
			} else if (StringUtils.isNotBlank(currConfigBaseSample.getCodeRule())) {//如果配置了样品编号生成规则，则以生成规则为准
				sampleCode = sequenceUtil.genCode(currConfigBaseSample.getCodeRule());
			}
			businessBaseSampleDO.setSampleCode(sampleCode);
			//样品生成时间为当前时间
			businessBaseSampleDO.setSampleTime(currentDateTime);
			//样品状态正常
			businessBaseSampleDO.setSampleStatus(QmsCommonConstant.NORMAL);
			//主样流程配置id
			businessBaseSampleDO.setConfigSampleFlowId(configSampleFlowBase.getId());
			//主样当前流程节点key
			businessBaseSampleDO.setSampleFlowNodeKey(sampleFlowNodeBase.getNodeKey());
			//主样当前流程节点时间
			businessBaseSampleDO.setSampleFlowNodeTime(currentDateTime);
			//操作人
			businessBaseSampleDO.setOperator(loginRealname);
			
			//添加到列表
			businessBaseSampleDOList.add(businessBaseSampleDO);

			//=======================报表==========================
			List<ConfigSampleReportDO> configSampleReportDOList = configSampleReportList.stream().filter(f -> f.getConfigBaseSampleId().equals(currConfigBaseSample.getId())).collect(Collectors.toList());
			for (ConfigSampleReportDO configSampleReport : configSampleReportDOList) {
				BusinessAssayReportDataDO businessAssayReportDataDO = new BusinessAssayReportDataDO();
				businessAssayReportDataDO.setBusinessBaseSampleId(businessBaseSampleDO.getId());
				businessAssayReportDataDO.setDataSource(configSampleReport.getDataSource());
				businessAssayReportDataDO.setConfigReportTypeId(configSampleReport.getConfigReportTypeId());
				businessAssayReportDataDO.setConfigSampleReportId(configSampleReport.getId());
				businessAssayReportDataDO.setSampleCode(businessBaseSampleDO.getSampleCode());
				
				businessAssayReportDataDOList.add(businessAssayReportDataDO);
			}
			//=====================委托明细======================
			//设置主样id
			businessSampleEntrustDetailDO.setBusinessBaseSampleId(businessBaseSampleDO.getId());
			//设置主样编号
			businessSampleEntrustDetailDO.setSampleCode(businessBaseSampleDO.getSampleCode());

			//=======================分样=========================
			for (ConfigSubSampleParentDO currConfigSubSampleParent : currConfigSubSampleParentList) {
				BusinessSubParentSampleDO businessSubParentSampleDO = new BusinessSubParentSampleDO();
				businessSubParentSampleDO.setId(IdWorker.getId());
				businessSubParentSampleDO.setDictionaryBusinessId(currConfigSubSampleParent.getDictionaryBusinessId());
				businessSubParentSampleDO.setBusinessBaseSampleId(businessBaseSampleDO.getId());
				businessSubParentSampleDO.setConfigSubSampleParentId(currConfigSubSampleParent.getId());
				businessSubParentSampleDO.setSampleName(businessBaseSampleDO.getSampleName());
				businessSubParentSampleDO.setSampleCode(businessBaseSampleDO.getSampleCode());
				businessSubParentSampleDO.setSubSampleCode(businessBaseSampleDO.getSampleCode());
				businessSubParentSampleDO.setSampleStatus(QmsCommonConstant.NORMAL);
				businessSubParentSampleDOList.add(businessSubParentSampleDO);
				

				//=======================子样=======================
				//获取子样配置列表
				List<ConfigSubSampleDO> currConfigSubSampleList = configSubSampleList.stream().filter(f -> f.getConfigBaseSampleId().equals(currConfigBaseSample.getId())).collect(Collectors.toList());
				for (ConfigSubSampleDO currConfigSubSample : currConfigSubSampleList) {

					ConfigSampleFlowDO configSampleFlowSub = configSampleFlowList.stream().filter(f -> f.getKey().equals(currConfigSubSample.getFlowKey())).findFirst().orElse(null);
					//样品流程定义
					SampleFlowDefinition sampleFlowDefinitionSub = JSON.parseObject(configSampleFlowSub.getContent(), SampleFlowDefinition.class);
					List<SampleFlowNode> flowNodeSubList = sampleFlowDefinitionSub.getFlowNodeList().stream().sorted(Comparator.comparing(SampleFlowNode::getSort)).collect(Collectors.toList());
					SampleFlowNode sampleFlowNodeSub = flowNodeSubList.get(0);
					
					BusinessSubSampleDO businessSubSampleDO = new BusinessSubSampleDO();
					businessSubSampleDO.setId(IdWorker.getId());
					businessSubSampleDO.setBusinessBaseSampleId(businessBaseSampleDO.getId());
					businessSubSampleDO.setBusinessSubParentSampleId(businessSubParentSampleDO.getId());
					businessSubSampleDO.setConfigSubSampleId(currConfigSubSample.getId());
					businessSubSampleDO.setDictionaryBusinessId(currConfigSubSample.getDictionaryBusinessId());
					businessSubSampleDO.setGroupId(businessSampleEntrustDetailDO.getEntrustGroupCode());
					businessSubSampleDO.setBatchCode(businessSampleEntrustDetailDO.getEntrustBatchCode());
					businessSubSampleDO.setDualFlag(businessSampleEntrustDetailDO.getEntrustDualFlag());
					businessSubSampleDO.setSampleName(businessBaseSampleDO.getSampleName());
					businessSubSampleDO.setSampleCode(businessBaseSampleDO.getSampleCode());
					businessSubSampleDO.setSampleAssayCode(businessBaseSampleDO.getSampleCode());
					businessSubSampleDO.setSampleReturnCode(businessBaseSampleDO.getSampleCode());
					businessSubSampleDO.setIsWeighing(businessSampleEntrustDetailDO.getIsWeighing());
					businessSubSampleDO.setSampleStatus(QmsCommonConstant.NORMAL);
					businessSubSampleDO.setConfigSampleFlowId(configSampleFlowSub.getId());
					businessSubSampleDO.setSampleFlowNodeKey(sampleFlowNodeSub.getNodeKey());
					businessSubSampleDO.setSampleFlowNodeTime(currentDateTime);
					businessSubSampleDO.setNextSampleFlowNode(sampleFlowNodeSub.getNextFlowNodeName());
					businessSubSampleDO.setIsMaterialAssayStandard(sampleEntrustRegistration.getIsMaterialAssayStandard());
					businessSubSampleDO.setAssayLevel(businessSampleEntrustDetailDO.getAssayLevel());
					businessSubSampleDO.setRemark(sampleEntrustRegistrationJsonObject.getString("sampleCategory"));//子样备注设置样品类型
					
					businessSubSampleDOList.add(businessSubSampleDO);
					

					//子样样品流转信息
					SampleFlowInfo sampleFlowInfo = new SampleFlowInfo();
					sampleFlowInfo.setId(businessSubSampleDO.getId());
					sampleFlowInfo.setSampleName(businessSubSampleDO.getSampleName());
					sampleFlowInfo.setSampleCode(businessSubSampleDO.getSampleCode());
					sampleFlowInfo.setIsWeighing(businessSubSampleDO.getIsWeighing());
					sampleFlowInfo.setSampleWeight(businessSubSampleDO.getLastSampleWeight());
					
					sampleFlowInfoList.add(sampleFlowInfo);
				}
				
			}
			
		}
		
		sampleEntrustRegistration.setRegistrationStatus(QmsCommonConstant.SUBMITTED);
		sampleEntrustRegistration.setAssayStatus(QmsCommonConstant.UNCHECKED);
		sampleEntrustRegistration.setDataStatus(QmsCommonConstant.UNRETURNED);
		
		sampleEntrustContext.setSampleFlowInfoList(sampleFlowInfoList);
		
		businessSampleEntrustRegistrationMapper.updateById(sampleEntrustRegistration);
		if (CollUtil.isNotEmpty(sampleEntrustDetailList)) {
			businessSampleEntrustDetailMapper.updateBatch(sampleEntrustDetailList);
		}
		if (CollUtil.isNotEmpty(sampleAssayResultList)) {
			businessSampleAssayResultMapper.updateBatch(sampleAssayResultList);
		}
		if (CollUtil.isNotEmpty(businessBaseSampleDOList)) {
			businessBaseSampleMapper.insertBatch(businessBaseSampleDOList);
		}
		if (CollUtil.isNotEmpty(businessSubParentSampleDOList)) {
			businessSubParentSampleMapper.insertBatch(businessSubParentSampleDOList);
		}
		if (CollUtil.isNotEmpty(businessSubSampleDOList)) {
			businessSubSampleMapper.insertBatch(businessSubSampleDOList);
		}
		if (CollUtil.isNotEmpty(businessAssayReportDataDOList)) {
			businessAssayReportDataMapper.insertBatch(businessAssayReportDataDOList);
		}
	}

	@Override
	public boolean isAccess() {
		SampleEntrustContext sampleEntrustContext = this.getContextBean(SampleEntrustContext.class);
		return !sampleEntrustContext.getIsUseMaterialAssayStandard();//非标准的执行
	}
	
	
}
