package com.zt.plat.module.qms.business.bus.service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
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.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONFactory;
import com.alibaba.fastjson2.JSONObject;
import com.alibaba.fastjson2.JSONWriter;
import com.yomahub.liteflow.core.FlowExecutor;
import com.yomahub.liteflow.flow.LiteflowResponse;

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.common.util.object.BeanUtils;
import com.zt.plat.framework.mybatis.core.query.LambdaQueryWrapperX;
import com.zt.plat.framework.tenant.core.context.TenantContextHolder;
import com.zt.plat.module.qms.business.bus.controller.vo.BusinessSampleEntrustDetailExtendRespVO;
import com.zt.plat.module.qms.business.bus.controller.vo.BusinessSampleEntrustProjectExtendRespVO;
import com.zt.plat.module.qms.business.bus.controller.vo.BusinessSampleEntrustRegistrationExtendRespVO;
import com.zt.plat.module.qms.business.bus.controller.vo.BusinessSampleEntrustRegistrationSubmitReqVO;
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.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.dal.mapper.BusinessSampleAssayResultMapper;
import com.zt.plat.module.qms.business.bus.dal.mapper.BusinessSampleEntrustDetailMapper;
import com.zt.plat.module.qms.business.bus.dal.mapper.BusinessSampleEntrustProjectMapper;
import com.zt.plat.module.qms.business.bus.dal.mapper.BusinessSampleEntrustRegistrationMapper;
import com.zt.plat.module.qms.business.bus.dal.mapper.BusinessSampleEntrustUnStandardProjectMapper;
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.enums.QmsCommonConstant;

import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import lombok.extern.slf4j.Slf4j;


@Slf4j
@Service
public class SampleEntrustServiceImpl implements SampleEntrustService {

    @Resource
    private FlowExecutor flowExecutor;
	
	@Resource
	private BusinessSampleEntrustRegistrationMapper businessSampleEntrustRegistrationMapper;
	
	@Resource
	private BusinessSampleEntrustDetailMapper businessSampleEntrustDetailMapper;
	
	@Resource
	private BusinessSampleEntrustProjectMapper businessSampleEntrustProjectMapper;
	
	@Resource
	private BusinessSampleEntrustUnStandardProjectMapper businessSampleEntrustUnStandardProjectMapper;
	
	@Resource
	private BusinessSampleAssayResultMapper businessSampleAssayResultMapper;
    
	@Override
	@Transactional(rollbackFor = Exception.class)
	public LiteflowResponse create(@Valid SampleEntrustParam sampleEntrustParam) {
    	Long tenantId = TenantContextHolder.getRequiredTenantId();
		LiteflowResponse response = flowExecutor.execute2Resp("sampleEntrustChain" + tenantId, sampleEntrustParam, SampleEntrustContext.class);
	    if (!response.isSuccess()){
	    	log.error("创建委托登记失败", response.getCause());
            throw new ServiceException(1_032_100_000, response.getCause().getMessage());
        }
	    return response;
	}

	@Override
	public BusinessSampleEntrustRegistrationExtendRespVO detail(Long id) {
		BusinessSampleEntrustRegistrationDO businessSampleEntrustRegistrationDO = businessSampleEntrustRegistrationMapper.selectById(id);

		BusinessSampleEntrustRegistrationExtendRespVO businessSampleEntrustRegistrationExtendRespVO = BeanUtil.copyProperties(businessSampleEntrustRegistrationDO, BusinessSampleEntrustRegistrationExtendRespVO.class);
		
		List<BusinessSampleEntrustDetailExtendRespVO> sampleEntrustDetailExtendRespVOList = new ArrayList<>();
		List<BusinessSampleEntrustDetailDO> sampleEntrustDetailList = businessSampleEntrustDetailMapper.selectByBusinessSampleEntrustRegistrationId(id);
		BusinessSampleEntrustDetailExtendRespVO businessSampleEntrustDetailExtendRespVO = null;
		for (BusinessSampleEntrustDetailDO businessSampleEntrustDetailDO : sampleEntrustDetailList) {
			businessSampleEntrustDetailExtendRespVO = BeanUtils.toBean(businessSampleEntrustDetailDO, BusinessSampleEntrustDetailExtendRespVO.class);
			
			List<BusinessSampleEntrustProjectExtendRespVO> businessSampleEntrustProjectExtendRespVOList = businessSampleEntrustProjectMapper.selectByBusinessSampleEntrustDetailId(businessSampleEntrustDetailDO.getId());
			
			businessSampleEntrustDetailExtendRespVO.setSampleEntrustDetailProjectList(businessSampleEntrustProjectExtendRespVOList);
			
			sampleEntrustDetailExtendRespVOList.add(businessSampleEntrustDetailExtendRespVO);
		}
		businessSampleEntrustRegistrationExtendRespVO.setSampleEntrustDetailList(sampleEntrustDetailExtendRespVOList);
		
		return businessSampleEntrustRegistrationExtendRespVO;
	}
	
