package com.ningdatech.pmapi.common.statemachine.action;

import cn.hutool.core.collection.CollUtil;
import com.ningdatech.pmapi.common.constant.ProjectDeclareConst;
import com.ningdatech.pmapi.common.constant.StateMachineConst;
import com.ningdatech.pmapi.common.enumeration.CommonEnum;
import com.ningdatech.pmapi.common.statemachine.util.StateMachineUtils;
import com.ningdatech.pmapi.common.statemachine.event.ProjectStatusChangeEvent;
import com.ningdatech.pmapi.projectlib.enumeration.ProjectStatusEnum;
import com.ningdatech.pmapi.projectlib.model.entity.Project;
import com.ningdatech.pmapi.projectlib.model.entity.ProjectApplication;
import lombok.extern.slf4j.Slf4j;
import org.springframework.statemachine.StateContext;
import org.springframework.statemachine.action.Action;

import java.util.List;

import static com.ningdatech.pmapi.common.constant.StateMachineConst.APPLICATION_DECLARE;

/**
 * 项目申报状态机选择分支action类
 *
 * @author CMM
 * @since 2023/02/07 22:31
 */
@Slf4j
public class ProjectDeclareChoiceAction implements Action<ProjectStatusEnum, ProjectStatusChangeEvent> {

    private static final String PROJECT_DECLARE = StateMachineConst.PROJECT_DECLARE;

    @Override
    public void execute(StateContext<ProjectStatusEnum, ProjectStatusChangeEvent> stateContext) {
        log.info(String.valueOf(stateContext.getTarget().getId()));
        ProjectStatusEnum projectStatusEnum = stateContext.getTarget().getId();
        switch (projectStatusEnum){
            case PENDING_PREQUALIFICATION_CHOICE:
                preDeclareChoice(stateContext);
                break;
            case PREQUALIFICATION_WITHDRAW_CHOICE:
                preWithDrawChoice(stateContext);
                break;
            case APPROVED_AFTER_CHOICE:
                approvedAfterChoice(stateContext);
                break;
            default:
                throw new IllegalStateException("Unexpected value: " + projectStatusEnum);
        }
    }

    private void approvedAfterChoice(StateContext<ProjectStatusEnum, ProjectStatusChangeEvent> stateContext) {
        List<ProjectApplication> projectApplications = stateContext.getMessage().getHeaders().get(APPLICATION_DECLARE, List.class);
        Project project = stateContext.getMessage().getHeaders().get(PROJECT_DECLARE, Project.class);
        log.info("立项批复之后，项目的状态为:{}" + project.getStatus());
        // 判断 是否有初次创建的应用
        if (CollUtil.isEmpty(projectApplications)){
            project.setStage(ProjectStatusEnum.PROJECT_APPROVED.getCode());
            project.setStatus(ProjectStatusEnum.TO_BE_PURCHASED.getCode());
        }
        final Boolean[] isFirstApp = {Boolean.FALSE};
        projectApplications.stream().forEach(app -> {
            Integer isFirst = app.getIsFirst();
            if(isFirst.equals(CommonEnum.YES.getCode())){
                isFirstApp[0] = Boolean.TRUE;
            }
        });
        if(isFirstApp[0]){
            project.setStage(ProjectStatusEnum.NOT_APPROVED.getCode());
            project.setStatus(ProjectStatusEnum.TO_BE_APP_REGISTER.getCode());
        }else{
            project.setStage(ProjectStatusEnum.PROJECT_APPROVED.getCode());
            project.setStatus(ProjectStatusEnum.TO_BE_PURCHASED.getCode());
        }
    }

    private void preDeclareChoice(StateContext<ProjectStatusEnum, ProjectStatusChangeEvent> stateContext) {
        Project project = stateContext.getMessage().getHeaders().get(PROJECT_DECLARE, Project.class);
        log.info("预审申报事件之前，项目的状态为:{}"+project.getStatus());
        if (StateMachineUtils.isCityProject(project) && StateMachineUtils.judgeDeclareAmount(project,
                ProjectDeclareConst.Number.DECLARE_AMOUNT_JUDGEMENT)){
            project.setStatus(ProjectStatusEnum.JOINT_REVIEW_BY_PROVINCIAL_DEPARTMENTS.getCode());
        }else {
            project.setStatus(ProjectStatusEnum.PRE_APPLYING.getCode());
        }
    }

    private void preWithDrawChoice(StateContext<ProjectStatusEnum, ProjectStatusChangeEvent> stateContext) {
        Project project = stateContext.getMessage().getHeaders().get(PROJECT_DECLARE, Project.class);
        log.info("预审中撤回事件之前，项目的状态为:{}"+project.getStatus());
        if (StateMachineUtils.isCityProject(project) && StateMachineUtils.judgeDeclareAmount(project,
                ProjectDeclareConst.Number.DECLARE_AMOUNT_JUDGEMENT)){
            project.setStatus(ProjectStatusEnum.JOINT_REVIEW_BY_PROVINCIAL_DEPARTMENTS_SUCCESS.getCode());
        }else {
            project.setStatus(ProjectStatusEnum.PENDING_PREQUALIFICATION.getCode());
        }
    }
}
