package com.infoepoch.pms.agent.domain.care.log;

import com.alibaba.cloud.ai.graph.RunnableConfig;
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;
import java.util.Collection;
import java.util.Map;
import java.util.StringJoiner;
import java.util.UUID;

/**
 * 精准关爱日志辅助
 */
public final class CareTraceLogSupport {

    private static final int MAX_PREVIEW_LENGTH = 60;
    public static final String METADATA_TRACE_ID = "traceId";
    public static final String METADATA_SESSION_ID = "sessionId";
    public static final String METADATA_SCENE = "scene";

    private CareTraceLogSupport() {
    }

    /**
     * 生成单次请求唯一 traceId。
     */
    public static String newTraceId() {
        return UUID.randomUUID().toString().replace("-", "");
    }

    /**
     * 统一拼接日志前缀。
     */
    public static String format(String traceId, String sessionId, String stage, String detail) {
        return "[链路ID=%s] [会话ID=%s] [阶段=%s] %s".formatted(
                safeValue(traceId),
                safeValue(sessionId),
                safeValue(stage),
                safeValue(detail)
        );
    }

    /**
     * 统一拼接完整模型请求日志，保留原始换行便于排查 prompt 结构。
     */
    public static String formatModelPrompt(String traceId, String sessionId, String stage, String prompt) {
        return "[链路ID=%s] [会话ID=%s] [阶段=%s] 模型请求内容:%n%s".formatted(
                safeValue(traceId),
                safeValue(sessionId),
                safeValue(stage),
                prompt == null ? "" : prompt
        );
    }

    /**
     * 统一拼接完整模型返回日志，保留原始换行便于排查响应结构。
     */
    public static String formatModelResponse(String traceId, String sessionId, String stage, String response) {
        return "[链路ID=%s] [会话ID=%s] [阶段=%s] 模型返回内容:%n%s".formatted(
                safeValue(traceId),
                safeValue(sessionId),
                safeValue(stage),
                response == null ? "" : response
        );
    }

    /**
     * 统一拼接流式模型分片日志，便于查看模型逐块返回的原始内容。
     */
    public static String formatModelStreamChunk(String traceId, String sessionId, String stage, int index, String chunk) {
        return "[链路ID=%s] [会话ID=%s] [阶段=%s] chunkIndex=%s, chunkLength=%s, chunk内容:%n%s".formatted(
                safeValue(traceId),
                safeValue(sessionId),
                safeValue(stage),
                index,
                chunk == null ? 0 : chunk.length(),
                chunk == null ? "" : chunk
        );
    }

    /**
     * 构造 care agent 调用使用的统一运行时配置。
     */
    public static RunnableConfig buildAgentRunnableConfig(String traceId, String sessionId, String scene) {
        return RunnableConfig.builder()
                .threadId(sessionId)
                .addMetadata(METADATA_TRACE_ID, traceId)
                .addMetadata(METADATA_SESSION_ID, sessionId)
                .addMetadata(METADATA_SCENE, scene)
                .build();
    }

    /**
     * 根据 RunnableConfig 读取 traceId。
     */
    public static String resolveTraceId(RunnableConfig runnableConfig) {
        return metadataValue(runnableConfig, METADATA_TRACE_ID);
    }

    /**
     * 根据 RunnableConfig 读取 sessionId，缺失时回退到 threadId。
     */
    public static String resolveSessionId(RunnableConfig runnableConfig) {
        String sessionId = metadataValue(runnableConfig, METADATA_SESSION_ID);
        if (StringUtils.hasText(sessionId)) {
            return sessionId;
        }
        return runnableConfig == null ? null : runnableConfig.threadId().orElse(null);
    }

    /**
     * 根据 RunnableConfig 读取业务场景。
     */
    public static String resolveScene(RunnableConfig runnableConfig) {
        return metadataValue(runnableConfig, METADATA_SCENE);
    }

