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

import cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper;
import cn.axzo.workflow.core.listener.BpmnTaskEventListener;
import cn.axzo.workflow.core.service.BpmnProcessInstanceService;
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.HashMap;
import java.util.Map;

import static cn.axzo.workflow.common.constant.BpmnConstants.APPROVAL_ENDS_AUTOMATICALLY;
import static cn.axzo.workflow.common.constant.BpmnConstants.COMMENT_TYPE_ADVICE;
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_DELETE_PROCESS_FLAG;
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_END_TENANT_ID;
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_END_USER_ID;
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_END_USER_NAME;
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_PROCESS_TYPE_REJECT;

/**
 * UserTask 节点自动通过和拒绝处理
 *
 * @author wangli
 * @since 2023/11/21 11:30
 */
@Slf4j
@Component
@AllArgsConstructor
public class AutoOperatorEventListener implements BpmnTaskEventListener, Ordered {

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

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

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

        BpmnMetaParserHelper.getApprovalMethod(userTask)
                .ifPresent(approvalMethodEnum -> {
                    switch (approvalMethodEnum) {
                        case autoPassed:
                            autoPass(delegateTask);
                            break;
                        case autoRejection:
                            autoReject(delegateTask);
                            break;
                        default:
                            break;
                    }
                });
    }

    private void autoReject(DelegateTask delegateTask) {
        taskService.addComment(delegateTask.getId(), delegateTask.getProcessInstanceId(), COMMENT_TYPE_ADVICE, "自动拒绝");
        Map<String, Object> variables = new HashMap<>();
        variables.put(INTERNAL_END_TENANT_ID, delegateTask.getTenantId());
        variables.put(INTERNAL_END_USER_NAME, "系统");
        variables.put(INTERNAL_END_USER_ID, "system");
        variables.put(INTERNAL_DELETE_PROCESS_FLAG, INTERNAL_PROCESS_TYPE_REJECT);
        runtimeService.setVariables(delegateTask.getProcessInstanceId(), variables);

        // 删除流程实例，以实现驳回任务时，取消整个审批流程
        processInstanceService.deleteProcessInstance(delegateTask.getProcessInstanceId(), APPROVAL_ENDS_AUTOMATICALLY);
    }


    private void autoPass(DelegateTask delegateTask) {
        taskService.addComment(delegateTask.getId(), delegateTask.getProcessInstanceId(), COMMENT_TYPE_ADVICE, "自动通过");
        taskService.complete(delegateTask.getId(), runtimeService.getVariables(delegateTask.getExecutionId()));
    }
}
