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

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

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.yomahub.liteflow.core.FlowExecutor;
import com.yomahub.liteflow.flow.LiteflowResponse;

import cn.hutool.core.collection.CollUtil;
import com.zt.plat.framework.common.exception.ServiceException;
import com.zt.plat.framework.common.pojo.CommonResult;
import com.zt.plat.framework.mybatis.core.query.LambdaQueryWrapperX;
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.BusinessAssayTaskDO;
import com.zt.plat.module.qms.business.bus.dal.dataobject.BusinessAssayTaskDataDO;
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.liteflow.param.SampleTaskAssignManualParam;
import com.zt.plat.module.qms.business.bus.liteflow.param.SampleTaskAssignMethodParam;
import com.zt.plat.module.qms.business.bus.liteflow.param.SampleTaskAssignSampleParam;
import com.zt.plat.module.qms.business.bus.liteflow.slot.SampleTaskAssignContext;
import com.zt.plat.module.qms.enums.QmsCommonConstant;
import com.zt.plat.module.system.api.dept.DeptApi;
import com.zt.plat.module.system.api.dept.dto.DeptRespDTO;
import com.zt.plat.module.system.api.user.AdminUserApi;
import com.zt.plat.module.system.api.user.dto.AdminUserRespDTO;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@Service
public class SampleTaskAssignServiceImpl implements SampleTaskAssignService {

    @Resource
    private FlowExecutor flowExecutor;
    
    @Resource
    private AdminUserApi adminUserApi;
    
    @Resource
    private DeptApi deptApi; 
    
    @Resource
    private BusinessAssayTaskMapper businessAssayTaskMapper;
    
    @Resource
    private BusinessAssayTaskDetailMapper businessAssayTaskDetailMapper;
    
    @Resource
    private BusinessAssayTaskDataMapper businessAssayTaskDataMapper;

	@Override
	public List<AdminUserRespDTO> getAssignUserList() {
		//当前登录用户
		LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
		Long visitDeptId = loginUser.getVisitDeptId();
		//当前部门及子部门id
		List<Long> deptIdList = new ArrayList<>();
		deptIdList.add(visitDeptId);
		//获取子部门
		CommonResult<List<DeptRespDTO>> childDeptListResult = deptApi.getChildDeptList(visitDeptId);
		if (childDeptListResult.isSuccess()) {
			List<DeptRespDTO> childDeptList = childDeptListResult.getData();
			if (CollUtil.isNotEmpty(childDeptList)) {
				List<Long> childDeptIdList = childDeptList.stream().map(m -> m.getId()).collect(Collectors.toList());
				deptIdList.addAll(childDeptIdList);
			}
		}		
		CommonResult<List<AdminUserRespDTO>> userListResult = adminUserApi.getUserListByDeptIds(deptIdList);
		return userListResult.getCheckedData();
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public LiteflowResponse methodAssign(SampleTaskAssignMethodParam param) {
		if (param.getConfigAssayMethodId() == null) {
			throw new ServiceException(500, "无分析方法");
		}
		if (CollUtil.isEmpty(param.getAssignAssayUserList())) {
			throw new ServiceException(500, "无任务分配人员");
		}
    	Long tenantId = TenantContextHolder.getRequiredTenantId();
    	LiteflowResponse response = flowExecutor.execute2Resp("sampleTaskAssignChain" + tenantId, param, SampleTaskAssignContext.class);
	    if (!response.isSuccess()){
	    	log.error("按方法分配任务失败", response.getCause());
            throw new ServiceException(500, response.getCause().getMessage());
	    }
	    return response;		
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public LiteflowResponse sampleAssign(SampleTaskAssignSampleParam param) {
		if (param.getAssignAssayUser() == null) {
			throw new ServiceException(500, "无任务分配人员");
		}
		if (CollUtil.isEmpty(param.getAssignSampleIdList())) {
			throw new ServiceException(500, "无任务分配样品");
		}
    	Long tenantId = TenantContextHolder.getRequiredTenantId();
    	LiteflowResponse response = flowExecutor.execute2Resp("sampleTaskAssignChain" + tenantId, param, SampleTaskAssignContext.class);
	    if (!response.isSuccess()){
	    	log.error("按样品分配任务失败", response.getCause());
            throw new ServiceException(500, response.getCause().getMessage());
	    }
	    return response;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public LiteflowResponse manualAssign(SampleTaskAssignManualParam param) {
		if (param.getAssignAssayUser() == null) {
			throw new ServiceException(500, "无任务分配人员");
		}
		if (CollUtil.isEmpty(param.getAssayTaskDataIdList())) {
			throw new ServiceException(500, "无分配的检测任务");
		}
    	Long tenantId = TenantContextHolder.getRequiredTenantId();
    	LiteflowResponse response = flowExecutor.execute2Resp("sampleTaskAssignChain" + tenantId, param, SampleTaskAssignContext.class);
	    if (!response.isSuccess()){
	    	log.error("手动分配任务失败", response.getCause());
            throw new ServiceException(500, response.getCause().getMessage());
	    }
	    return response;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void submitAssign(Long id) {
		BusinessAssayTaskDO businessAssayTaskDO = businessAssayTaskMapper.selectById(id);
		businessAssayTaskDO.setTaskAssignStatus(QmsCommonConstant.SUBMITTED);
		businessAssayTaskDO.setTaskAssignSubmitTime(LocalDateTime.now());
		businessAssayTaskMapper.updateById(businessAssayTaskDO);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void voidAssign(Long id) {
		BusinessAssayTaskDO businessAssayTaskDO = businessAssayTaskMapper.selectById(id);
		if (QmsCommonConstant.SUBMITTED.equals(businessAssayTaskDO.getTaskAssignStatus())) {
			throw new ServiceException(500, "任务已提交，不允许作废");
		}
		businessAssayTaskDO.setTaskAssignStatus(QmsCommonConstant.VOID);
		
	    List<BusinessAssayTaskDataDO> businessAssayTaskDataDOList = businessAssayTaskDataMapper.selectList(new LambdaQueryWrapperX<BusinessAssayTaskDataDO>().eq(BusinessAssayTaskDataDO::getBusinessAssayTaskId, businessAssayTaskDO.getId()));
	    for (BusinessAssayTaskDataDO businessAssayTaskDataDO : businessAssayTaskDataDOList) {
	    	businessAssayTaskDataDO.setAssayOperator(null);
	    	businessAssayTaskDataDO.setAssignTaskTime(null);
	    	businessAssayTaskDataDO.setIsAssignTasked(0);
		}
	    businessAssayTaskMapper.updateById(businessAssayTaskDO);
	    businessAssayTaskDataMapper.updateBatch(businessAssayTaskDataDOList);
	}
}
