package com.agent.management.engine.executor;

import com.agent.management.engine.*;
import com.agent.management.config.WorkflowProperties;
import com.agent.management.service.AiModelService;
import com.fasterxml.jackson.databind.JsonNode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Component;

import java.util.LinkedHashMap;
import java.util.Map;

/**
 * 智能操作节点执行器（内置 LLM 模式）
 * 根据 actionPrompt（操作要求）调用 LLM，支持 modelId 指定模型
 *
 * <p>当节点声明 outputs 时（与 LLM 节点一致），走 {@link StructuredOutputHelper#extractWithRetry}
 * 统一结构化输出流程；未声明 outputs 时降级为单变量透传。</p>
 *
 * <p>当 hermes.enabled=true 时此类不激活，由 HermesSmartActionExecutor 替代。</p>
 */
@Slf4j
@Component
@ConditionalOnProperty(name = "hermes.enabled", havingValue = "false", matchIfMissing = true)
public class SmartActionExecutor implements NodeExecutor {

    private final AiModelService aiModelService;
    private final ChatClient.Builder fallbackBuilder;
    private final WorkflowProperties workflowProperties;

    public SmartActionExecutor(ChatClient.Builder chatClientBuilder,
                               AiModelService aiModelService,
                               WorkflowProperties workflowProperties) {
        this.fallbackBuilder = chatClientBuilder;
        this.aiModelService = aiModelService;
        this.workflowProperties = workflowProperties;
    }

    @Override
    public String getType() {
        return "smartAction";
    }

    @Override
    public NodeExecutionResult execute(String nodeId, JsonNode data, WorkflowContext context, NodeWorkspace workspace) {
        String actionPrompt = TemplateRenderer.render(
                data.path("actionPrompt").asText(""), workspace.getVariables());

        if (actionPrompt.isEmpty()) {
            return NodeExecutionResult.success(nodeId,
                    NodeOutputEnvelope.failure("智能操作节点的操作要求为空").toMap());
        }

        ChatClient client = resolveChatClient(data);
        JsonNode outputsDecl = data.path("outputs");
        boolean structured = StructuredOutputHelper.needsStructuredOutput(data);
        // 智能操作节点没有用户可配置的 systemPrompt，仅注入当前节点明确定义的输入变量作为系统提示
        String systemPrompt = ContextPromptHelper.buildInputContextSystemPrompt(data, workspace);

        log.info("[SmartAction] 节点 {} 开始执行, actionPrompt长度={}, structured={}",
                nodeId, actionPrompt.length(), structured);

        // 结构化模式：走与 LLM 节点一致的 extractWithRetry 流程
        if (structured) {
            RetryPolicy policy = RetryPolicy.fromNodeData(data, workflowProperties);
            StructuredOutputHelper.ExtractionResult ext =
                    StructuredOutputHelper.extractWithRetry(client, actionPrompt, systemPrompt, outputsDecl, policy);

            if (ext.errorMessage != null) {
                log.warn("[SmartAction] 节点 {} 结构化输出失败（重试 {} 次）: {}",
                        nodeId, ext.attempts, ext.errorMessage);
                return NodeExecutionResult.success(nodeId,
                        NodeOutputEnvelope.failure(ext.errorMessage).toMap());
            }

            String msg = "智能操作执行成功" + (ext.attempts > 1 ? "（重试 " + (ext.attempts - 1) + " 次）" : "");
            log.info("[SmartAction] 节点 {} 完成, 输出字段数={}, attempts={}",
                    nodeId, ext.data.size(), ext.attempts);
            return NodeExecutionResult.success(nodeId,
                    NodeOutputEnvelope.success(msg, ext.data).toMap());
        }

        // 降级模式：未声明 outputs，按默认变量名写一个字段
        try {
            var request = client.prompt().user(actionPrompt);
            if (!systemPrompt.isEmpty()) {
                request = request.system(systemPrompt);
            }
            String result = request.call().content();

            if (result == null || result.isBlank()) {
                return NodeExecutionResult.success(nodeId,
                        NodeOutputEnvelope.failure("智能操作返回空结果").toMap());
            }

            String varName = NodeTypeUtils.resolveOutputVarName(data, "result");
            Map<String, Object> dataMap = new LinkedHashMap<>();
            dataMap.put(varName, result);

            log.info("[SmartAction] 节点 {} 完成, 结果长度={}", nodeId, result.length());
            return NodeExecutionResult.success(nodeId,
                    NodeOutputEnvelope.success("智能操作执行成功", dataMap).toMap());

        } catch (Exception e) {
            log.error("[SmartAction] 节点 {} 调用失败: {}", nodeId, e.getMessage());
            return NodeExecutionResult.success(nodeId,
                    NodeOutputEnvelope.failure("智能操作调用失败: " + e.getMessage()).toMap());
        }
    }

    private ChatClient resolveChatClient(JsonNode data) {
        long modelId = data.path("modelId").asLong(0);
        if (modelId > 0) {
            try {
                return aiModelService.getChatClient(modelId);
            } catch (Exception e) {
                log.warn("[SmartAction] 指定模型 {} 获取失败，回退到默认模型: {}", modelId, e.getMessage());
            }
        }
        // 每次动态获取默认模型，确保模型配置变更能及时生效
        return aiModelService.getChatClientOrFallback(fallbackBuilder);
    }
}
