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

import com.ningdatech.basic.exception.BizException;
import com.ningdatech.pmapi.common.constant.ProjectDeclareConstants;
import com.ningdatech.pmapi.common.constant.StateMachineHeaderNameConstants;
import com.ningdatech.pmapi.common.statemachine.builder.ProjectDeclareStateMachineBuilder;
import com.ningdatech.pmapi.common.statemachine.event.ProjectStatusChangeEvent;
import com.ningdatech.pmapi.projectlib.enumeration.ProjectStatusEnum;
import com.ningdatech.pmapi.projectlib.model.entity.Project;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.statemachine.StateMachine;
import org.springframework.statemachine.persist.StateMachinePersister;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Objects;

/**
 * 状态机工具类
 *
 * @author CMM
 * @since 2023/02/07 22:49
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class StateMachineUtils {

    private static final String PROJECT_DECLARE = StateMachineHeaderNameConstants.PROJECT_DECLARE;

    private final ProjectDeclareStateMachineBuilder projectDeclareStateMachineBuilder;

    @Resource(name = "projectDeclareStateMachinePersister")
    private StateMachinePersister projectDeclareStateMachinePersister;

    public void execute(Project project, ProjectStatusChangeEvent event) throws Exception {
        log.info("调用状态机前的项目状态为>>>>>>>>>>{}" + project.getStatus());
        //获取TO状态机
        StateMachine<ProjectStatusEnum, ProjectStatusChangeEvent> stateMachine = projectDeclareStateMachineBuilder.build();
        Message message = MessageBuilder.withPayload(event).setHeader(PROJECT_DECLARE, project).build();
        //初始化状态机
        projectDeclareStateMachinePersister.restore(stateMachine, project);
        stateMachine.sendEvent(message);
        log.info("调用状态机后的项目状态为>>>>>>>>>>{}" + project.getStatus());
    }

    /**
     * 判断项目申报金额是否大于1000万元
     *
     * @param project
     * @return boolean
     * @author CMM
     * @since 2023/02/07 17:13
     */
    public static boolean judgeDeclareAmount(Project project) {
        int flag = project.getDeclareAmount().compareTo(ProjectDeclareConstants.Number.DECLARE_AMOUNT_JUDGEMENT);
        if (flag > 0 || flag == 0) {
            return true;
        }
        return false;
    }

    /**
     * 判断项目建设层级是否为市级项目
     *
     * @param project
     * @return boolean
     * @author CMM
     * @since 2023/02/07 17:05
     */
    public static boolean isCityProject(Project project) {
        if (ProjectDeclareConstants.Number.CITY_BUILD_LEVEL.equals(project.getBuildLevel()) ||
                ProjectDeclareConstants.Number.CITY_SELF_BUILD_LEVEL.equals(project.getBuildLevel())) {
            return true;
        }
        return false;
    }

    public ProjectStatusChangeEvent getProjectStatusPassEvent(Integer projectStatusSecond) {
        ProjectStatusChangeEvent event = ProjectStatusChangeEvent.getPassValueByCode(projectStatusSecond);
        if (Objects.isNull(event)) {
            throw new BizException("该状态下没有对应的通过操作！");
        }
        return event;
    }

    public ProjectStatusChangeEvent getProjectStatusRejectEvent(Integer projectStatusSecond) {
        ProjectStatusChangeEvent event = ProjectStatusChangeEvent.getRejectValueByCode(projectStatusSecond);
        if (Objects.isNull(event)) {
            throw new BizException("该状态下没有对应的驳回操作！");
        }
        return event;
    }

    public ProjectStatusChangeEvent getProjectStatusWithdrawEvent(Integer projectStatusSecond) {
        ProjectStatusChangeEvent event = ProjectStatusChangeEvent.getWithdrawValueByCode(projectStatusSecond);
        if (Objects.isNull(event)) {
            throw new BizException("该状态下没有对应的撤回操作！");
        }
        return event;
    }
}
