package cn.iocoder.yudao.module.inspection.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.iocoder.yudao.framework.security.core.LoginUser;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.yudao.module.inspection.entity.DlInspectionProject;
import cn.iocoder.yudao.module.inspection.entity.InspectionInfo;
import cn.iocoder.yudao.module.inspection.entity.InspectionStepInfo;
import cn.iocoder.yudao.module.inspection.entity.InspectionWorkNode;
import cn.iocoder.yudao.module.inspection.mapper.InspectionWorkNodeMapper;
import cn.iocoder.yudao.module.inspection.service.DlInspectionProjectService;
import cn.iocoder.yudao.module.inspection.service.IInspectionInfoService;
import cn.iocoder.yudao.module.inspection.service.IInspectionWorkNodeService;
import cn.iocoder.yudao.module.inspection.service.InspectionStepInfoService;
import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
import cn.iocoder.yudao.module.system.service.user.AdminUserService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * <p>
 * 检测流程表 服务实现类
 * </p>
 *
 * @author dianliang
 * @since 2024-10-31
 */
@Service
public class InspectionWorkNodeServiceImpl extends ServiceImpl<InspectionWorkNodeMapper, InspectionWorkNode> implements IInspectionWorkNodeService {
    @Autowired
    private IInspectionInfoService inspectionInfoService;
    @Autowired
    private AdminUserService userService;
    @Autowired
    private DlInspectionProjectService inspectionProjectService;
    @Autowired
    private InspectionStepInfoService inspectionStepService;

    /**
     * 员工接单
     * @param inspectionId
     * @param workNodeId
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateInspectionWorkNode(Integer inspectionId, String workNodeId) {
        //获取当前登录人
        LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
        //当前登陆人 就是检测人
        AdminUserDO workerUser = userService.getUser(loginUser.getId());
        //根据工单id获取工单
        InspectionInfo inspectionInfo = inspectionInfoService.getById(inspectionId);
        if (ObjectUtil.isNull(inspectionInfo)) {
            throw new RuntimeException("工单不存在");
        }
        //根据流程id获取流程
        InspectionWorkNode workNode = this.getById(workNodeId);
        if (ObjectUtil.isNull(workNode)) {
            throw new RuntimeException("流程不存在");
        }
        //判断当前流程是否已被接单
        if (!workNode.getStatus().equals("0")) {
            throw new RuntimeException("当前流程已被接单");
        }
        //修改流程相关信息
        workNode.setDealUserId(workerUser.getId());
        workNode.setDealUserName(workerUser.getNickname());
        workNode.setStatus("1");
        //更新
        this.updateById(workNode);

        //查询用户 信息
        //修改工单表中当前施工人
        inspectionInfo.setWorkId(workerUser.getId());
        inspectionInfo.setWorkerName(workerUser.getNickname());
        inspectionInfo.setWorkerPhone(workerUser.getMobile());
        inspectionInfoService.updateById(inspectionInfo);

        //新增步骤
        //根据projectId查询项目名称
        DlInspectionProject project = inspectionProjectService.getOne(new LambdaQueryWrapper<DlInspectionProject>()
                .eq(DlInspectionProject::getId, workNode.getProjectId()));

        InspectionStepInfo inspectionStepInfo = new InspectionStepInfo();
        inspectionStepInfo.setInspectionInfoId(Integer.parseInt(String.valueOf(inspectionInfo.getId())));
        inspectionStepInfo.setTitle(project.getProjectName() + "项目开始检测");
        inspectionStepInfo.setContent(project.getProjectName() + "项目开始检测");
        inspectionStepInfo.setCreateTime(DateUtil.date());
        inspectionStepInfo.setCreator(Integer.parseInt(String.valueOf(workerUser.getId())));
        inspectionStepService.save(inspectionStepInfo);
    }

    /**
     * 更新流程图片 步骤信息
     *
     * @param inspectionWorkNode
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateImageAndStep(InspectionWorkNode inspectionWorkNode) {
        //获取当前登陆人
        LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
        switch (inspectionWorkNode.getSelectType()) {
            case 1:
                //退办理
                returnInspectionInfo(inspectionWorkNode);
                return;
            case 2:
                //选择重审
                retrial(inspectionWorkNode);
                return;
            default:
                //项目完成
                break;
        }
        //根据流程id获取流程
        InspectionWorkNode workNode = this.getById(inspectionWorkNode.getId());

        //根据工单id查询工单
        InspectionInfo inspectionInfo = inspectionInfoService.selectInspectionInfoById(workNode.getInspectionInfoId());

        //判断是否是最后一个项目 根据工单id查询
        //根据工单id查询流程列表
        LambdaQueryWrapper<InspectionWorkNode> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(InspectionWorkNode::getInspectionInfoId, workNode.getInspectionInfoId());
        List<InspectionWorkNode> inspectionWorkNodes = this.list(queryWrapper);
        //判断当前是否是最后一个项目 根据顺序号判断
        boolean flag = hasNextNode(inspectionWorkNodes, workNode);

        // 插入步骤信息
        InspectionStepInfo inspectionStepInfo = new InspectionStepInfo();
        inspectionStepInfo.setInspectionInfoId(Integer.parseInt(String.valueOf(workNode.getInspectionInfoId())));

        //根据projectId查询项目名称
        DlInspectionProject project = inspectionProjectService.getOne(new LambdaQueryWrapper<DlInspectionProject>()
                .eq(DlInspectionProject::getId, workNode.getProjectId()));
        String stepTitle = project.getProjectName() + "项目检测完成";
        inspectionStepInfo.setTitle(stepTitle);
        inspectionStepInfo.setContent(stepTitle);
        inspectionStepInfo.setCreateTime(DateUtil.date());
        inspectionStepInfo.setCreator(Integer.parseInt(String.valueOf(loginUser.getId())));
        inspectionStepService.save(inspectionStepInfo);
        if (!flag) {
            stepTitle = "检测结束";
            //设置工单状态为已完成
            inspectionInfo.setStatus("1");
            //设置工单通过
            inspectionInfo.setIsPass("1");
            //设置工单结束时间
            inspectionInfo.setEndTime(DateUtil.date());
            //设置制证完成
            inspectionInfo.setMakeCert("1");

            //步骤结束
            inspectionStepInfo = new InspectionStepInfo();
            inspectionStepInfo.setTitle(stepTitle);
            inspectionStepInfo.setContent(stepTitle);
            inspectionStepInfo.setCreateTime(DateUtil.date());
            inspectionStepInfo.setCreator(Integer.parseInt(String.valueOf(loginUser.getId())));
            inspectionStepService.save(inspectionStepInfo);
        } else {
            //修改工单表当前流程
            inspectionInfo.setNowOrderNum(workNode.getOrderNum() + 1);
        }

        //将节点状态改为已完成
        inspectionWorkNode.setStatus("2");
        //更新流程节点表
        baseMapper.updateById(inspectionWorkNode);
        //更细工单状态
        inspectionInfoService.updateById(inspectionInfo);
    }

    /**
     * 根据检测id获取流程信息
     *
     * @param inspectionId
     * @return
     */
    @Override
    public List<InspectionWorkNode> getWeorkNodesById(Integer inspectionId) {
        return baseMapper.getWeorkNodesById(inspectionId);
    }

