package org.jeecg.modules.stm.rectify.assin.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
  
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.util.SpringContextUtils;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.common.system.vo.SelectTreeModel;
import org.jeecg.modules.stm.problem.entity.StProblem;
import org.jeecg.modules.stm.problem.service.IStProblemService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.jeecg.modules.stm.project.create.entity.StProjectCre;
import org.jeecg.modules.stm.project.create.service.IStProjectCreService;
import org.jeecg.modules.stm.project.execpro.entity.StProjectExecPro;
import org.jeecg.modules.stm.project.execpro.service.IStProjectExecProService;
import org.jeecg.modules.stm.rectify.assin.entity.StProblemTaskAssin;
import org.jeecg.modules.stm.rectify.assin.mapper.StProblemTaskAssinMapper;
import org.jeecg.modules.stm.rectify.assin.service.IStProblemTaskAssinService;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.util.*;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.jeecg.modules.stm.rectify.assin.vo.BatchFpVo;
import org.jeecg.modules.stm.rectify.assin.vo.ProjectImportAssinVo;
import org.jeecg.modules.stm.rectify.plan.entity.StRectifyPlan;
import org.jeecg.modules.stm.rectify.plan.service.IStRectifyPlanService;
import org.jeecg.modules.stm.utils.UserUtil;

/**
 * @Description: 任务分配
 * @Author: jeecg-boot
 * @Date:   2023-07-21
 * @Version: V1.0
 */
@Service
public class StProblemTaskAssinServiceImpl extends ServiceImpl<StProblemTaskAssinMapper, StProblemTaskAssin> implements IStProblemTaskAssinService {

    @Autowired
    private IStProblemService iStProblemService;

    @Autowired
    private IStProjectCreService iStProjectCreService;

	@Override
	public void addStProblemTaskAssin(StProblemTaskAssin stProblemTaskAssin) {
	    if("2".equals(stProblemTaskAssin.getProblemSourceFlag())){
            stProblemTaskAssin.setProblemSource("专项检查");
        }
	    String userCode = UserUtil.getUserCode();
	    stProblemTaskAssin.setCreatedUser(userCode);
        stProblemTaskAssin.setUpdatedUser(userCode);
	   //新增时设置hasChild为0
	    stProblemTaskAssin.setHasChild(IStProblemTaskAssinService.NOCHILD);
		if(oConvertUtils.isEmpty(stProblemTaskAssin.getPid())){
			stProblemTaskAssin.setPid(Integer.valueOf(IStProblemTaskAssinService.ROOT_PID_VALUE));
		}else{
			//如果当前节点父ID不为空 则设置父节点的hasChildren 为1
			StProblemTaskAssin parent = baseMapper.selectById(stProblemTaskAssin.getPid());
			if(parent!=null && !"1".equals(parent.getHasChild())){
				parent.setHasChild("1");
				baseMapper.updateById(parent);
			}
		}
        checkLastTime(stProblemTaskAssin);
		baseMapper.insert(stProblemTaskAssin);
	}

	private void checkLastTime(StProblemTaskAssin stProblemTaskAssin){
        if(!ROOT_PID_VALUE.equals(stProblemTaskAssin.getPid().toString())) {
            // 校验主任务时间
            QueryWrapper<StProblemTaskAssin> queryWrapperParent = new QueryWrapper<StProblemTaskAssin>();
            queryWrapperParent.eq("ID", stProblemTaskAssin.getPid());
            List<StProblemTaskAssin> parentList = this.list(queryWrapperParent);
            if (!CollectionUtils.isEmpty(parentList)) {
                StProblemTaskAssin stProblemTaskAssin1 = parentList.get(0);
                Date endTime = stProblemTaskAssin1.getLateFinishTime();
                Date cEndTime = stProblemTaskAssin.getLateFinishTime();
                // 如果子问题最晚完成时间大于父项
                if (cEndTime.after(endTime)) {
                    throw new JeecgBootException("子问题最晚完成时间不能大于父问题最晚完成时间!");
                }
            }
        }
    }

