package com.hz.pm.api.projectdeclared.manage;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.hz.pm.api.common.enumeration.ProjectProcessStageEnum;
import com.hz.pm.api.projectlib.manage.ProjectLibManage;
import com.hz.pm.api.projectlib.model.entity.Project;
import com.hz.pm.api.projectlib.model.enumeration.ProjectStatusEnum;
import com.hz.pm.api.projectlib.service.IProjectInstService;
import com.hz.pm.api.projectlib.service.IProjectService;
import com.hz.pm.api.staging.enums.MsgTypeEnum;
import com.hz.pm.api.sys.manage.NoticeManage;
import com.hz.pm.api.todocenter.constant.WorkNoticeConstant;
import com.ningdatech.basic.function.VUtils;
import com.wflow.bean.entity.WflowModels;
import com.wflow.exception.BusinessException;
import com.wflow.workflow.bean.dto.OrgInfoDTO;
import com.wflow.workflow.bean.vo.ProcessStartParamsVo;
import com.wflow.workflow.service.ProcessInstanceService;
import com.wflow.workflow.service.ProcessModelService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collections;
import java.util.Map;
import java.util.Objects;

/**
 * @Classname ReviewByDeptJointManage
 * @Description 部门联审
 * @Date 2023/2/17 14:48
 * @Author PoffyZhang
 */
@Component
@Slf4j
@RequiredArgsConstructor
public class ReviewByDeptJointManage {

    private final IProjectService projectService;

    private final ProcessModelService processModelService;

    private final ProcessInstanceService processService;

    private final IProjectInstService projectInstService;
    private final DefaultDeclaredProjectManage declaredProjectManage;
    private final ProjectLibManage projectLibManage;
    private final DefaultDeclaredProjectManage defaultDeclaredProjectManage;

    private final NoticeManage noticeManage;

    /**
     * 部门联审
     *
     * @param project
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public Boolean startTheProcess(Project project) {
        //这里是任务发起的 所以用项目发起人
        Long startUserCode = Long.parseLong(project.getSponsor());

        VUtils.isTrue(Objects.isNull(project.getId())).throwMessage("提交失败 缺少项目ID!");
        Project projectInfo = projectService.getNewProject(project.getId());
        VUtils.isTrue(Objects.isNull(projectInfo)).throwMessage("提交失败 此项目不存在!");

        WflowModels model = processModelService.getOne(Wrappers.lambdaQuery(WflowModels.class)
                .eq(WflowModels::getProcessType, ProjectProcessStageEnum.DEPARTMENT_JOINT_APPROVAL_PROCESS.getCode())
                .last("limit 1"));

        if (Objects.isNull(model)) {
            throw new BusinessException("找不到部门联审申报流程配置");
        }
        //要判断 项目当前状态 是不是 部门联审
        VUtils.isTrue(!ProjectStatusEnum.DEPARTMENT_JOINT_REVIEW.getCode().equals(projectInfo.getStatus()) ||
                        !ProjectStatusEnum.NOT_APPROVED.getCode().equals(projectInfo.getStage()))
                .throwMessage("提交失败 该项目不是 省级部门联审状态状态或者未立项阶段");

        // 再判断 该项目是否 真实走完 预审审批 并且提取出 提交人
        VUtils.isTrue(Objects.isNull(projectInfo.getSponsor())).throwMessage("提交失败 项目信息 缺少项目发起人!");

        ProcessStartParamsVo params = new ProcessStartParamsVo();
        //发起人的信息
        params.setUser(declaredProjectManage.buildUser(Long.valueOf(projectInfo.getSponsor())));
        params.setProcessUsers(Collections.emptyMap());
        //放入条件判断的项目字段
        //把条件值给放入工作流
        defaultDeclaredProjectManage.buildCondition(params, projectInfo);

        // 获取发起单位、发起单位主管单位、发起单位上级主管条线单位信息
        Map<String, OrgInfoDTO> orgModelMap = defaultDeclaredProjectManage.buildOrgModelMap(startUserCode, project);
        String instanceId = processService.startProcessLs(model, params, orgModelMap);
        log.info("部门联审申报成功 【{}】", instanceId);

        //保存项目信息
        projectInfo = projectLibManage.saveProjectWithVersion(projectInfo, instanceId, ProjectProcessStageEnum.DEPARTMENT_JOINT_APPROVAL_PROCESS.getCode());

        //发送给第一个审批人消息
        noticeManage.sendFirstUser(projectInfo, model.getFormName(), instanceId, WorkNoticeConstant.PASS_MSG_TEMPLATE, MsgTypeEnum.PROJECT_REVIEW);
        return Boolean.TRUE;
    }

}
