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

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
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 cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;

import com.zt.plat.framework.common.exception.ServiceException;
import com.zt.plat.framework.security.core.LoginUser;
import com.zt.plat.framework.security.core.util.SecurityFrameworkUtils;
import com.zt.plat.framework.tenant.core.context.TenantContextHolder;
import com.zt.plat.module.qms.business.bus.dal.dataobject.BusinessSampleEntrustDetailDO;
import com.zt.plat.module.qms.business.bus.dal.dataobject.BusinessSampleEntrustProjectDO;
import com.zt.plat.module.qms.business.bus.dal.dataobject.BusinessSampleEntrustRegistrationDO;
import com.zt.plat.module.qms.business.bus.dal.dataobject.BusinessSampleEntrustUnStandardProjectDO;
import com.zt.plat.module.qms.business.bus.liteflow.param.SampleEntrustDetail;
import com.zt.plat.module.qms.business.bus.liteflow.param.SampleEntrustDetailProject;
import com.zt.plat.module.qms.business.bus.liteflow.param.SampleEntrustParam;
import com.zt.plat.module.qms.business.bus.liteflow.slot.SampleEntrustContext;
import com.zt.plat.module.qms.business.config.controller.vo.MaterialAssayStandardDetailRespVO;
import com.zt.plat.module.qms.business.config.dal.dataobject.BaseSampleDO;
import com.zt.plat.module.qms.business.config.dal.dataobject.ConfigEntrustSourceDO;
import com.zt.plat.module.qms.business.config.dal.dataobject.MaterialAssayStandardMethodDO;
import com.zt.plat.module.qms.business.config.dal.mapper.BaseSampleMapper;
import com.zt.plat.module.qms.business.config.dal.mapper.ConfigEntrustSourceMapper;
import com.zt.plat.module.qms.business.config.dal.mapper.MaterialAssayStandardDetailMapper;
import com.zt.plat.module.qms.business.config.dal.mapper.MaterialAssayStandardMapper;
import com.zt.plat.module.qms.business.config.dal.mapper.MaterialAssayStandardMethodMapper;
import com.zt.plat.module.qms.business.dic.dal.dataobject.DictionaryProjectDO;
import com.zt.plat.module.qms.business.dic.dal.mapper.DictionaryProjectMapper;
import com.zt.plat.module.qms.enums.QmsCommonConstant;

import jakarta.annotation.Resource;

/**
 * 样品委托上下文初始化
 */
@LiteflowComponent(id = "sampleEntrustContextInitCmp", name = "样品委托上下文初始化")
public class SampleEntrustContextInitCmp extends NodeComponent {
	
	@Resource
	private BaseSampleMapper baseSampleMapper;

	@Resource
	private DictionaryProjectMapper dictionaryProjectMapper;

	@Resource
	private ConfigEntrustSourceMapper configEntrustSourceMapper;
	
	@Resource
	private MaterialAssayStandardMapper materialAssayStandardMapper;
	
	@Resource
	private MaterialAssayStandardDetailMapper materialAssayStandardDetailMapper;
	
	@Resource
	private MaterialAssayStandardMethodMapper materialAssayStandardMethodMapper;