	@Override
	public void updateStProblemTaskAssin(StProblemTaskAssin stProblemTaskAssin) {
		StProblemTaskAssin entity = this.getById(stProblemTaskAssin.getId());
		if(entity==null) {
			throw new JeecgBootException("未找到对应实体");
		}
        checkLastTime(stProblemTaskAssin);
        String userCode = UserUtil.getUserCode();
        stProblemTaskAssin.setUpdatedUser(userCode);
		String old_pid = entity.getPid().toString();
		String new_pid = stProblemTaskAssin.getPid().toString();
		if(!old_pid.equals(new_pid)) {
			updateOldParentNode(old_pid);
			if(oConvertUtils.isEmpty(new_pid)){
				stProblemTaskAssin.setPid(Integer.valueOf(IStProblemTaskAssinService.ROOT_PID_VALUE));
			}
			if(!IStProblemTaskAssinService.ROOT_PID_VALUE.equals(stProblemTaskAssin.getPid())) {
				baseMapper.updateTreeNodeStatus(stProblemTaskAssin.getPid().toString(), IStProblemTaskAssinService.HASCHILD);
			}
		}
		baseMapper.updateById(stProblemTaskAssin);
        if ("1".equals(stProblemTaskAssin.getReceiveStatus()) && "1".equals(stProblemTaskAssin.getIsReceive())) {
            // 任务接受处理
            IStRectifyPlanService iStRectifyPlanService = (IStRectifyPlanService) SpringContextUtils.getBean(IStRectifyPlanService.class);
            StRectifyPlan stRectifyPlan = new StRectifyPlan();
            stRectifyPlan.setProblemTaskId(stProblemTaskAssin.getId());
            stRectifyPlan.setHeadCode(stProblemTaskAssin.getHeadCode());
            stRectifyPlan.setHeadDepCode(stProblemTaskAssin.getHeadDepCode());
            stRectifyPlan.setCreatedUser(userCode);
            stRectifyPlan.setUpdatedUser(userCode);
            iStRectifyPlanService.save(stRectifyPlan);
        }
        // 校验父状态
        if(!ROOT_PID_VALUE.equals(stProblemTaskAssin.getPid().toString())) {
            QueryWrapper<StProblemTaskAssin> queryWrapper = new QueryWrapper<StProblemTaskAssin>();
            queryWrapper.eq("PID",stProblemTaskAssin.getPid());
            long pCount = baseMapper.selectCount(queryWrapper);
            queryWrapper.eq("ASSIN_STATUS","1");
            long assinCount = baseMapper.selectCount(queryWrapper);
            queryWrapper.eq("RECEIVE_STATUS","1");
            long reciveCount = baseMapper.selectCount(queryWrapper);
            StProblemTaskAssin problemTaskAssin = new StProblemTaskAssin();
            problemTaskAssin.setId(stProblemTaskAssin.getPid());
            if(pCount == assinCount) {
                problemTaskAssin.setAssinStatus("1");
            }
            if(pCount == reciveCount){
                problemTaskAssin.setReceiveStatus("1");
            }
            baseMapper.updateById(problemTaskAssin);
        }
	}
	
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void deleteStProblemTaskAssin(String id) throws JeecgBootException {
		//查询选中节点下所有子节点一并删除
        id = this.queryTreeChildIds(id);
        if(id.indexOf(",")>0) {
            StringBuffer sb = new StringBuffer();
            String[] idArr = id.split(",");
            for (String idVal : idArr) {
                if(idVal != null){
                    StProblemTaskAssin stProblemTaskAssin = this.getById(idVal);
                    String pidVal = stProblemTaskAssin.getPid().toString();
                    //查询此节点上一级是否还有其他子节点
                    List<StProblemTaskAssin> dataList = baseMapper.selectList(new QueryWrapper<StProblemTaskAssin>().eq("pid", pidVal).notIn("id",Arrays.asList(idArr)));
                    boolean flag = (dataList == null || dataList.size() == 0) && !Arrays.asList(idArr).contains(pidVal) && !sb.toString().contains(pidVal);
                    if(flag){
                        //如果当前节点原本有子节点 现在木有了，更新状态
                        sb.append(pidVal).append(",");
                    }
                }
            }
            //批量删除节点
            baseMapper.deleteBatchIds(Arrays.asList(idArr));
            //修改已无子节点的标识
            String[] pidArr = sb.toString().split(",");
            for(String pid : pidArr){
                this.updateOldParentNode(pid);
            }
        }else{
            StProblemTaskAssin stProblemTaskAssin = this.getById(id);
            if(stProblemTaskAssin==null) {
                throw new JeecgBootException("未找到对应实体");
            }
            updateOldParentNode(stProblemTaskAssin.getPid().toString());
            baseMapper.deleteById(id);
        }
	}
	
	@Override
    public List<StProblemTaskAssin> queryTreeListNoPage(QueryWrapper<StProblemTaskAssin> queryWrapper) {
        List<StProblemTaskAssin> dataList = baseMapper.selectList(queryWrapper);
        List<StProblemTaskAssin> mapList = new ArrayList<>();
        for(StProblemTaskAssin data : dataList){
            String pidVal = data.getPid().toString();
            //递归查询子节点的根节点
            if(pidVal != null && !IStProblemTaskAssinService.NOCHILD.equals(pidVal)){
                StProblemTaskAssin rootVal = this.getTreeRoot(pidVal);
                if(rootVal != null && !mapList.contains(rootVal)){
                    mapList.add(rootVal);
                }
            }else{
                if(!mapList.contains(data)){
                    mapList.add(data);
                }
            }
        }
        return mapList;
    }