	@Override
	public JSONObject reportDetail(Long id) {
		JSONWriter.Context context = JSONFactory.createWriteContext();
		context.setDateFormat("yyyy-MM-dd HH:mm:ss");
		
		JSONObject result = new JSONObject();
		BusinessSampleEntrustRegistrationDO businessSampleEntrustRegistrationDO = businessSampleEntrustRegistrationMapper.selectById(id);
		String externalInfomation = businessSampleEntrustRegistrationDO.getExternalInfomation();
		JSONObject extInfJsonObject = new JSONObject();
		if (StringUtils.isNotBlank(externalInfomation)) {
			extInfJsonObject = JSON.parseObject(externalInfomation);
		}
		
		String jsonString = JSON.toJSONString(businessSampleEntrustRegistrationDO, context);
		JSONObject sampleEntrustRegistration = JSON.parseObject(jsonString);
		extInfJsonObject.forEach((key, value) -> {
			sampleEntrustRegistration.put(key, value);
		});
		
		List<BusinessSampleEntrustDetailExtendRespVO> sampleEntrustDetailExtendRespVOList = businessSampleEntrustDetailMapper.selectExtendByBusinessSampleEntrustRegistrationId(id);
		for (BusinessSampleEntrustDetailExtendRespVO businessSampleEntrustDetailExtendRespVO : sampleEntrustDetailExtendRespVOList) {
			List<BusinessSampleEntrustProjectExtendRespVO> businessSampleEntrustProjectExtendRespVOList = businessSampleEntrustProjectMapper.selectByBusinessSampleEntrustDetailId(businessSampleEntrustDetailExtendRespVO.getId());
			
			businessSampleEntrustDetailExtendRespVO.setSampleEntrustDetailProjectList(businessSampleEntrustProjectExtendRespVOList);
		}
		//样品类型分组统计
		Map<String, Long> groupMap = sampleEntrustDetailExtendRespVOList.stream().collect(Collectors.groupingBy(BusinessSampleEntrustDetailExtendRespVO::getSampleTypeDictionaryBusinessKey, Collectors.counting()));
		for (Map.Entry<String, Long> entry : groupMap.entrySet()) {
			String key = entry.getKey();
			Long val = entry.getValue();
			sampleEntrustRegistration.put(key + "Count", val);
		}

		JSONArray jsonArray = new JSONArray();
		jsonArray.add(sampleEntrustRegistration);

		String sampleEntrustDetailJsonString = JSON.toJSONString(sampleEntrustDetailExtendRespVOList, context);
		result.put("sampleEntrustRegistration", jsonArray);
		result.put("sampleEntrustDetail", JSON.parseArray(sampleEntrustDetailJsonString));
		return result;
	}
	
	
	@Override
	@Transactional(rollbackFor = Exception.class)
	public LiteflowResponse update(@Valid SampleEntrustParam sampleEntrustParam) {
    	Long tenantId = TenantContextHolder.getRequiredTenantId();
    	LiteflowResponse response = flowExecutor.execute2Resp("sampleEntrustChain" + tenantId, sampleEntrustParam, SampleEntrustContext.class);
	    if (!response.isSuccess()){
	    	log.error("更新委托登记失败", response.getCause());
            throw new ServiceException(1_032_100_000, response.getCause().getMessage());
	    }
	    return response;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void delete(Long id) {
		if (id == null) {
			throw new ServiceException(1_032_100_000, "委托登记id不允许为空");
		}
		if (businessSampleEntrustRegistrationMapper.selectById(id) == null) {
			throw new ServiceException(1_032_100_000, "委托登记业务不存在");
		}
		
		List<BusinessSampleEntrustDetailDO> sampleEntrustDetailList = businessSampleEntrustDetailMapper.selectList(new LambdaQueryWrapperX<BusinessSampleEntrustDetailDO>().eq(BusinessSampleEntrustDetailDO::getBusinessSampleEntrustRegistrationId, id));
		if (CollUtil.isNotEmpty(sampleEntrustDetailList)) {
			List<Long> sampleEntrustDetailIdList = sampleEntrustDetailList.stream().map(m -> m.getId()).collect(Collectors.toList());
			List<BusinessSampleEntrustProjectDO> sampleEntrustProjectList = businessSampleEntrustProjectMapper.selectList(new LambdaQueryWrapperX<BusinessSampleEntrustProjectDO>().in(BusinessSampleEntrustProjectDO::getBusinessSampleEntrustDetailId, sampleEntrustDetailIdList));
			if (CollUtil.isNotEmpty(sampleEntrustProjectList)) {
				List<Long> sampleEntrustProjectIdList = sampleEntrustProjectList.stream().map(m -> m.getId()).collect(Collectors.toList());
				//删除样品对应的检验项目
				businessSampleEntrustProjectMapper.deleteByIds(sampleEntrustProjectIdList);
			}
			List<BusinessSampleAssayResultDO> sampleAssayResultList = businessSampleAssayResultMapper.selectList(new LambdaQueryWrapperX<BusinessSampleAssayResultDO>().in(BusinessSampleAssayResultDO::getBusinessSampleEntrustDetailId, sampleEntrustDetailIdList));
			if (CollUtil.isNotEmpty(sampleAssayResultList)) {
				List<Long> sampleAssayResultIdList = sampleAssayResultList.stream().map(m -> m.getId()).collect(Collectors.toList());
				//删除来样品位
				businessSampleAssayResultMapper.deleteByIds(sampleAssayResultIdList);
			}
			
			//删除委托登记明细
			businessSampleEntrustDetailMapper.deleteByIds(sampleEntrustDetailIdList);
		}
		//删除委托登记
		businessSampleEntrustRegistrationMapper.deleteById(id);
		
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void deleteList(List<Long> ids) {
		if (ids == null || ids.size() <= 0) {
			throw new ServiceException(1_032_100_000, "委托登记id列表不允许为空");
		}
		List<BusinessSampleEntrustRegistrationDO> sampleEntrustRegistrationList = businessSampleEntrustRegistrationMapper.selectByIds(ids);
		if (CollUtil.isEmpty(sampleEntrustRegistrationList) || sampleEntrustRegistrationList.size() != ids.size()) {
			throw new ServiceException(1_032_100_000, "委托登记业务不存在");
		}

		List<BusinessSampleEntrustDetailDO> sampleEntrustDetailList = businessSampleEntrustDetailMapper.selectList(new LambdaQueryWrapperX<BusinessSampleEntrustDetailDO>().in(BusinessSampleEntrustDetailDO::getBusinessSampleEntrustRegistrationId, ids));
		if (CollUtil.isNotEmpty(sampleEntrustDetailList)) {
			List<Long> sampleEntrustDetailIdList = sampleEntrustDetailList.stream().map(m -> m.getId()).collect(Collectors.toList());
			List<BusinessSampleEntrustProjectDO> sampleEntrustProjectList = businessSampleEntrustProjectMapper.selectList(new LambdaQueryWrapperX<BusinessSampleEntrustProjectDO>().in(BusinessSampleEntrustProjectDO::getBusinessSampleEntrustDetailId, sampleEntrustDetailIdList));
			if (CollUtil.isNotEmpty(sampleEntrustProjectList)) {
				List<Long> sampleEntrustProjectIdList = sampleEntrustProjectList.stream().map(m -> m.getId()).collect(Collectors.toList());
				//删除样品对应的检验项目
				businessSampleEntrustProjectMapper.deleteByIds(sampleEntrustProjectIdList);
			}
			List<BusinessSampleAssayResultDO> sampleAssayResultList = businessSampleAssayResultMapper.selectList(new LambdaQueryWrapperX<BusinessSampleAssayResultDO>().in(BusinessSampleAssayResultDO::getBusinessSampleEntrustDetailId, sampleEntrustDetailIdList));
			if (CollUtil.isNotEmpty(sampleAssayResultList)) {
				List<Long> sampleAssayResultIdList = sampleAssayResultList.stream().map(m -> m.getId()).collect(Collectors.toList());
				//删除来样品位
				businessSampleAssayResultMapper.deleteByIds(sampleAssayResultIdList);
			}
			
			//删除委托登记明细
			businessSampleEntrustDetailMapper.deleteByIds(sampleEntrustDetailIdList);
		}
		//删除委托登记
		businessSampleEntrustRegistrationMapper.deleteByIds(ids);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void submit(@Valid BusinessSampleEntrustRegistrationSubmitReqVO req) {
    	Long tenantId = TenantContextHolder.getRequiredTenantId();
    	BusinessSampleEntrustRegistrationDO sampleEntrustRegistration = businessSampleEntrustRegistrationMapper.selectById(req.getId());
    	if (sampleEntrustRegistration == null) {
    		throw new ServiceException(1_032_100_000, "委托登记业务不存在");
		}
    	SampleEntrustParam sampleEntrustParam = BeanUtils.toBean(sampleEntrustRegistration, SampleEntrustParam.class);
    	sampleEntrustParam.setIsReceiveSample(req.getIsReceiveSample());
    	sampleEntrustParam.setIsSendSample(req.getIsSendSample());

		List<BusinessSampleEntrustDetailDO> sampleEntrustDetailDOList = businessSampleEntrustDetailMapper.selectByBusinessSampleEntrustRegistrationId(req.getId());
    	if (CollUtil.isNotEmpty(sampleEntrustDetailDOList)) {
    		
			List<Long> sampleEntrustDetailIdList = sampleEntrustDetailDOList.stream().map(m -> m.getId()).collect(Collectors.toList());
			
			List<BusinessSampleEntrustProjectDO> sampleEntrustProjectDOList = businessSampleEntrustProjectMapper.selectByBusinessSampleEntrustDetailIds(sampleEntrustDetailIdList);
			
			List<BusinessSampleEntrustUnStandardProjectDO> sampleEntrustUnStandardProjectDOList = businessSampleEntrustUnStandardProjectMapper.selectByBusinessSampleEntrustDetailIds(sampleEntrustDetailIdList);
			
    		List<SampleEntrustDetail> sampleEntrustDetailList = BeanUtils.toBean(sampleEntrustDetailDOList, SampleEntrustDetail.class);
    		for (SampleEntrustDetail sampleEntrustDetail : sampleEntrustDetailList) {

				List<SampleEntrustDetailProject> sampleEntrustDetailProjectList = null;
    			if (sampleEntrustRegistration.getIsMaterialAssayStandard().equals(QmsCommonConstant.YES)) {
        			List<BusinessSampleEntrustProjectDO> entrustProjectDOList = sampleEntrustProjectDOList.stream().filter(f -> f.getBusinessSampleEntrustDetailId().equals(sampleEntrustDetail.getId())).collect(Collectors.toList());
        			sampleEntrustDetailProjectList = BeanUtils.toBean(entrustProjectDOList, SampleEntrustDetailProject.class);
				} else {
					List<BusinessSampleEntrustUnStandardProjectDO> entrustProjectDOList = sampleEntrustUnStandardProjectDOList.stream().filter(f -> f.getBusinessSampleEntrustDetailId().equals(sampleEntrustDetail.getId())).collect(Collectors.toList());
					sampleEntrustDetailProjectList = BeanUtils.toBean(entrustProjectDOList, SampleEntrustDetailProject.class);
				}
				
				sampleEntrustDetail.setSampleEntrustDetailProjectList(sampleEntrustDetailProjectList);
			}
    		
    		sampleEntrustParam.setSampleEntrustDetailList(sampleEntrustDetailList);
    		
		}
		
    	LiteflowResponse response = flowExecutor.execute2Resp("sampleEntrustSubmitChain" + tenantId, sampleEntrustParam, SampleEntrustContext.class);
	    if (!response.isSuccess()){
	    	log.error("提交委托登记失败", response.getCause());
	    	 response.getCause().printStackTrace();
	    	throw new ServiceException(1_032_100_000, response.getCause().getMessage());
	    }
	}

	

}
