package cn.axzo.workflow.core.converter.json;

import cn.axzo.workflow.common.enums.ApprovalMethodEnum;
import cn.axzo.workflow.common.model.request.bpmn.BpmnJsonNode;
import cn.axzo.workflow.common.model.request.bpmn.BpmnJsonNodeProperty;
import org.flowable.bpmn.model.ExtensionAttribute;
import org.flowable.bpmn.model.ExtensionElement;
import org.flowable.bpmn.model.FlowableListener;
import org.flowable.bpmn.model.Process;
import org.flowable.bpmn.model.ReceiveTask;
import org.flowable.engine.delegate.BaseExecutionListener;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

import static cn.axzo.workflow.common.constant.BpmnConstants.CONFIG_APPROVAL_METHOD;
import static cn.axzo.workflow.common.constant.BpmnConstants.ELEMENT_ATTRIBUTE_DESC;
import static cn.axzo.workflow.common.constant.BpmnConstants.ELEMENT_ATTRIBUTE_VALUE;
import static org.flowable.bpmn.model.ImplementationType.IMPLEMENTATION_TYPE_DELEGATEEXPRESSION;

/**
 * 接收任务节点
 *
 * @author wangli
 * @since 2023/10/13 17:01
 */
public class ReceiveTaskJsonConverter extends AbstractBpmnJsonConverter<ReceiveTask> {

    @Override
    public ReceiveTask convertJsonToElement(BpmnJsonNode node, Process process) {
        ReceiveTask receiveTask = new ReceiveTask();

        receiveTask.setId(node.getId());
        receiveTask.setName(node.getName());

        // "设置审批人"
        setApprovalExtensionElement(node, receiveTask);

        // 设置执行监听
        setExecutionListeners(node, receiveTask);
        return receiveTask;
    }

    private static void setExecutionListeners(BpmnJsonNode node, ReceiveTask receiveTask) {

        List<FlowableListener> executionListeners = new ArrayList<>();

        if (Objects.nonNull(node.getProperty()) && !Objects.equals(node.getProperty().getApprovalMethod(),
                ApprovalMethodEnum.nobody)) {
            FlowableListener executionListener = new FlowableListener();
            executionListener.setEvent(BaseExecutionListener.EVENTNAME_START);
            executionListener.setImplementationType(IMPLEMENTATION_TYPE_DELEGATEEXPRESSION);
            executionListener.setImplementation("${engineExecutionStartListener}");
            executionListeners.add(executionListener);
        }

        FlowableListener activityStartListener = new FlowableListener();
        activityStartListener.setEvent(BaseExecutionListener.EVENTNAME_START);
        activityStartListener.setImplementationType(IMPLEMENTATION_TYPE_DELEGATEEXPRESSION);
        activityStartListener.setImplementation("${engineActivityStartEventListener}");
        executionListeners.add(activityStartListener);

        FlowableListener activityTakeListener = new FlowableListener();
        activityTakeListener.setEvent(BaseExecutionListener.EVENTNAME_TAKE);
        activityTakeListener.setImplementationType(IMPLEMENTATION_TYPE_DELEGATEEXPRESSION);
        activityTakeListener.setImplementation("${engineActivityTakeEventListener}");
        executionListeners.add(activityTakeListener);

        FlowableListener activityEndListener = new FlowableListener();
        activityEndListener.setEvent(BaseExecutionListener.EVENTNAME_END);
        activityEndListener.setImplementationType(IMPLEMENTATION_TYPE_DELEGATEEXPRESSION);
        activityEndListener.setImplementation("${engineActivityEndEventListener}");
        executionListeners.add(activityEndListener);

        receiveTask.setExecutionListeners(executionListeners);
    }

    private static void setApprovalExtensionElement(BpmnJsonNode node, ReceiveTask receiveTask) {
        BpmnJsonNodeProperty property = node.getProperty();
        if (Objects.isNull(property)) {
            return;
        }

        // 审批方式
        ExtensionElement approvalMethodElement = new ExtensionElement();
        approvalMethodElement.setName(CONFIG_APPROVAL_METHOD);

        ExtensionAttribute approvalMethodValueAttribute = new ExtensionAttribute();
        approvalMethodValueAttribute.setName(ELEMENT_ATTRIBUTE_VALUE);
        approvalMethodValueAttribute.setValue(property.getApprovalMethod().getType());
        approvalMethodElement.addAttribute(approvalMethodValueAttribute);

        ExtensionAttribute approvalMethodDescAttribute = new ExtensionAttribute();
        approvalMethodDescAttribute.setName(ELEMENT_ATTRIBUTE_DESC);
        approvalMethodDescAttribute.setValue("审批方式");
        approvalMethodElement.addAttribute(approvalMethodDescAttribute);
        receiveTask.addExtensionElement(approvalMethodElement);
    }
}
