package com.zt.plat.module.qms.thirdpartyapi.service;

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

import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson2.JSON;
import com.zt.plat.framework.common.exception.ServiceException;
import com.zt.plat.framework.common.pojo.CommonResult;
import com.zt.plat.framework.common.util.object.BeanUtils;
import com.zt.plat.module.qms.business.bus.controller.vo.BusinessAssayParameterDataExtendRespVO;
import com.zt.plat.module.qms.business.bus.controller.vo.BusinessAssayProjectDataExtendRespVO;
import com.zt.plat.module.qms.business.bus.controller.vo.BusinessAssayTaskDataExtendRespVO;
import com.zt.plat.module.qms.business.bus.controller.vo.BusinessAssayTaskDataReqVO;
import com.zt.plat.module.qms.business.bus.controller.vo.BusinessAssayTaskExtendRespVO;
import com.zt.plat.module.qms.business.bus.controller.vo.BusinessAssayTaskPageReqVO;
import com.zt.plat.module.qms.business.bus.controller.vo.BusinessAssayTaskParameterDataExtendRespVO;
import com.zt.plat.module.qms.business.bus.dal.dataobject.BusinessAssayParameterDataDO;
import com.zt.plat.module.qms.business.bus.dal.dataobject.BusinessAssayProjectDataDO;
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.BusinessAssayTaskParameterDataDO;
import com.zt.plat.module.qms.business.bus.dal.dataobject.BusinessSubSampleDO;
import com.zt.plat.module.qms.business.bus.dal.mapper.BusinessAssayParameterDataMapper;
import com.zt.plat.module.qms.business.bus.dal.mapper.BusinessAssayProjectDataMapper;
import com.zt.plat.module.qms.business.bus.dal.mapper.BusinessAssayTaskDataMapper;
import com.zt.plat.module.qms.business.bus.dal.mapper.BusinessAssayTaskDetailMapper;
import com.zt.plat.module.qms.business.bus.dal.mapper.BusinessAssayTaskMapper;
import com.zt.plat.module.qms.business.bus.dal.mapper.BusinessAssayTaskParameterDataMapper;
import com.zt.plat.module.qms.business.bus.dal.mapper.BusinessSubSampleMapper;
import com.zt.plat.module.qms.business.config.controller.vo.ConfigSubSampleMethodConfInfo;
import com.zt.plat.module.qms.business.config.controller.vo.ConfigSubSampleMethodConfItem;
import com.zt.plat.module.qms.business.config.controller.vo.ConfigSubSampleMethodConfPoint;
import com.zt.plat.module.qms.business.config.controller.vo.ConfigSubSampleMethodExtendRespVO;
import com.zt.plat.module.qms.business.config.dal.mapper.ConfigSubSampleMethodMapper;
import com.zt.plat.module.qms.enums.QmsCommonConstant;
import com.zt.plat.module.qms.thirdpartyapi.controller.vo.AutoIngredientsTaskAssayResultReqVO;
import com.zt.plat.module.qms.thirdpartyapi.controller.vo.AutoIngredientsTaskDetailAssayResultReqVO;
import com.zt.plat.module.qms.thirdpartyapi.controller.vo.AutoIngredientsTaskDetailRespVO;
import com.zt.plat.module.qms.thirdpartyapi.controller.vo.AutoIngredientsTaskQueryReqVO;
import com.zt.plat.module.qms.thirdpartyapi.controller.vo.AutoIngredientsTaskRespVO;
import com.zt.plat.module.system.api.user.AdminUserApi;
import com.zt.plat.module.system.api.user.dto.AdminUserRespDTO;

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

@Service
public class AutoIngredientsServiceImpl implements AutoIngredientsService {
	
    @Resource
    private AdminUserApi adminUserApi;
	
	@Resource
	private BusinessSubSampleMapper businessSubSampleMapper;
	
	@Resource
	private BusinessAssayTaskMapper businessAssayTaskMapper;
	
	@Resource
	private BusinessAssayTaskDetailMapper businessAssayTaskDetailMapper;
	
