package com.hz.pm.api.common.statemachine.action;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.hz.pm.api.common.model.constant.ProjectDeclareConst;
import com.hz.pm.api.common.model.constant.StateMachineConst;
import com.hz.pm.api.common.enumeration.CommonEnum;
import com.hz.pm.api.common.statemachine.util.StateMachineUtil;
import com.hz.pm.api.common.statemachine.event.ProjectStatusChangeEvent;
import com.hz.pm.api.projectlib.model.enumeration.ProjectStatusEnum;
import com.hz.pm.api.projectlib.model.entity.Project;
import com.hz.pm.api.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.hz.pm.api.common.model.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) {
        Project project = getProject(stateContext);
        List<ProjectApplication> projectApplications = getProjectApplication(stateContext);
        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.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 = getProject(stateContext);
        log.info("预审申报事件之前，项目的状态为:{}", project.getStatus());
        project.setStatus(ProjectStatusEnum.PRE_APPLYING.getCode());
    }

    private void preWithDrawChoice(StateContext<ProjectStatusEnum, ProjectStatusChangeEvent> stateContext) {
        Project project = getProject(stateContext);
        log.info("预审中撤回事件之前，项目的状态为:{}", project.getStatus());
        project.setStatus(ProjectStatusEnum.PENDING_PREQUALIFICATION.getCode());
    }

    private Project getProject(StateContext<ProjectStatusEnum, ProjectStatusChangeEvent> stateContext) {
        Project project = stateContext.getMessage().getHeaders().get(PROJECT_DECLARE, Project.class);
        Assert.notNull(project, "项目信息获取失败%s", JSONUtil.toJsonStr(stateContext.getMessage()));
        return project;
    }

    @SuppressWarnings("unchecked")
    private List<ProjectApplication> getProjectApplication(StateContext<ProjectStatusEnum, ProjectStatusChangeEvent> stateContext) {
        return stateContext.getMessage().getHeaders().get(APPLICATION_DECLARE, List.class);
    }

}
