package com.qqchen.deploy.backend.workflow.util;

import org.flowable.bpmn.model.FlowElement;
import org.flowable.bpmn.model.SequenceFlow;
import org.flowable.bpmn.model.Process;
import org.flowable.bpmn.model.StartEvent;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.Set;
import java.util.stream.Collectors;

public class FlowableUtils {


    public static List<FlowElement> sortFlowElements(Process process) {
        List<FlowElement> sortedElements = new ArrayList<>();
        Queue<FlowElement> queue = new LinkedList<>();
        Set<String> visited = new HashSet<>();

        // 1. 找到开始节点
        FlowElement startEvent = process.getFlowElements().stream()
            .filter(element -> element instanceof StartEvent)
            .findFirst()
            .orElseThrow(() -> new RuntimeException("No start event found"));

        // 2. 从开始节点开始遍历
        queue.offer(startEvent);
        visited.add(startEvent.getId());

        while (!queue.isEmpty()) {
            FlowElement current = queue.poll();
            sortedElements.add(current);

            // 3. 获取当前节点的所有出口连线
            List<SequenceFlow> outgoingFlows = process.getFlowElements().stream()
                .filter(element -> element instanceof SequenceFlow)
                .map(element -> (SequenceFlow) element)
                .filter(flow -> flow.getSourceRef().equals(current.getId()))
                .collect(Collectors.toList());

            // 4. 按连线顺序添加下一个节点
            for (SequenceFlow flow : outgoingFlows) {
                FlowElement nextElement = process.getFlowElement(flow.getTargetRef());
                if (nextElement != null && !visited.contains(nextElement.getId())) {
                    queue.offer(nextElement);
                    visited.add(nextElement.getId());
                }
            }
        }

        return sortedElements;
    }

}
