package tech.easyflow.core.runtime;

import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * 聊天运行时历史 payload 的统一读写工具。
 * <p>
 * 该工具只处理 {@link Map} / {@link List} 结构，避免把 easy-agents 类型泄漏到通用协议模块。
 */
public final class ChatRuntimeHistoryPayloadHelper {

    public static final String KEY_MESSAGE_CHAIN = "messageChain";
    public static final String KEY_ASSISTANT_MESSAGE = "assistantMessage";
    public static final String KEY_FINAL_ASSISTANT_MESSAGE = "finalAssistantMessage";
    public static final String KEY_TOOL_MESSAGES = "toolMessages";
    public static final String KEY_DISPLAY_CHAINS = "displayChains";
    public static final String KEY_CHAINS = "chains";

    private ChatRuntimeHistoryPayloadHelper() {
    }

    /**
     * 构造 assistant 历史消息结构。
     *
     * @param content assistant 内容
     * @param reasoningContent assistant reasoning 内容
     * @param toolCalls assistant tool calls
     * @return assistant 历史消息结构
     */
    public static Map<String, Object> assistantMessage(String content,
                                                       String reasoningContent,
                                                       List<Map<String, Object>> toolCalls) {
        Map<String, Object> message = new LinkedHashMap<>();
        message.put("role", "assistant");
        if (content != null) {
            message.put("content", content);
        }
        if (reasoningContent != null && !reasoningContent.isEmpty()) {
            message.put("reasoningContent", reasoningContent);
        }
        if (toolCalls != null && !toolCalls.isEmpty()) {
            message.put("toolCalls", deepCopyList(toolCalls));
        }
        return message;
    }

    /**
     * 构造 tool 历史消息结构。
     *
     * @param toolCallId tool call id
     * @param content tool 结果内容
     * @return tool 历史消息结构
     */
    public static Map<String, Object> toolMessage(String toolCallId, String content) {
        Map<String, Object> message = new LinkedHashMap<>();
        message.put("role", "tool");
        message.put("toolCallId", toolCallId);
        if (content != null) {
            message.put("content", content);
        }
        return message;
    }

    /**
     * 构造统一的历史 payload。
     *
     * @param messageChain 完整 assistant/tool 历史链
     * @param toolMessages tool 历史列表
     * @param displayChains 前端展示链
     * @return payload
     */
    public static Map<String, Object> buildPayload(List<Map<String, Object>> messageChain,
                                                   List<Map<String, Object>> toolMessages,
                                                   List<Map<String, Object>> displayChains) {
        Map<String, Object> payload = new LinkedHashMap<>();
        List<Map<String, Object>> safeMessageChain = deepCopyList(messageChain);
        List<Map<String, Object>> safeToolMessages = deepCopyList(toolMessages);
        List<Map<String, Object>> safeDisplayChains = deepCopyList(displayChains);
        if (!safeMessageChain.isEmpty()) {
            payload.put(KEY_MESSAGE_CHAIN, safeMessageChain);
            Map<String, Object> firstAssistant = findAssistant(safeMessageChain, false);
            if (!firstAssistant.isEmpty()) {
                payload.put(KEY_ASSISTANT_MESSAGE, firstAssistant);
            }
            Map<String, Object> lastAssistant = findAssistant(safeMessageChain, true);
            if (!lastAssistant.isEmpty() && !lastAssistant.equals(firstAssistant)) {
                payload.put(KEY_FINAL_ASSISTANT_MESSAGE, lastAssistant);
            }
        }
        if (!safeToolMessages.isEmpty()) {
            payload.put(KEY_TOOL_MESSAGES, safeToolMessages);
        }
        if (!safeDisplayChains.isEmpty()) {
            payload.put(KEY_DISPLAY_CHAINS, safeDisplayChains);
            payload.put(KEY_CHAINS, deepCopyList(safeDisplayChains));
        }
        return payload;
    }

    /**
     * 读取结构化消息链。
     *
     * @param payload contentPayload
     * @return 结构化消息链
     */
    public static List<Map<String, Object>> getMessageChain(Map<String, Object> payload) {
        return getMapList(payload == null ? null : payload.get(KEY_MESSAGE_CHAIN));
    }

    /**
     * 读取 assistant 历史消息。
     *
     * @param payload contentPayload
     * @return assistant 历史消息
     */
    public static Map<String, Object> getAssistantMessage(Map<String, Object> payload) {
        return getMap(payload == null ? null : payload.get(KEY_ASSISTANT_MESSAGE));
    }

