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.ArrayList;
import java.util.function.Function;

@Slf4j
@Component
@Order(6)
public class FlowAfterInterceptor extends AbstractFlowMsgPreInterceptor{

    private final TaskInstHolder taskInstHolder;

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

    @Override
    public TaskNodeExecuteResult doIntercept(TaskNodeExecuteMessage message, Function<TaskNodeExecuteMessage, TaskNodeExecuteResult> next) {
        TaskNodeExecuteResult result = next.apply(message);
        FlowExecutionEvent.EventType eventType;
        String errorMessage = null;

        if (result != null && result.isSuccess()) {
            eventType = FlowExecutionEvent.EventType.NODE_COMPLETED;
        } else {
            eventType = FlowExecutionEvent.EventType.NODE_FAILED;
            errorMessage = result != null ? result.getErrorMsg() : "执行结果为空";
        }

        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(eventType)
                .nodeName(message.getNodeName())
                .instId(message.getInstId())
                .taskId(message.getTaskId())
                .moduleCode(moduleCode)
                .itemId(message.getItemId())
                .nodeId(message.getNodeId())
                .nodeCount(message.getGraph().allNodeIds().size())
                .nodeType(message.getNodeType())
                .action(message.getAction())
                .outputParams(result != null ? result.getOutputParams() : null)
                .terminalId(message.getTerminalId())
                .iterations(message.getIterations() == null
                        ? new ArrayList<>() : new ArrayList<>(message.getIterations()))
                .errorMessage(errorMessage)
                .build();

        eventPublisher.publishEvent(event);
        return result;
    }
}
