package com.cmvr.test.flow.runtime.interceptor;

import com.cmvr.test.flow.context.TaskContext;
import com.cmvr.test.flow.context.TaskInstHolder;
import com.cmvr.test.flow.runtime.event.FlowExecutionEvent;
import com.cmvr.test.flow.runtime.event.FlowExecutionEventPublisher;
import com.cmvr.test.flow.runtime.message.TaskNodeExecuteMessage;
import com.cmvr.test.flow.runtime.message.TaskNodeExecuteResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.util.function.Function;

@Slf4j
@Component
@Order(1)
public class FlowBeforeInterceptor extends AbstractFlowMsgPreInterceptor{

    private final TaskInstHolder taskInstHolder;

    public FlowBeforeInterceptor(FlowExecutionEventPublisher eventPublisher, TaskInstHolder taskInstHolder) {
        super(eventPublisher);
        this.taskInstHolder = taskInstHolder;
    }

    @Override
    public TaskNodeExecuteResult doIntercept(TaskNodeExecuteMessage message, Function<TaskNodeExecuteMessage, TaskNodeExecuteResult> next) {
        TaskContext taskContext = taskInstHolder.getContext(message.getInstId());
        String moduleCode = taskContext != null ? taskContext.getModuleCode() : null;
        
        if (moduleCode == null) {
            log.warn("节点 [{}] 执行前，任务上下文 [{}] 的 moduleCode 为空，事件可能不会被监听器处理",
                    message.getNodeName(), message.getInstId());
        }
        
        FlowExecutionEvent event = FlowExecutionEvent.builder()
                .eventType(FlowExecutionEvent.EventType.NODE_STARTED)
                .instId(message.getInstId())
                .taskId(message.getTaskId())
                .moduleCode(moduleCode)
                .itemId(message.getItemId())
                .nodeId(message.getNodeId())
                .nodeCount(message.getGraph().allNodeIds().size())
                .nodeName(message.getNodeName())
                .nodeType(message.getNodeType())
                .build();

        eventPublisher.publishEvent(event);
        return next.apply(message);
    }
}