    /**
     * 读取最终 assistant 历史消息。
     *
     * @param payload contentPayload
     * @return 最终 assistant 历史消息
     */
    public static Map<String, Object> getFinalAssistantMessage(Map<String, Object> payload) {
        return getMap(payload == null ? null : payload.get(KEY_FINAL_ASSISTANT_MESSAGE));
    }

    /**
     * 读取 tool 历史消息列表。
     *
     * @param payload contentPayload
     * @return tool 历史消息列表
     */
    public static List<Map<String, Object>> getToolMessages(Map<String, Object> payload) {
        return getMapList(payload == null ? null : payload.get(KEY_TOOL_MESSAGES));
    }

    /**
     * 判断 payload 是否已经包含新结构化历史。
     *
     * @param payload contentPayload
     * @return true 表示包含新结构
     */
    public static boolean hasStructuredHistory(Map<String, Object> payload) {
        return !getMessageChain(payload).isEmpty()
                || !getAssistantMessage(payload).isEmpty()
                || !getToolMessages(payload).isEmpty();
    }

    /**
     * 读取对象为 Map。
     *
     * @param value 值
     * @return Map 视图
     */
    @SuppressWarnings("unchecked")
    public static Map<String, Object> getMap(Object value) {
        if (!(value instanceof Map<?, ?> source)) {
            return Collections.emptyMap();
        }
        Map<String, Object> result = new LinkedHashMap<>();
        for (Map.Entry<?, ?> entry : source.entrySet()) {
            if (entry.getKey() != null) {
                result.put(String.valueOf(entry.getKey()), entry.getValue());
            }
        }
        return result;
    }

    /**
     * 读取对象为 Map 列表。
     *
     * @param value 值
     * @return Map 列表
     */
    public static List<Map<String, Object>> getMapList(Object value) {
        if (!(value instanceof List<?> source)) {
            return Collections.emptyList();
        }
        List<Map<String, Object>> result = new ArrayList<>(source.size());
        for (Object item : source) {
            Map<String, Object> map = getMap(item);
            if (!map.isEmpty()) {
                result.add(map);
            }
        }
        return result;
    }

    /**
     * 深拷贝 Map 列表。
     *
     * @param source 原始列表
     * @return 深拷贝后的列表
     */
    public static List<Map<String, Object>> deepCopyList(List<Map<String, Object>> source) {
        if (source == null || source.isEmpty()) {
            return new ArrayList<>();
        }
        List<Map<String, Object>> copy = new ArrayList<>(source.size());
        for (Map<String, Object> item : source) {
            copy.add(deepCopyMap(item));
        }
        return copy;
    }

    /**
     * 深拷贝 Map。
     *
     * @param source 原始 Map
     * @return 深拷贝后的 Map
     */
    @SuppressWarnings("unchecked")
    public static Map<String, Object> deepCopyMap(Map<String, Object> source) {
        if (source == null || source.isEmpty()) {
            return new LinkedHashMap<>();
        }
        Map<String, Object> copy = new LinkedHashMap<>();
        for (Map.Entry<String, Object> entry : source.entrySet()) {
            Object value = entry.getValue();
            if (value instanceof Map<?, ?> mapValue) {
                copy.put(entry.getKey(), deepCopyMap((Map<String, Object>) mapValue));
            } else if (value instanceof List<?> listValue) {
                copy.put(entry.getKey(), deepCopyValueList((List<Object>) listValue));
            } else {
                copy.put(entry.getKey(), value);
            }
        }
        return copy;
    }

    private static List<Object> deepCopyValueList(List<Object> source) {
        List<Object> copy = new ArrayList<>(source.size());
        for (Object item : source) {
            if (item instanceof Map<?, ?> mapItem) {
                copy.add(deepCopyMap((Map<String, Object>) mapItem));
            } else if (item instanceof List<?> listItem) {
                copy.add(deepCopyValueList((List<Object>) listItem));
            } else {
                copy.add(item);
            }
        }
        return copy;
    }

    private static Map<String, Object> findAssistant(List<Map<String, Object>> messageChain, boolean reverse) {
        if (messageChain == null || messageChain.isEmpty()) {
            return Collections.emptyMap();
        }
        if (reverse) {
            for (int i = messageChain.size() - 1; i >= 0; i--) {
                Map<String, Object> item = messageChain.get(i);
                if ("assistant".equalsIgnoreCase(String.valueOf(item.get("role")))) {
                    return deepCopyMap(item);
                }
            }
            return Collections.emptyMap();
        }
        for (Map<String, Object> item : messageChain) {
            if ("assistant".equalsIgnoreCase(String.valueOf(item.get("role")))) {
                return deepCopyMap(item);
            }
        }
        return Collections.emptyMap();
    }
}