	@Resource
	private BusinessAssayTaskDataMapper businessAssayTaskDataMapper;
	
	@Resource
	private BusinessAssayTaskParameterDataMapper businessAssayTaskParameterDataMapper;
	
	@Resource
	private ConfigSubSampleMethodMapper configSubSampleMethodMapper;
	
	@Resource
	private BusinessAssayProjectDataMapper businessAssayProjectDataMapper;
	
	@Resource
	private BusinessAssayParameterDataMapper businessAssayParameterDataMapper;

	@Override
	public List<AutoIngredientsTaskRespVO> taskList(AutoIngredientsTaskQueryReqVO reqVO) {
		BusinessAssayTaskPageReqVO search = new BusinessAssayTaskPageReqVO();
		search.setIsIngredients(QmsCommonConstant.YES);
		search.setIngredientsWay(QmsCommonConstant.AUTOMATIC);//自动火试金配料
		search.setIngredientsStatus(QmsCommonConstant.IN_PROGRESS);
		if (reqVO.getTaskTimeStart() != null && reqVO.getTaskTimeEnd() != null) {
			LocalDateTime[] taskAssignSubmiTimes = {reqVO.getTaskTimeStart(), reqVO.getTaskTimeEnd()};
			search.setTaskAssignSubmitTime(taskAssignSubmiTimes);
		}
		List<BusinessAssayTaskExtendRespVO> list = businessAssayTaskMapper.selectList(search);
		List<Long> assayOperatorIdList = list.stream().filter(f -> f.getAssayOperatorId() != null).map(m -> m.getAssayOperatorId()).distinct().collect(Collectors.toList());
		CommonResult<List<AdminUserRespDTO>> userListResult = adminUserApi.getUserList(assayOperatorIdList);
		if (userListResult.isError()) {
			throw new ServiceException(userListResult.getCode(), userListResult.getMsg());
		}
		List<AdminUserRespDTO> userList = userListResult.getData();
		List<AutoIngredientsTaskRespVO> resultList = list.stream().map(m -> {
			AdminUserRespDTO user = userList.stream().filter(f -> f.getId().equals(m.getAssayOperatorId())).findFirst().orElse(null);
			return new AutoIngredientsTaskRespVO(m.getId(), m.getTaskNo(), m.getTaskAssignSubmitTime(), user.getUsername(), m.getAssayOperator());
		}).collect(Collectors.toList());
		return resultList;
	}

