package com.easyagents.agent.runtime.event.observer;

import com.easyagents.agent.runtime.event.AgentRuntimeEvent;
import com.easyagents.agent.runtime.event.AgentRuntimeEventBridge;
import com.easyagents.agent.runtime.event.AgentRuntimeEventType;
import com.easyagents.agent.runtime.event.AgentRuntimeObserver;
import io.agentscope.core.hook.HookEvent;
import io.agentscope.core.hook.PostReasoningEvent;
import io.agentscope.core.hook.PreReasoningEvent;
import io.agentscope.core.message.Msg;
import reactor.core.publisher.Mono;

/**
 * 监听 AgentScope 推理生命周期，并发射思考状态旁路事件。
 *
 * <p>{@link AgentRuntimeEventType#REASONING_DELTA} 表示主线路中的推理内容片段；
 * 本观察器发射的 started/completed 事件只用于前端状态展示，不携带模型上下文，
 * 也不会修改 AgentScope 的推理输入或输出。</p>
 */
public class ReasoningLifecycleObserver implements AgentRuntimeObserver {

    private final AgentRuntimeEventBridge eventBridge;

    /**
     * 创建推理生命周期观察器。
     *
     * @param eventBridge 旁路事件桥
     */
    public ReasoningLifecycleObserver(AgentRuntimeEventBridge eventBridge) {
        this.eventBridge = eventBridge;
    }

    /**
     * 观察推理开始和完成事件。
     *
     * @param event AgentScope Hook 事件
     * @return 完成信号
     */
    @Override
    public Mono<Void> observe(HookEvent event) {
        if (event instanceof PreReasoningEvent preReasoningEvent) {
            emitStarted(preReasoningEvent);
            return Mono.empty();
        }
        if (event instanceof PostReasoningEvent postReasoningEvent) {
            emitCompleted(postReasoningEvent);
        }
        return Mono.empty();
    }

    private void emitStarted(PreReasoningEvent event) {
        AgentRuntimeEvent runtimeEvent = eventBridge.event(AgentRuntimeEventType.REASONING_STARTED);
        runtimeEvent.getPayload().put("modelName", event.getModelName());
        runtimeEvent.getPayload().put("messageCount", event.getInputMessages() == null ? 0 : event.getInputMessages().size());
        runtimeEvent.getPayload().put("source", "HOOK");
        runtimeEvent.getPayload().put("phase", "PRE_REASONING");
        eventBridge.emit(runtimeEvent);
    }

    private void emitCompleted(PostReasoningEvent event) {
        AgentRuntimeEvent runtimeEvent = eventBridge.event(AgentRuntimeEventType.REASONING_COMPLETED);
        runtimeEvent.getPayload().put("modelName", event.getModelName());
        runtimeEvent.getPayload().put("stopRequested", event.isStopRequested());
        runtimeEvent.getPayload().put("gotoReasoningRequested", event.isGotoReasoningRequested());
        runtimeEvent.getPayload().put("text", reasoningText(event.getReasoningMessage()));
        runtimeEvent.getPayload().put("source", "HOOK");
        runtimeEvent.getPayload().put("phase", "POST_REASONING");
        eventBridge.emit(runtimeEvent);
    }

    private String reasoningText(Msg message) {
        if (message == null || message.getTextContent() == null) {
            return "";
        }
        return message.getTextContent();
    }
}