    @Override
    public List<SelectTreeModel> queryListByCode(String parentCode) {
        String pid = ROOT_PID_VALUE;
        if (oConvertUtils.isNotEmpty(parentCode)) {
            LambdaQueryWrapper<StProblemTaskAssin> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(StProblemTaskAssin::getPid, parentCode);
            List<StProblemTaskAssin> list = baseMapper.selectList(queryWrapper);
            if (list == null || list.size() == 0) {
                throw new JeecgBootException("该编码【" + parentCode + "】不存在，请核实!");
            }
            if (list.size() > 1) {
                throw new JeecgBootException("该编码【" + parentCode + "】存在多个，请核实!");
            }
            pid = list.get(0).getId().toString();
        }
        return baseMapper.queryListByPid(pid, null);
    }

    @Override
    public List<SelectTreeModel> queryListByPid(String pid) {
        if (oConvertUtils.isEmpty(pid)) {
            pid = ROOT_PID_VALUE;
        }
        String userCode = UserUtil.getUserCode();
        List<SelectTreeModel> datas = baseMapper.queryListByPid(pid, null);
        return datas.stream().filter(selectTreeModel -> baseMapper.selectCount(new QueryWrapper<StProblemTaskAssin>().
                eq("id",selectTreeModel.getKey()).
                and(wrapper->wrapper.eq("CREATED_USER",userCode).or().eq("HEAD_CODE",userCode)))>0).collect(Collectors.toList());

    }

    /**
     * 批量分配
     * @param batchFpVo
     */
    @Override
    public void batchEditFp(BatchFpVo batchFpVo) {
        List<Serializable> ids = batchFpVo.getIds();
        List<StProblemTaskAssin> stProblemTaskAssinList =  baseMapper.selectBatchIds(ids);
        long count = stProblemTaskAssinList.stream().filter(stProblemTaskAssin -> "1".equals(stProblemTaskAssin.getHasChild())).count();
        if(count>0){
            throw new JeecgBootException("任务存在父级，请重新选择");
        }
        count = stProblemTaskAssinList.stream().filter(stProblemTaskAssin ->
                StringUtils.isEmpty(stProblemTaskAssin.getSeverity())).count();
        if(count>0){
            throw new JeecgBootException("请修改选择严重程度");
        }
        count = stProblemTaskAssinList.stream().filter(stProblemTaskAssin ->
                StringUtils.isEmpty(stProblemTaskAssin.getPriorityFlag())).count();
        if(count>0){
            throw new JeecgBootException("请修改选择优先级");
        }
        count = stProblemTaskAssinList.stream().filter(stProblemTaskAssin ->
                ObjectUtils.isEmpty(stProblemTaskAssin.getLateFinishTime())).count();
        if(count>0){
            throw new JeecgBootException("请修改选择最晚完成时间");
        }
        count = stProblemTaskAssinList.stream().filter(stProblemTaskAssin ->
                "1".equals(stProblemTaskAssin.getAssinStatus())&&"1".equals(stProblemTaskAssin.getReceiveStatus())).count();
        if(count>0){
            throw new JeecgBootException("问题项中有已经接收的任务，无法重新分配，请重新选择");
        }
        String headCode = batchFpVo.getHeadCode();
        String headDepCode = batchFpVo.getHeadDepCode();
        String userCode = UserUtil.getUserCode();
        for(StProblemTaskAssin stProblemTaskAssin:stProblemTaskAssinList){
            StProblemTaskAssin stProblemTaskAssin1 = new StProblemTaskAssin();
            stProblemTaskAssin1.setId(stProblemTaskAssin.getId());
            stProblemTaskAssin1.setHeadCode(headCode);
            stProblemTaskAssin1.setHeadDepCode(headDepCode);
            stProblemTaskAssin1.setUpdatedUser(userCode);
            stProblemTaskAssin1.setPid(stProblemTaskAssin.getPid());
            stProblemTaskAssin1.setAssinStatus("1");
            stProblemTaskAssin1.setReceiveStatus("0");
            baseMapper.updateById(stProblemTaskAssin1);
        }
    }

