package com.infoepoch.pms.agent.observability.ai;

import org.springframework.ai.chat.messages.AbstractMessage;
import org.springframework.ai.chat.messages.Message;
import org.springframework.ai.chat.messages.MessageType;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.List;

/**
 * AI 观测可读日志格式化工具。
 */
public final class AiReadableLogSupport {

    private AiReadableLogSupport() {
    }

    public static String format(AiObservationContext context, String stage, String detail) {
        return "[链路ID=%s] [会话ID=%s] [阶段=%s] %s".formatted(
                safeValue(context == null ? null : context.traceId()),
                safeValue(context == null ? null : context.sessionId()),
                safeValue(stage),
                safeValue(detail)
        );
    }

    public static String formatModelPrompt(AiObservationContext context, String stage, String prompt) {
        return "[链路ID=%s] [会话ID=%s] [阶段=%s] 模型请求内容:%n%s".formatted(
                safeValue(context == null ? null : context.traceId()),
                safeValue(context == null ? null : context.sessionId()),
                safeValue(stage),
                prompt == null ? "" : prompt
        );
    }

    public static String formatModelMessages(AiObservationContext context, String stage, List<Message> messages) {
        String lineSeparator = System.lineSeparator();
        StringBuilder builder = new StringBuilder("[链路ID=%s] [会话ID=%s] [阶段=%s] 模型请求消息:%s".formatted(
                safeValue(context == null ? null : context.traceId()),
                safeValue(context == null ? null : context.sessionId()),
                safeValue(stage),
                lineSeparator
        ));
        if (CollectionUtils.isEmpty(messages)) {
            return builder.append("(空)").toString();
        }
        for (int index = 0; index < messages.size(); index++) {
            Message message = messages.get(index);
            builder.append('[')
                    .append(index + 1)
                    .append("] role=")
                    .append(resolveRole(message))
                    .append(lineSeparator)
                    .append(resolveText(message));
            if (index < messages.size() - 1) {
                builder.append(lineSeparator);
            }
        }
        return builder.toString();
    }

    public static String formatModelResponse(AiObservationContext context, String stage, String response) {
        return "[链路ID=%s] [会话ID=%s] [阶段=%s] 模型返回内容:%n%s".formatted(
                safeValue(context == null ? null : context.traceId()),
                safeValue(context == null ? null : context.sessionId()),
                safeValue(stage),
                response == null ? "" : response
        );
    }

    public static String findLastAssistantText(List<Message> messages) {
        if (CollectionUtils.isEmpty(messages)) {
            return "";
        }
        for (int index = messages.size() - 1; index >= 0; index--) {
            Message message = messages.get(index);
            if (message != null && message.getMessageType() == MessageType.ASSISTANT) {
                return resolveText(message);
            }
        }
        return "";
    }

    public static String stageWithScene(AiObservationContext context, String suffix) {
        if (context != null && StringUtils.hasText(context.scene())) {
            return context.scene() + suffix;
        }
        return suffix;
    }

    private static String resolveRole(Message message) {
        if (message == null || message.getMessageType() == null) {
            return "unknown";
        }
        return message.getMessageType().getValue();
    }

    private static String resolveText(Message message) {
        if (message instanceof AbstractMessage abstractMessage) {
            return abstractMessage.getText() == null ? "" : abstractMessage.getText();
        }
        return message == null ? "" : message.toString();
    }

    private static String safeValue(String value) {
        return StringUtils.hasText(value) ? value : "-";
    }
}