    /**
     * 判断传入的 InspectionWorkNode 对象是否在集合中有后续项目
     *
     * @param nodes       InspectionWorkNode 对象的集合
     * @param currentNode 当前需要判断的 InspectionWorkNode 对象
     * @return 如果存在后续项目返回 true，否则返回 false
     */
    public boolean hasNextNode(List<InspectionWorkNode> nodes, InspectionWorkNode currentNode) {
        int currentOrderNum = currentNode.getOrderNum();

        // 遍历集合中的所有节点，检查是否有 orderNum 大于当前节点的
        for (InspectionWorkNode node : nodes) {
            if (node.getOrderNum() > currentOrderNum) {
                return true;
            }
        }
        return false;
    }

    /**
     * 退办理
     * @param inspectionWorkNode
     */
    public void returnInspectionInfo(InspectionWorkNode inspectionWorkNode){
        // 通过
        //通过工单id获取工单
        InspectionInfo info = inspectionInfoService.getById(inspectionWorkNode.getInspectionInfoId());
        info.setIsPass("0");
        info.setEndTime(DateUtil.date());
        info.setStatus("1");
        inspectionInfoService.updateById(info);

        //插入步骤信息
        InspectionStepInfo stepInfo = new InspectionStepInfo();
        stepInfo.setInspectionInfoId(Integer.parseInt(inspectionWorkNode.getInspectionInfoId().toString()));
        stepInfo.setTitle("退办理");
        stepInfo.setContent("退办理");
        inspectionStepService.save(stepInfo);
    }

    /**
     * 重审
     * @param inspectionWorkNode
     */
    public void retrial(InspectionWorkNode inspectionWorkNode) {
        //通过流程节点id查询流程
        InspectionWorkNode workNode = this.getById(inspectionWorkNode.getId());
        //通过工单id获取工单
        InspectionInfo info = inspectionInfoService.getById(inspectionWorkNode.getInspectionInfoId());
        info.setIsRetrial("1");
        info.setNowOrderNum(workNode.getOrderNum());

        // 将选择的重审项目之后的所有项目设置为待开始
        this.update(new UpdateWrapper<InspectionWorkNode>()
                .set("status", "0")
                .eq("inspection_info_id", inspectionWorkNode.getInspectionInfoId())
                .ge("order_num", workNode.getOrderNum()));

        //跟新工单表
        inspectionInfoService.updateById(info);

        // 添加步骤信息表
        InspectionStepInfo stepInfo = new InspectionStepInfo();
        stepInfo.setInspectionInfoId(Integer.parseInt(inspectionWorkNode.getInspectionInfoId().toString()));
        stepInfo.setTitle("重审");
        stepInfo.setContent("重审");
        inspectionStepService.save(stepInfo);
    }
}