package cn.axzo.workflow.server.controller.listener.task;

import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
import cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper;
import cn.axzo.workflow.core.listener.BpmnTaskEventListener;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.flowable.bpmn.model.Process;
import org.flowable.bpmn.model.UserTask;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.TaskService;
import org.flowable.task.service.delegate.DelegateTask;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;

import java.util.Objects;

import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_INITIATOR;
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_TASK_RELATION_ASSIGNEE_INFO_SNAPSHOT;
import static cn.axzo.workflow.common.enums.BpmnFlowNodeType.NODE_STARTER;

/**
 * 仿钉钉版本的 发起人 节点自动通过处理
 *
 * @author wangli
 * @since 2023/10/16 13:55
 */
@Slf4j
@Component
@AllArgsConstructor
public class StartNodeAutoCompleteEventListener implements BpmnTaskEventListener, Ordered {

    private final TaskService taskService;
    private final RuntimeService runtimeService;
    private final RepositoryService repositoryService;

    @Override
    public int getOrder() {
        return Integer.MIN_VALUE + 2;
    }

    @Override
    public void onCreated(DelegateTask delegateTask) {
        Process mainProcess = repositoryService.getBpmnModel(delegateTask.getProcessDefinitionId()).getMainProcess();
        UserTask userTask = (UserTask) mainProcess.getFlowElement(delegateTask.getTaskDefinitionKey());

        // 这一个通用的“发起人“节点，完全不需要审批，
        // 为什么要创建这个节点？只是为了在审批记录中有一个发起人的记录信息而已！！！
        BpmnMetaParserHelper.getNodeType(userTask).ifPresent(nodeType -> {
            if (Objects.equals(NODE_STARTER, nodeType)) {
                BpmnTaskDelegateAssigner initiator = delegateTask.getVariable(INTERNAL_INITIATOR,
                        BpmnTaskDelegateAssigner.class);
                delegateTask.setVariable(INTERNAL_TASK_RELATION_ASSIGNEE_INFO_SNAPSHOT + delegateTask.getId(),
                        initiator);
                // 直接完成
                taskService.complete(delegateTask.getId(), runtimeService.getVariables(delegateTask.getExecutionId()));
            }
        });
    }
}