	@Override
	public void process() throws Exception {
		//租户id
		Long tenantId = TenantContextHolder.getRequiredTenantId();
		
		//当前登录用户
		LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
		
		//当前登录用户昵称
		String nickName = SecurityFrameworkUtils.getLoginUserNickname();
		
		//委托来源配置
		ConfigEntrustSourceDO configEntrustSourceDO = null;
		
		//是否使用物料分析标准
		Boolean isUseMaterialAssayStandard = true;
		
		//获取样品委托参数
		SampleEntrustParam sampleEntrustParam = this.getRequestData();
		
		if (sampleEntrustParam == null) {
			throw new ServiceException(1_032_100_000, "样品委托参数不允许为空");
		}
		
		//获取样品委托上下文
		SampleEntrustContext sampleEntrustContext = this.getContextBean(SampleEntrustContext.class);
		sampleEntrustContext.setTenantId(tenantId);
		sampleEntrustContext.setLoginUser(loginUser);
		sampleEntrustContext.setLoginRealname(nickName);
		
		//样品提交时是否收样
		sampleEntrustContext.setIsReceiveSample(sampleEntrustParam.getIsReceiveSample());
		//样品提交时是否送样
		sampleEntrustContext.setIsSendSample(sampleEntrustParam.getIsSendSample());
		
		//检测项目字典
		List<DictionaryProjectDO> dictionaryProjectList = dictionaryProjectMapper.selectList();
		sampleEntrustContext.setDictionaryProjectList(dictionaryProjectList);
		
		//委托登记明细
		List<SampleEntrustDetail> detailList = sampleEntrustParam.getSampleEntrustDetailList();
		
		//物料分析标准项目id列表
		List<Long> materialAssayStandardDetailIdList = detailList.stream()
			    .filter(Objects::nonNull) // 过滤 outer null
			    .map(m -> m.getSampleEntrustDetailProjectList())
			    .filter(Objects::nonNull) // 过滤 inner list null
			    .flatMap(List::stream)
			    .filter(Objects::nonNull) // 过滤 inner element null
			    .map(SampleEntrustDetailProject::getMaterialAssayStandardDetailId)
			    .filter(Objects::nonNull) // 如果 ID 可能为 null，也过滤
			    .distinct()
			    .collect(Collectors.toList());
		
		//如果物料分析标准项目id列表不为空，则当前分析的为标准分析样品
		if (CollUtil.isNotEmpty(materialAssayStandardDetailIdList)) {
			isUseMaterialAssayStandard = Boolean.TRUE;
			//物料检验标准项
			List<MaterialAssayStandardDetailRespVO> materialAssayStandardDetailList = materialAssayStandardDetailMapper.selectExtendByIds(materialAssayStandardDetailIdList);
			sampleEntrustContext.setMaterialAssayStandardDetailList(materialAssayStandardDetailList);

			//物料检验标准方法
			List<MaterialAssayStandardMethodDO> materialAssayStandardMethodList = materialAssayStandardMethodMapper.selectByMaterialAssayStandardDetailIds(materialAssayStandardDetailIdList);
			sampleEntrustContext.setMaterialAssayStandardMethodList(materialAssayStandardMethodList);
		} else {
			isUseMaterialAssayStandard = Boolean.FALSE;
		}
		sampleEntrustContext.setIsUseMaterialAssayStandard(isUseMaterialAssayStandard);
		
		//委托登记
		BusinessSampleEntrustRegistrationDO sampleEntrustRegistration = BeanUtil.copyProperties(sampleEntrustParam, BusinessSampleEntrustRegistrationDO.class);	
		
		if (sampleEntrustRegistration.getSampleQuantity() == null) {
			sampleEntrustRegistration.setSampleQuantity(detailList.size());
		}
		
		//委托来源id为空并且委托来源key也为空
		if (sampleEntrustParam.getConfigEntrustSourceId() == null && StringUtils.isBlank(sampleEntrustParam.getConfigEntrustSourceKey())) {
			throw new ServiceException(1_032_100_000, "委托来源id或委托来源key为空");
		}
		
		//委托来源的id为空
		if (sampleEntrustParam.getConfigEntrustSourceId() == null && StringUtils.isNotBlank(sampleEntrustParam.getConfigEntrustSourceKey()) && StringUtils.isNotBlank(sampleEntrustParam.getEntrustType())) {
			configEntrustSourceDO = configEntrustSourceMapper.selectBySourceKeyAndEntrustType(sampleEntrustParam.getConfigEntrustSourceKey(), sampleEntrustParam.getEntrustType());
			if (configEntrustSourceDO == null) {
				throw new ServiceException(1_032_100_000, "样品委托来源不正确");
			}
			sampleEntrustRegistration.setConfigEntrustSourceId(configEntrustSourceDO.getId());
		} else {
			configEntrustSourceDO = configEntrustSourceMapper.selectById(sampleEntrustParam.getConfigEntrustSourceId());
			if (configEntrustSourceDO == null) {
				throw new ServiceException(1_032_100_000, "样品委托来源不正确");
			}
		}
		sampleEntrustContext.setConfigEntrustSource(configEntrustSourceDO);

		//设置登记是否使用物料分析标准
		if (isUseMaterialAssayStandard) {
			sampleEntrustRegistration.setIsMaterialAssayStandard(QmsCommonConstant.YES);
		} else {
			sampleEntrustRegistration.setIsMaterialAssayStandard(QmsCommonConstant.NO);
		}
		
		//赋值委托来源id
		sampleEntrustContext.setSampleEntrustRegistration(sampleEntrustRegistration);
				
		//样品大类id列表
		List<Long> baseSampleIdList = detailList.stream().map(m -> m.getBaseSampleId()).distinct().collect(Collectors.toList());
		List<BaseSampleDO> baseSampleDOList = baseSampleMapper.selectByIds(baseSampleIdList);
		sampleEntrustContext.setBaseSampleList(baseSampleDOList);
		
		//委托登记样品明细的检测项目明细
		List<BusinessSampleEntrustProjectDO> sampleEntrustProjectList = new ArrayList<>();
		List<BusinessSampleEntrustUnStandardProjectDO> sampleEntrustUnStandardProjectList = new ArrayList<>();
		int sort = 1;
		for (SampleEntrustDetail sampleEntrustDetail : detailList) {
			if (sampleEntrustDetail.getId() == null) {
				sampleEntrustDetail.setId(IdWorker.getId());
			}
			if (sampleEntrustDetail.getSampleTypeDictionaryBusinessId() == null) {
				BaseSampleDO baseSampleDO = sampleEntrustContext.getBaseSampleById(sampleEntrustDetail.getBaseSampleId());
				sampleEntrustDetail.setSampleTypeDictionaryBusinessId(baseSampleDO.getDictionaryBusinessId());
			}
			if (sampleEntrustDetail.getSort() == null) {
				sampleEntrustDetail.setSort(sort);
				sort++;
			}
			if (StringUtils.isBlank(sampleEntrustDetail.getSampleName())) {
				sampleEntrustDetail.setSampleName(sampleEntrustDetail.getEntrustSampleName());
			}
			List<String> assayProjectList = new ArrayList<>();
			List<SampleEntrustDetailProject> projectList = sampleEntrustDetail.getSampleEntrustDetailProjectList();
			for (SampleEntrustDetailProject sampleEntrustDetailProject : projectList) {
				if (isUseMaterialAssayStandard) {
					MaterialAssayStandardDetailRespVO materialAssayStandardDetail = sampleEntrustContext.getMaterialAssayStandardDetailById(sampleEntrustDetailProject.getMaterialAssayStandardDetailId());
					assayProjectList.add(materialAssayStandardDetail.getDictionaryProjectShowName());
				} else {
					DictionaryProjectDO dictionaryProjectDO = sampleEntrustContext.getDictionaryProjectById(sampleEntrustDetailProject.getDictionaryProjectId());
					assayProjectList.add(dictionaryProjectDO.getShowName());
				}
				//判定委托明细id是否为空
				if (sampleEntrustDetailProject.getBusinessSampleEntrustDetailId() == null) {
					sampleEntrustDetailProject.setBusinessSampleEntrustDetailId(sampleEntrustDetail.getId());
				}
			}
			if (StringUtils.isBlank(sampleEntrustDetail.getAssayProject())) {
				sampleEntrustDetail.setAssayProject(CollUtil.join(assayProjectList, ","));
			}
			if (isUseMaterialAssayStandard) {
				sampleEntrustProjectList.addAll(BeanUtil.copyToList(projectList, BusinessSampleEntrustProjectDO.class));
			} else {
				sampleEntrustUnStandardProjectList.addAll(BeanUtil.copyToList(projectList, BusinessSampleEntrustUnStandardProjectDO.class));
			}
		}
		sampleEntrustContext.setSampleEntrustProjectList(sampleEntrustProjectList);
		sampleEntrustContext.setSampleEntrustUnStandardProjectList(sampleEntrustUnStandardProjectList);

	    //委托登记样品明细
		List<BusinessSampleEntrustDetailDO> sampleEntrustDetailList = BeanUtil.copyToList(detailList, BusinessSampleEntrustDetailDO.class);
		sampleEntrustContext.setSampleEntrustDetailList(sampleEntrustDetailList);
	}

}
