package com.gzzm.lobster.tool;

import com.gzzm.lobster.common.JsonUtil;
import com.gzzm.lobster.common.PendingRequestType;
import com.gzzm.lobster.common.ToolResultStatus;

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

/**
 * ToolResult —— 工具统一结果 / Unified tool execution result.
 */
public final class ToolResult {

    private final ToolResultStatus status;
    private final String message;
    private final Map<String, Object> data;
    private final List<String> artifactIds;
    private final String pendingRequestId;
    /** pending 类型（仅 status=pending 时有值）/ Pending type when status=pending. */
    private final PendingRequestType pendingType;
    /** pending 的真实标题（用于前端弹窗） / True pending title for the UI dialog. */
    private final String pendingTitle;
    private final Map<String, Object> diagnostics;

    private ToolResult(ToolResultStatus status, String message, Map<String, Object> data,
                       List<String> artifactIds, String pendingRequestId,
                       PendingRequestType pendingType, String pendingTitle,
                       Map<String, Object> diagnostics) {
        this.status = status;
        this.message = message == null ? "" : message;
        this.data = data == null ? Collections.<String, Object>emptyMap() : Collections.unmodifiableMap(new LinkedHashMap<>(data));
        this.artifactIds = artifactIds == null ? Collections.<String>emptyList() : artifactIds;
        this.pendingRequestId = pendingRequestId;
        this.pendingType = pendingType;
        this.pendingTitle = pendingTitle;
        this.diagnostics = diagnostics == null ? Collections.<String, Object>emptyMap() : diagnostics;
    }

    public static ToolResult ok(String message, Map<String, Object> data) {
        return new ToolResult(ToolResultStatus.ok, message, data, null, null, null, null, null);
    }

    public static ToolResult okData(Map<String, Object> data) {
        return new ToolResult(ToolResultStatus.ok, null, data, null, null, null, null, null);
    }

    /**
     * 带 artifactIds 的 ok —— 供 code_exec / write_file 等产生 Artifact 的工具使用.
     * AgentRuntime 用此字段驱动 AgentLoopDetector.ProgressSignal.artifactProduced，
     * 让 loop 检测正确识别 "LLM 确实在产出新工件，不是在空转".
     */
    public static ToolResult okWithArtifacts(String message, Map<String, Object> data, List<String> artifactIds) {
        return new ToolResult(ToolResultStatus.ok, message, data, artifactIds, null, null, null, null);
    }

    public static ToolResult error(String message) {
        return new ToolResult(ToolResultStatus.error, message, null, null, null, null, null, null);
    }

    public static ToolResult error(String message, Map<String, Object> diagnostics) {
        return new ToolResult(ToolResultStatus.error, message, null, null, null, null, null, diagnostics);
    }

    public static ToolResult errorData(String message, Map<String, Object> data) {
        return new ToolResult(ToolResultStatus.error, message, data, null, null, null, null, null);
    }

    /**
     * 工具返回 pending 态 / Pending tool result.
     *
     * @param pendingRequestId 后端创建的 pending 请求 id
     * @param type             交互类型（confirm_action / ask_user / wait_external_event / wait_timer）
     * @param pendingTitle     pending 的真实标题（直接显示为前端弹窗标题，
     *                         如"覆盖原 OA 文件"、"补充说明"），**不是**工具的通用提示文案。
     * @param userMessage      工具返回给 LLM 的通用提示，例如「已发出确认请求，等待用户响应」
     */
    public static ToolResult pending(String pendingRequestId, PendingRequestType type,
                                     String pendingTitle, String userMessage) {
        Map<String, Object> data = new LinkedHashMap<>();
        data.put("pendingRequestId", pendingRequestId);
        data.put("status", "PENDING");
        if (type != null) data.put("type", type.name());
        if (pendingTitle != null && !pendingTitle.isEmpty()) data.put("title", pendingTitle);
        return new ToolResult(ToolResultStatus.pending, userMessage, data, null,
                pendingRequestId, type, pendingTitle, null);
    }

    /** 向后兼容：未声明 title 时用 userMessage 兜底。 */
    public static ToolResult pending(String pendingRequestId, PendingRequestType type, String userMessage) {
        return pending(pendingRequestId, type, userMessage, userMessage);
    }

    /** 向后兼容：未声明 type 时默认 confirm_action。 */
    public static ToolResult pending(String pendingRequestId, String userMessage) {
        return pending(pendingRequestId, PendingRequestType.confirm_action, userMessage, userMessage);
    }

    public ToolResultStatus getStatus() { return status; }
    public String getMessage() { return message; }
    public Map<String, Object> getData() { return data; }
    public List<String> getArtifactIds() { return artifactIds; }
    public String getPendingRequestId() { return pendingRequestId; }
    public PendingRequestType getPendingType() { return pendingType; }
    public String getPendingTitle() { return pendingTitle; }
    public Map<String, Object> getDiagnostics() { return diagnostics; }

    /** 规范化为 tool message 内容文本 / Canonical string form fed back to the LLM. */
    public String toToolMessageContent() {
        Map<String, Object> map = new LinkedHashMap<>();
        map.put("status", status.name());
        if (message != null && !message.isEmpty()) map.put("message", message);
        if (!data.isEmpty()) map.put("data", data);
        if (artifactIds != null && !artifactIds.isEmpty()) map.put("artifactIds", artifactIds);
        if (pendingRequestId != null) map.put("pendingRequestId", pendingRequestId);
        return JsonUtil.toJson(map);
    }
}