    /**
     * 将真实消息列表渲染成便于排查的日志文本。
     */
    public static String formatModelMessages(String traceId, String sessionId, String stage, List<Message> messages) {
        String lineSeparator = System.lineSeparator();
        StringBuilder builder = new StringBuilder("[链路ID=%s] [会话ID=%s] [阶段=%s] 模型请求消息:%s".formatted(
                safeValue(traceId),
                safeValue(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(resolveMessageRole(message))
                    .append(lineSeparator)
                    .append(resolveMessageText(message));
            if (index < messages.size() - 1) {
                builder.append(lineSeparator);
            }
        }
        return builder.toString();
    }

    /**
     * 提取消息列表中的最后一条 assistant 文本。
     */
    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) {
                continue;
            }
            String text = resolveMessageText(message);
            if (text != null) {
                return text;
            }
        }
        return "";
    }

    /**
     * 返回 prompt 的原始长度，便于判断上下文体积。
     */
    public static int promptLength(String prompt) {
        return prompt == null ? 0 : prompt.length();
    }

    /**
     * 生成安全的消息摘要。
     */
    public static String safeMessageSummary(String message) {
        if (!StringUtils.hasText(message)) {
            return "长度=0";
        }
        String normalized = normalizeText(message);
        return "长度=%d 摘要=%s".formatted(message.length(), abbreviate(normalized));
    }

    /**
     * 生成安全的条件摘要。
     */
    public static String safeConditionsSummary(Map<String, Object> conditions) {
        if (conditions == null || conditions.isEmpty()) {
            return "空";
        }
        StringJoiner joiner = new StringJoiner(", ", "{", "}");
        conditions.forEach((key, value) -> joiner.add(key + "=" + summarizeValue(value)));
        return joiner.toString();
    }

    /**
     * 生成安全的文本摘要。
     */
    public static String safeText(String text) {
        if (!StringUtils.hasText(text)) {
            return "";
        }
        return abbreviate(normalizeText(text));
    }

    /**
     * 生成安全的集合条数摘要。
     */
    public static String safeCount(String label, Collection<?> values) {
        int size = CollectionUtils.isEmpty(values) ? 0 : values.size();
        return label + "=" + size;
    }

    /**
     * 兼容多种对象值的安全摘要。
     */
    private static String summarizeValue(Object value) {
        if (value == null) {
            return "空";
        }
        if (value instanceof Collection<?> collection) {
            return "数量=" + collection.size();
        }
        if (value instanceof Map<?, ?> map) {
            return "数量=" + map.size();
        }
        return abbreviate(normalizeText(value.toString()));
    }

    /**
     * 读取 RunnableConfig metadata 中的文本值。
     */
    private static String metadataValue(RunnableConfig runnableConfig, String key) {
        if (runnableConfig == null || !StringUtils.hasText(key)) {
            return null;
        }
        return runnableConfig.metadata(key)
                .map(Object::toString)
                .orElse(null);
    }

    /**
     * 提取消息角色。
     */
    private static String resolveMessageRole(Message message) {
        if (message == null || message.getMessageType() == null) {
            return "unknown";
        }
        return message.getMessageType().getValue();
    }

    /**
     * 提取消息文本。
     */
    private static String resolveMessageText(Message message) {
        if (message instanceof AbstractMessage abstractMessage) {
            return abstractMessage.getText() == null ? "" : abstractMessage.getText();
        }
        return message == null ? "" : message.toString();
    }

    /**
     * 归一化文本中的连续空白。
     */
    private static String normalizeText(String text) {
        return text.replaceAll("\\s+", " ").trim();
    }

    /**
     * 截断过长文本，避免日志膨胀。
     */
    private static String abbreviate(String text) {
        if (!StringUtils.hasText(text) || text.length() <= MAX_PREVIEW_LENGTH) {
            return text;
        }
        return text.substring(0, MAX_PREVIEW_LENGTH) + "...";
    }

    /**
     * 将空值统一显示为短横线。
     */
    private static String safeValue(String value) {
        return StringUtils.hasText(value) ? value : "-";
    }
}

