package com.infoepoch.pms.agent.platform.agent.adapter.out.ai;

import com.alibaba.cloud.ai.graph.agent.interceptor.ModelCallHandler;
import com.alibaba.cloud.ai.graph.agent.interceptor.ModelInterceptor;
import com.alibaba.cloud.ai.graph.agent.interceptor.ModelRequest;
import com.alibaba.cloud.ai.graph.agent.interceptor.ModelResponse;
import org.springframework.ai.chat.messages.Message;
import org.springframework.ai.chat.messages.SystemMessage;

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

/**
 * 消息滑动窗口拦截器。
 * <p>
 * 在每次 LLM 调用前，将消息列表截断为最多 {@code maxMessages} 条：
 * 保留第一条 SystemMessage（如有）+ 最后 N-1 条其余消息。
 * {@code maxMessages=0} 时透传，不过滤。
 * </p>
 */
public class MessageFilterInterceptor extends ModelInterceptor {

    private final int maxMessages;

    /**
     * 构造消息滑动窗口拦截器。
     *
     * @param maxMessages 最大消息数，0 表示不限制
     */
    public MessageFilterInterceptor(int maxMessages) {
        this.maxMessages = maxMessages;
    }

    /**
     * 拦截模型调用，过滤消息后再转发给处理链。
     */
    @Override
    public ModelResponse interceptModel(ModelRequest request, ModelCallHandler handler) {
        List<Message> original = request.getMessages();
        List<Message> filtered = applyFilter(original);
        if (filtered != original) {
            request = ModelRequest.builder(request).messages(filtered).build();
        }
        return handler.call(request);
    }

    /**
     * 返回拦截器名称。
     */
    @Override
    public String getName() {
        return "MessageFilterInterceptor";
    }

    /**
     * 核心过滤逻辑，包可见以便单元测试直接调用。
     */
    List<Message> applyFilter(List<Message> messages) {
        if (maxMessages == 0 || messages.size() <= maxMessages) {
            return messages;
        }
        List<Message> filtered = new ArrayList<>();
        messages.stream()
                .filter(m -> m instanceof SystemMessage)
                .findFirst()
                .ifPresent(filtered::add);
        boolean hasSystem = !filtered.isEmpty();
        int startIndex = Math.max(0, messages.size() - maxMessages + (hasSystem ? 1 : 0));
        filtered.addAll(messages.subList(startIndex, messages.size()));
        return filtered;
    }
}
