package cn.axzo.workflow.core.engine.cmd;

import cn.axzo.workflow.common.enums.ApprovalMethodEnum;
import cn.axzo.workflow.common.exception.WorkflowEngineException;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnActivityTriggerDTO;
import cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper;
import com.alibaba.fastjson.JSON;
import org.apache.commons.lang3.StringUtils;
import org.flowable.bpmn.model.BpmnModel;
import org.flowable.bpmn.model.FlowElement;
import org.flowable.common.engine.impl.interceptor.CommandContext;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl;
import org.flowable.engine.impl.util.CommandContextUtil;
import org.flowable.engine.impl.util.ProcessDefinitionUtil;
import org.flowable.task.service.impl.persistence.entity.TaskEntity;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.Serializable;
import java.util.Objects;

import static cn.axzo.workflow.common.code.BpmnTaskRespCode.ACTIVITY_TRIGGER_NOT_EXISTS;
import static cn.axzo.workflow.common.constant.BpmnConstants.COMMENT_TYPE_OPERATION_DESC;
import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.addComment;

/**
 * 自定义(同步)流转业务姐弟那的命令器实现
 *
 * @author wangli
 * @since 2024-09-09 13:58
 */
public class CustomActivityTriggerCmd extends AbstractCommand<Void> implements Serializable {

    private static final long serialVersionUID = 5806130509691903321L;
    private static final Logger log = LoggerFactory.getLogger(CustomActivityTriggerCmd.class);
    private final BpmnActivityTriggerDTO dto;

    public CustomActivityTriggerCmd(BpmnActivityTriggerDTO dto) {
        this.dto = dto;
    }

    @Override
    public String paramToJsonString() {
        return JSON.toJSONString(dto);
    }

    @Override
    public Void execute(CommandContext commandContext) {
        ProcessEngineConfigurationImpl processEngineConfiguration =
                CommandContextUtil.getProcessEngineConfiguration(commandContext);

        TaskEntity task = (TaskEntity) processEngineConfiguration.getTaskService().createTaskQuery()
                .executionId(dto.getTriggerId())
                .taskDefinitionKey(StringUtils.isBlank(dto.getActivityId()) ? null : dto.getActivityId())
                .singleResult();
        if (Objects.isNull(task)) {
            throw new WorkflowEngineException(ACTIVITY_TRIGGER_NOT_EXISTS, dto.getTriggerId());
        }

        if (!validateActivityConfig(task)) {
            log.info("业务节点唤醒时，发现节点已经修改配置，无法继续唤醒，processInstanceId:{}, taskDefinitionKey={}", task.getProcessInstanceId(), task.getTaskDefinitionKey());
            return null;
        }

        addComment(commandContext, task, COMMENT_TYPE_OPERATION_DESC, "已同意");
        RuntimeService runtimeService = processEngineConfiguration.getRuntimeService();
        runtimeService.trigger(dto.getTriggerId());
        return null;
    }

    public static boolean validateActivityConfig(TaskEntity task) {
        BpmnModel bpmnModel = ProcessDefinitionUtil.getBpmnModel(task.getProcessDefinitionId());
        FlowElement flowElement = bpmnModel.getFlowElement(task.getTaskDefinitionKey());
        ApprovalMethodEnum approvalMethodEnum = BpmnMetaParserHelper.getApprovalMethod(flowElement).orElse(ApprovalMethodEnum.unknown);
        return Objects.equals(approvalMethodEnum, ApprovalMethodEnum.nobody);
    }


}
