package com.ningdatech.pmapi.projectlib.handle;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.common.collect.Lists;
import com.ningdatech.pmapi.common.constant.BizConst;
import com.ningdatech.pmapi.common.constant.ProjectDeclareConst;
import com.ningdatech.pmapi.common.enumeration.ProjectProcessStageEnum;
import com.ningdatech.pmapi.common.statemachine.contants.RegionContant;
import com.ningdatech.pmapi.common.statemachine.util.StateMachineUtils;
import com.ningdatech.pmapi.projectlib.model.entity.Project;
import com.ningdatech.pmapi.projectlib.service.IProjectService;
import com.wflow.bean.entity.WflowModels;
import com.wflow.workflow.bean.vo.ProcessDetailVO;
import com.wflow.workflow.service.ProcessModelService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 流程执行链
 *
 * @author CMM
 * @since 2023/02/26 21:36
 */
@Component
public class ProcessExecuteChainHandle {

    @Autowired
    private IProjectService projectService;

    @Autowired
    private ProcessModelService processModelService;

    /**
     * 具体处理者的集合
     */
    private List<AbstractProcessBusinessHandle> processBusinessHandles;

    public ProcessExecuteChainHandle(List<AbstractProcessBusinessHandle> processBusinessHandles) {
        this.processBusinessHandles = processBusinessHandles;
    }

    /**
     * 遍历处理链，通过前缀判断能否处理逻辑，如果不能继续遍历
     * @param projectId
     * @return void
     * @author CMM
     * @since 2023/02/26
     */
    public List<ProcessDetailVO> handle(Long projectId, List<ProcessDetailVO> processSchedule){
        Project project = projectService.getById(projectId);

        List<AbstractProcessBusinessHandle> handles = Lists.newArrayList();
        for (AbstractProcessBusinessHandle processBusinessHandle : processBusinessHandles) {
            if(Objects.nonNull(project) && RegionContant.LS_LQ_CODE.equals(project.getAreaCode())) {
                if(processBusinessHandle instanceof AnnualPlanHandle){
                    processBusinessHandle.setOrder(7);
                }else if(processBusinessHandle instanceof ConstructionPlanReviewHandle){
                    processBusinessHandle.setOrder(6);
                }
            }else{
                if(processBusinessHandle instanceof AnnualPlanHandle){
                    processBusinessHandle.setOrder(6);
                }else if(processBusinessHandle instanceof ConstructionPlanReviewHandle){
                    processBusinessHandle.setOrder(7);
                }
            }

            //建设方案
            if(processBusinessHandle instanceof ConstructionPlanReviewHandle){
                WflowModels model = processModelService.getOne(Wrappers.lambdaQuery(WflowModels.class)
                        .eq(WflowModels::getRegionCode, project.getAreaCode())
                        .eq(WflowModels::getProcessType, ProjectProcessStageEnum.CONSTRUCTION_PROJECT_APPROVAL_PROCESS.getCode())
                        .last(BizConst.LIMIT_1));
                if(Objects.nonNull(model)){
                    if(!model.getIsStop()){
                        handles.add(processBusinessHandle);
                    }
                }
            }else if(processBusinessHandle instanceof ProvinceUnitedReviewHandle){
                //省级联审
                if (StateMachineUtils.isCityProject(project) && StateMachineUtils.judgeDeclareAmount(project,
                        ProjectDeclareConst.Number.DECLARE_AMOUNT_JUDGEMENT)){
                    handles.add(processBusinessHandle);
                }
            }else{
                handles.add(processBusinessHandle);
            }
        }

        handles = handles.stream()
                .sorted(Comparator.comparing(AbstractProcessBusinessHandle::getOrder))
                .collect(Collectors.toList());
        if (handles.size() > 0) {
            for (AbstractProcessBusinessHandle processBusinessHandle : handles) {
                processBusinessHandle.businessHandle(projectId, processSchedule);
            }
            return processSchedule;
        }
        return Collections.emptyList();
    }
}
