package com.ningdatech.pmapi.projectlib.handle;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.common.collect.Lists;
import com.ningdatech.basic.exception.BizException;
import com.ningdatech.basic.util.NdDateUtils;
import com.ningdatech.pmapi.common.constant.CommonConst;
import com.ningdatech.pmapi.projectlib.enumeration.InstTypeEnum;
import com.ningdatech.pmapi.projectlib.model.entity.Project;
import com.ningdatech.pmapi.projectlib.model.entity.ProjectInst;
import com.ningdatech.pmapi.projectlib.service.IProjectInstService;
import com.ningdatech.pmapi.projectlib.service.IProjectService;
import com.ningdatech.pmapi.projectlib.utils.ProjectVersionUtil;
import com.ningdatech.pmapi.todocenter.constant.TodoCenterConstant;
import com.ningdatech.pmapi.todocenter.utils.BuildUserUtils;
import com.wflow.workflow.bean.process.ProgressNode;
import com.wflow.workflow.bean.vo.ProcessDetailVO;
import com.wflow.workflow.bean.vo.ProcessProgressVo;
import com.wflow.workflow.enums.ProcessStatusEnum;
import com.wflow.workflow.enums.StepStatusEnum;
import com.wflow.workflow.service.ProcessInstanceService;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;

/**
 * 项目预审处理
 *
 * @author CMM
 * @since 2023/02/27 10:09
 */
@Order(4)
@Component
public class PreliminaryPreviewHandle extends AbstractProcessBusinessHandle {

    private final IProjectInstService projectInstService;
    private final ProcessInstanceService processInstanceService;
    private final BuildUserUtils buildUserUtils;
    private final ProjectVersionUtil projectVersionUtil;
    private final IProjectService projectService;

    private Integer order = 4;

    public PreliminaryPreviewHandle(IProjectInstService projectInstService, ProcessInstanceService processInstanceService, BuildUserUtils buildUserUtils, ProjectVersionUtil projectVersionUtil, IProjectService projectService) {
        this.projectInstService = projectInstService;
        this.processInstanceService = processInstanceService;
        this.buildUserUtils = buildUserUtils;
        this.projectVersionUtil = projectVersionUtil;
        this.projectService = projectService;
    }

    @Override
    void businessHandle(Long projectId, List<ProcessDetailVO> processSchedule) {
        ProcessDetailVO processDetailVO = new ProcessDetailVO();
        Project project = projectService.getById(projectId);

        if (Objects.isNull(project)){
            throw new BizException("当前项目不存在!");
        }
        //查出历史版本的 所有项目ID
        List<Long> allVersionProjectIds = projectService.getAllVersionProjectId(projectId);
        // 根据项目ID查询项目预审流程的流程状态
        ProjectInst projectInst = projectInstService.getOne(Wrappers.lambdaQuery(ProjectInst.class)
                .in(ProjectInst::getProjectId, allVersionProjectIds)
                .eq(ProjectInst::getInstType, InstTypeEnum.PRELIMINARY_PREVIEW.getCode())
                .ne(ProjectInst::getInstCode, TodoCenterConstant.Declared.NULL_INST_CODE)
                .orderByDesc(ProjectInst::getCreatOn)
                .last("limit 1"));
        ProcessProgressVo instanceDetail = null;
        // 未找到当前版本项目的预审审核流程且当前项目版本号大于1(是被驳回重新申报的项目或者建设方案申报的项目)
        if (Objects.isNull(projectInst)) {
            if (project.getVersion() > CommonConst.VERSION_ONE){
                // 获取上个版本的信息
                instanceDetail = projectVersionUtil.getPreVerProcessInfo(projectId,InstTypeEnum.PRELIMINARY_PREVIEW);
            }
        }else {
            String instCode = projectInst.getInstCode();
            instanceDetail = processInstanceService.getProgressInstanceDetail(null, instCode);
        }
        if (Objects.isNull(instanceDetail)){
            processDetailVO.setStepStatus(StepStatusEnum.NOT_START);
            processDetailVO.setProcessName(CommonConst.PRELIMINARY_PREVIEW);
            processSchedule.add(processDetailVO);
            return;
        }
        String status = instanceDetail.getStatus();
        if (ProcessStatusEnum.UNDER_REVIEW.getDesc().equals(status)){
            processDetailVO.setStepStatus(StepStatusEnum.ON_GOING);
        } else if (ProcessStatusEnum.BE_REJECTED.getDesc().equals(status)) {
            processDetailVO.setStepStatus(StepStatusEnum.REJECTED);
        } else if (ProcessStatusEnum.APPROVED.getDesc().equals(status)) {
            processDetailVO.setStepStatus(StepStatusEnum.COMPLETED);
        }

        // 装配节点审核人员信息
        List<ProgressNode> progressInfo = instanceDetail.getProgressInfo();
        if (CollUtil.isNotEmpty(progressInfo)) {
            buildUserUtils.buildUserByProcessInfo(progressInfo);
            // 根据流程处理详情获取流程完成时间
            if (StepStatusEnum.contains(processDetailVO.getStepStatus(),
                    Lists.newArrayList(StepStatusEnum.REJECTED,
                            StepStatusEnum.COMPLETED))) {
                ProgressNode progressNode = progressInfo.get(progressInfo.size() - 1);
                LocalDateTime finishTime = NdDateUtils.date2LocalDateTime(progressNode.getFinishTime());
                processDetailVO.setFinishTime(finishTime);
            }
        }else {
            LocalDateTime finishTime = NdDateUtils.date2LocalDateTime(instanceDetail.getStartTime());
            processDetailVO.setFinishTime(finishTime);
        }
        processDetailVO.setProcessProgressVo(instanceDetail);
        processDetailVO.setProcessName(CommonConst.PRELIMINARY_PREVIEW);
        processSchedule.add(processDetailVO);
    }

    @Override
    Integer getOrder() {
        return order;
    }

    @Override
    void setOrder(Integer order) {
        this.order = order;
    }
}