    @Override
    public void projectImport(ProjectImportAssinVo projectImportAssinVo){
        Integer projectCreId = projectImportAssinVo.getProjectCreId();
        if(projectCreId==null){
            throw new JeecgBootException("请选择项目");
        }
        StProjectCre stProjectCre = iStProjectCreService.getById(projectCreId);
        String projectName = "";
        if(stProjectCre!=null){
            projectName = stProjectCre.getProjectName();
        }
        List<Serializable> ids = projectImportAssinVo.getIds();
        if(CollectionUtils.isEmpty(ids)){
            throw new JeecgBootException("请选择问题");
        }
        String userCode = UserUtil.getUserCode();
        StProblemTaskAssin stProblemTaskAssin = new StProblemTaskAssin();
        stProblemTaskAssin.setProblemSourceFlag("0");
        stProblemTaskAssin.setProblemSource(projectName);
        stProblemTaskAssin.setProjectNo(String.valueOf(projectCreId));
        stProblemTaskAssin.setAssinStatus("0");
        stProblemTaskAssin.setHasChild("0");
        stProblemTaskAssin.setCreatedUser(userCode);
        stProblemTaskAssin.setCreatedUser(userCode);
        IStProjectExecProService iStProjectExecProService = SpringContextUtils.getBean(IStProjectExecProService.class);
        for(Serializable id :ids) {
            StProjectExecPro execPro = iStProjectExecProService.getById(id);
            if(execPro==null||execPro.getId()==null){
                continue;
            }
            stProblemTaskAssin.setId(null);
            stProblemTaskAssin.setActNo(String.valueOf(id));
            stProblemTaskAssin.setProblemItem(execPro.getProblemTitle());
            stProblemTaskAssin.setProblemDes(execPro.getProblemContent());
            this.save(stProblemTaskAssin);
        }
    }

    @Override
    public void importProblemAssin(List<Serializable> ids) {
        if(CollectionUtils.isEmpty(ids)){
            throw new JeecgBootException("请选择问题");
        }
        String userCode = UserUtil.getUserCode();
        StProblemTaskAssin stProblemTaskAssin = new StProblemTaskAssin();
        stProblemTaskAssin.setProblemSourceFlag("1");
        stProblemTaskAssin.setProblemSource("问题库");
        stProblemTaskAssin.setAssinStatus("0");
        stProblemTaskAssin.setHasChild("0");
        stProblemTaskAssin.setCreatedUser(userCode);
        stProblemTaskAssin.setCreatedUser(userCode);
        for(Serializable id :ids) {
            StProblem stProblem = iStProblemService.getById(id);
            stProblemTaskAssin.setId(null);
            stProblemTaskAssin.setActNo(stProblem.getCaNo());
            stProblemTaskAssin.setProblemItem(stProblem.getProblemItem());
            stProblemTaskAssin.setProblemDes(stProblem.getProblemExample());
            this.save(stProblemTaskAssin);
        }
    }

    /**
	 * 根据所传pid查询旧的父级节点的子节点并修改相应状态值
	 * @param pid
	 */
	private void updateOldParentNode(String pid) {
		if(!IStProblemTaskAssinService.ROOT_PID_VALUE.equals(pid)) {
			Long count = baseMapper.selectCount(new QueryWrapper<StProblemTaskAssin>().eq("pid", pid));
			if(count==null || count<=1) {
				baseMapper.updateTreeNodeStatus(pid, IStProblemTaskAssinService.NOCHILD);
			}
		}
	}

	/**
     * 递归查询节点的根节点
     * @param pidVal
     * @return
     */
    private StProblemTaskAssin getTreeRoot(String pidVal){
        StProblemTaskAssin data =  baseMapper.selectById(pidVal);
        if(data != null && !IStProblemTaskAssinService.ROOT_PID_VALUE.equals(data.getPid())){
            return this.getTreeRoot(data.getPid().toString());
        }else{
            return data;
        }
    }

    /**
     * 根据id查询所有子节点id
     * @param ids
     * @return
     */
    private String queryTreeChildIds(String ids) {
        //获取id数组
        String[] idArr = ids.split(",");
        StringBuffer sb = new StringBuffer();
        for (String pidVal : idArr) {
            if(pidVal != null){
                if(!sb.toString().contains(pidVal)){
                    if(sb.toString().length() > 0){
                        sb.append(",");
                    }
                    sb.append(pidVal);
                    this.getTreeChildIds(pidVal,sb);
                }
            }
        }
        return sb.toString();
    }

    /**
     * 递归查询所有子节点
     * @param pidVal
     * @param sb
     * @return
     */
    private StringBuffer getTreeChildIds(String pidVal,StringBuffer sb){
        List<StProblemTaskAssin> dataList = baseMapper.selectList(new QueryWrapper<StProblemTaskAssin>().eq("pid", pidVal));
        if(dataList != null && dataList.size()>0){
            for(StProblemTaskAssin tree : dataList) {
                if(!sb.toString().contains(tree.getId().toString())){
                    sb.append(",").append(tree.getId());
                }
                this.getTreeChildIds(tree.getId().toString(),sb);
            }
        }
        return sb;
    }

    @Override
    public List<Map<String,Object>> statProblemLevel() {
        return this.baseMapper.statProblemLevel();
    }

}