	@Override
	public List<AutoIngredientsTaskDetailRespVO> taskDetailList(Long taskId) {
		//查询任务分配信息
//		BusinessAssayTaskDO businessAssayTaskDO = businessAssayTaskMapper.selectById(taskId);
		//查询子样检测任务
		BusinessAssayTaskDataReqVO search = new BusinessAssayTaskDataReqVO();
		search.setBusinessAssayTaskId(taskId);
		List<BusinessAssayTaskDataExtendRespVO> list = businessAssayTaskDataMapper.selectList(search);
		
		//分析人员id列表
		List<Long> assayOperatorIdList = list.stream().filter(f -> f.getAssayOperatorId() != null).map(m -> m.getAssayOperatorId()).distinct().collect(Collectors.toList());
		
		//子样配置id列表
		List<Long> configSubSampleIdList = list.stream().map(m -> m.getConfigSubSampleId()).distinct().collect(Collectors.toList());
		
		//方法id列表
		List<Long> configAssayMethodIdList = list.stream().map(m -> m.getConfigAssayMethodId()).distinct().collect(Collectors.toList());
		
		//子样配置方法
		List<ConfigSubSampleMethodExtendRespVO> configSubSampleMethodList = configSubSampleMethodMapper.selectByConfigSubSampleIdsAndConfigAssayMethodIds(configSubSampleIdList, configAssayMethodIdList);
		
		//分析任务id列表
		List<Long> businessAssayTaskDataIdList = list.stream().map(m -> m.getId()).collect(Collectors.toList());
		
		//查询检测项目
		List<BusinessAssayProjectDataExtendRespVO> businessAssayProjectDataList = businessAssayProjectDataMapper.selectByBusinessAssayTaskDataIds(businessAssayTaskDataIdList);
		List<Long> businessAssayProjectDataIdList = businessAssayProjectDataList.stream().map(m -> m.getId()).collect(Collectors.toList());
		//查询检测项目参数
		List<BusinessAssayParameterDataExtendRespVO> businessAssayParameterDataList = businessAssayParameterDataMapper.selectExtendByBusinessAssayProjectDataIds(businessAssayProjectDataIdList);
		
		//查询任务参数
		List<BusinessAssayTaskParameterDataExtendRespVO> businessAssayTaskParameterDataList = businessAssayTaskParameterDataMapper.selectExtendByBusinessAssayTaskDataIds(businessAssayTaskDataIdList);
		
		CommonResult<List<AdminUserRespDTO>> userListResult = adminUserApi.getUserList(assayOperatorIdList);
		if (userListResult.isError()) {
			throw new ServiceException(userListResult.getCode(), userListResult.getMsg());
		}
		List<AdminUserRespDTO> userList = userListResult.getData();
		List<AutoIngredientsTaskDetailRespVO> resultList = list.stream().map(m -> {
			//分析人员信息
			AdminUserRespDTO user = userList.stream().filter(f -> f.getId().equals(m.getAssayOperatorId())).findFirst().orElse(null);
			//子样配置信息
			ConfigSubSampleMethodExtendRespVO configSubSampleMethodDO = configSubSampleMethodList.stream().filter(f -> f.getConfigSubSampleId().equals(m.getConfigSubSampleId()) && f.getConfigAssayMethodId().equals(m.getConfigAssayMethodId())).findFirst().orElse(null);
			String configInfomation = configSubSampleMethodDO.getConfigInfomation();
			//当前检测项目列表
			List<BusinessAssayProjectDataExtendRespVO> currentBusinessAssayProjectDataList = businessAssayProjectDataList.stream().filter(f -> f.getBusinessAssayTaskDataId().equals(m.getId())).collect(Collectors.toList());
			
			AutoIngredientsTaskDetailRespVO autoIngredientsTaskDetailRespVO = new AutoIngredientsTaskDetailRespVO();
			autoIngredientsTaskDetailRespVO.setId(m.getId());
			autoIngredientsTaskDetailRespVO.setTaskId(m.getBusinessAssayTaskId());
			autoIngredientsTaskDetailRespVO.setSampleCode(m.getSampleAssayCode());
			autoIngredientsTaskDetailRespVO.setSampleName(m.getSampleName());
			
			if (StringUtils.isNotBlank(configInfomation)) {
				ConfigSubSampleMethodConfInfo configSubSampleMethodConfInfo = JSON.parseObject(configInfomation, ConfigSubSampleMethodConfInfo.class);
				//获取下发配置
				List<ConfigSubSampleMethodConfItem> downIngredients = configSubSampleMethodConfInfo.getDownIngredients();
				for (ConfigSubSampleMethodConfItem configSubSampleMethodConfItem : downIngredients) {
					if (configSubSampleMethodConfItem.getRequired()) {
						ConfigSubSampleMethodConfPoint source = configSubSampleMethodConfItem.getSource();
						if (StringUtils.isNotBlank(source.getProject())) {//从检测项目参数中来
							List<String> projectList = Arrays.asList(source.getProject().split(","));//来源可以有多个
							for (String project : projectList) {
								String parameter = source.getParameter();
								BusinessAssayProjectDataExtendRespVO currentBusinessAssayProjectData = currentBusinessAssayProjectDataList.stream().filter(f -> f.getSimpleName().equals(project)).findFirst().orElse(null);
								BusinessAssayParameterDataExtendRespVO currentBusinessAssayParameterData = businessAssayParameterDataList.stream().filter(f -> f.getBusinessAssayProjectDataId().equals(currentBusinessAssayProjectData.getId()) && f.getParameterKey().equals(parameter)).findFirst().orElse(null);
								if (currentBusinessAssayParameterData != null && StringUtils.isNotBlank(currentBusinessAssayParameterData.getValue())) {
									ConfigSubSampleMethodConfPoint target = configSubSampleMethodConfItem.getTarget();
									String field = target.getField();
									BeanUtil.setFieldValue(autoIngredientsTaskDetailRespVO, field, currentBusinessAssayParameterData.getValue());
									break;
								}
							}
						} else if (StringUtils.isNotBlank(source.getAttribute())) {//从分析任务属性中来
							BusinessAssayTaskParameterDataExtendRespVO currentBusinessAssayTaskParameterData = businessAssayTaskParameterDataList.stream().filter(f -> f.getBusinessAssayTaskDataId().equals(m.getId()) && f.getKey().equals(source.getAttribute())).findFirst().orElse(null);
							if (currentBusinessAssayTaskParameterData != null && StringUtils.isNotBlank(currentBusinessAssayTaskParameterData.getValue())) {
								ConfigSubSampleMethodConfPoint target = configSubSampleMethodConfItem.getTarget();
								String field = target.getField();
								BeanUtil.setFieldValue(autoIngredientsTaskDetailRespVO, field, currentBusinessAssayTaskParameterData.getValue());
							}
						}
					}
				}
			}
			autoIngredientsTaskDetailRespVO.setAssayProject(m.getAssayProject());
			autoIngredientsTaskDetailRespVO.setAssayOperator(user.getUsername());
			autoIngredientsTaskDetailRespVO.setAssayOperatorName(m.getAssayOperator());
			autoIngredientsTaskDetailRespVO.setRemark(m.getRemark());
			
			return autoIngredientsTaskDetailRespVO;
		}).collect(Collectors.toList());
		return resultList;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void submitAssayResult(AutoIngredientsTaskAssayResultReqVO body) {
		
		List<BusinessAssayTaskDataDO> updateBusinessAssayTaskDataDOList = new ArrayList<>();
		List<BusinessAssayTaskParameterDataDO> updateBusinessAssayTaskParameterDataDOList = new ArrayList<>();
		List<BusinessAssayProjectDataDO> updateBusinessAssayProjectDataDOList = new ArrayList<>();
        List<BusinessAssayParameterDataDO> updateBusinessAssayParameterDataDOList = new ArrayList<>(); 
		
		//任务id
		Long taskId = body.getTaskId();
		//查询任务分配信息
		BusinessAssayTaskDO businessAssayTaskDO = businessAssayTaskMapper.selectById(taskId);
		if (QmsCommonConstant.MANUAL.equals(businessAssayTaskDO.getIngredientsWay())) {
			throw new ServiceException(1_032_001_000, "当前任务已人工配料");
		}
		if (QmsCommonConstant.SUBMITTED.equals(businessAssayTaskDO.getTaskAssayStatus())) {
			throw new ServiceException(1_032_001_000, "当前任务已提交");
		}
		
		List<AutoIngredientsTaskDetailAssayResultReqVO> sampleList = body.getSampleList();
		//获取检测任务id
		List<Long> businessAssayTaskDataIdList = sampleList.stream().map(m -> m.getId()).collect(Collectors.toList());
		List<BusinessAssayTaskDataDO> businessAssayTaskDataDOList = businessAssayTaskDataMapper.selectByIds(businessAssayTaskDataIdList);
		if (CollUtil.isEmpty(businessAssayTaskDataDOList)) {
			throw new ServiceException(1_032_001_000, "当前任务未找到分析数据");
		}
		//获取子样id列表
		List<Long> businessSubSampleIdList = businessAssayTaskDataDOList.stream().map(m -> m.getBusinessSubSampleId()).distinct().collect(Collectors.toList());
		//获取子样
		List<BusinessSubSampleDO> businessSubSampleDOList = businessSubSampleMapper.selectByIds(businessSubSampleIdList);
		//子样配置id列表
		List<Long> configSubSampleIdList = businessSubSampleDOList.stream().map(m -> m.getConfigSubSampleId()).distinct().collect(Collectors.toList());		
		//方法id列表
		List<Long> configAssayMethodIdList = businessAssayTaskDataDOList.stream().map(m -> m.getConfigAssayMethodId()).distinct().collect(Collectors.toList());
		//子样配置方法
		List<ConfigSubSampleMethodExtendRespVO> configSubSampleMethodList = configSubSampleMethodMapper.selectByConfigSubSampleIdsAndConfigAssayMethodIds(configSubSampleIdList, configAssayMethodIdList);
		
		//查询分析任务属性
		List<BusinessAssayTaskParameterDataExtendRespVO> businessAssayTaskParameterDataList = businessAssayTaskParameterDataMapper.selectExtendByBusinessAssayTaskDataIds(businessAssayTaskDataIdList);
		
		//查询检测项目
		List<BusinessAssayProjectDataExtendRespVO> businessAssayProjectDataList = businessAssayProjectDataMapper.selectByBusinessAssayTaskDataIds(businessAssayTaskDataIdList);
		List<Long> businessAssayProjectDataIdList = businessAssayProjectDataList.stream().map(m -> m.getId()).collect(Collectors.toList());
		//查询检测项目参数
		List<BusinessAssayParameterDataExtendRespVO> businessAssayParameterDataList = businessAssayParameterDataMapper.selectExtendByBusinessAssayProjectDataIds(businessAssayProjectDataIdList);
		
		for (AutoIngredientsTaskDetailAssayResultReqVO autoIngredientsTaskDetailAssayResultReqVO : sampleList) {
			//获取子样检测任务
			BusinessAssayTaskDataDO businessAssayTaskDataDO = businessAssayTaskDataDOList.stream().filter(f -> f.getId().equals(autoIngredientsTaskDetailAssayResultReqVO.getId())).findFirst().orElse(null);
			//获取子样
			BusinessSubSampleDO businessSubSampleDO = businessSubSampleDOList.stream().filter(f -> f.getId().equals(businessAssayTaskDataDO.getBusinessSubSampleId())).findFirst().orElse(null);
			
			//子样配置信息
			ConfigSubSampleMethodExtendRespVO configSubSampleMethodDO = configSubSampleMethodList.stream().filter(f -> f.getConfigSubSampleId().equals(businessSubSampleDO.getConfigSubSampleId()) && f.getConfigAssayMethodId().equals(businessAssayTaskDataDO.getConfigAssayMethodId())).findFirst().orElse(null);
			String configInfomation = configSubSampleMethodDO.getConfigInfomation();
			if (StringUtils.isNotBlank(configInfomation)) {
				ConfigSubSampleMethodConfInfo configSubSampleMethodConfInfo = JSON.parseObject(configInfomation, ConfigSubSampleMethodConfInfo.class);
				//获取上传配置
				List<ConfigSubSampleMethodConfItem> upIngredients = configSubSampleMethodConfInfo.getUpIngredients();
				for (ConfigSubSampleMethodConfItem configSubSampleMethodConfItem : upIngredients) {
					if (configSubSampleMethodConfItem.getRequired()) {
						ConfigSubSampleMethodConfPoint source = configSubSampleMethodConfItem.getSource();
						String field = source.getField();
//						System.out.println("field:" + field);
//						Field field2 = ReflectUtil.getField(autoIngredientsTaskDetailAssayResultReqVO.getClass(), field);
//						Map<String, Field> fieldMap = ReflectUtil.getFieldMap(autoIngredientsTaskDetailAssayResultReqVO.getClass());
//						Object fieldValue2 = ReflectUtil.getFieldValue(autoIngredientsTaskDetailAssayResultReqVO, fieldMap.get(field));
						Object fieldValue = BeanUtil.getFieldValue(autoIngredientsTaskDetailAssayResultReqVO, field);
						if (fieldValue == null || "/".equals(fieldValue)) {
							fieldValue = "";
						}
//						System.out.println("fieldValue:" + fieldValue);
						
						ConfigSubSampleMethodConfPoint target = configSubSampleMethodConfItem.getTarget();
						if (StringUtils.isNotBlank(target.getProject())) {//保存到检测项目参数
							List<String> projectList = Arrays.asList(target.getProject().split(","));//目标可以有多个
							for (String project : projectList) {
								BusinessAssayProjectDataExtendRespVO currentBusinessAssayProjectData = businessAssayProjectDataList.stream().filter(f -> f.getBusinessAssayTaskDataId().equals(autoIngredientsTaskDetailAssayResultReqVO.getId()) && f.getSimpleName().equals(project)).findFirst().orElse(null);
								if (currentBusinessAssayProjectData != null) {
									String parameter = target.getParameter();
									if (StringUtils.isBlank(parameter)) {
										currentBusinessAssayProjectData.setValue(fieldValue.toString());
										updateBusinessAssayProjectDataDOList.add(BeanUtils.toBean(currentBusinessAssayProjectData, BusinessAssayProjectDataDO.class));
									} else {
										BusinessAssayParameterDataExtendRespVO currentBusinessAssayParameterData = businessAssayParameterDataList.stream().filter(f -> f.getBusinessAssayProjectDataId().equals(currentBusinessAssayProjectData.getId()) && f.getParameterKey().equals(parameter)).findFirst().orElse(null);
										if (currentBusinessAssayParameterData != null) {
											currentBusinessAssayParameterData.setValue(fieldValue.toString());
											updateBusinessAssayParameterDataDOList.add(BeanUtils.toBean(currentBusinessAssayParameterData, BusinessAssayParameterDataDO.class));
										}
									}
								}
							}
						} else if (StringUtils.isNotBlank(target.getAttribute())) {//保存到分析任务属性
							BusinessAssayTaskParameterDataExtendRespVO currentBusinessAssayTaskParameterData = businessAssayTaskParameterDataList.stream().filter(f -> f.getBusinessAssayTaskDataId().equals(autoIngredientsTaskDetailAssayResultReqVO.getId()) && f.getKey().equals(target.getAttribute())).findFirst().orElse(null);
							if (currentBusinessAssayTaskParameterData != null) {
								currentBusinessAssayTaskParameterData.setValue(fieldValue.toString());
								updateBusinessAssayTaskParameterDataDOList.add(BeanUtils.toBean(currentBusinessAssayTaskParameterData, BusinessAssayTaskParameterDataDO.class));
							}
						}
					}
				}
			}
			String remark = CollUtil.join(Arrays.asList(autoIngredientsTaskDetailAssayResultReqVO.getRemark()), "、");
			
			businessAssayTaskDataDO.setRemark(remark);
			updateBusinessAssayTaskDataDOList.add(businessAssayTaskDataDO);
		}
		
		businessAssayTaskDO.setIngredientsStatus(QmsCommonConstant.ALLOW_SUBMIT);
		
		businessAssayTaskMapper.updateById(businessAssayTaskDO);
		
		if (CollUtil.isNotEmpty(updateBusinessAssayTaskDataDOList)) {
			businessAssayTaskDataMapper.updateBatch(updateBusinessAssayTaskDataDOList);
		}
		if (CollUtil.isNotEmpty(updateBusinessAssayTaskParameterDataDOList)) {
			businessAssayTaskParameterDataMapper.updateBatch(updateBusinessAssayTaskParameterDataDOList);
		}
		if (CollUtil.isNotEmpty(updateBusinessAssayProjectDataDOList)) {
			businessAssayProjectDataMapper.updateBatch(updateBusinessAssayProjectDataDOList);
		}
		if (CollUtil.isNotEmpty(updateBusinessAssayParameterDataDOList)) {
			businessAssayParameterDataMapper.updateBatch(updateBusinessAssayParameterDataDOList);
		}
		
	}

}
