package tech.easyflow.ai.easyagentsflow.repository;

import com.easyagents.flow.core.chain.ChainDefinition;
import com.easyagents.flow.core.node.ConfirmNode;
import com.easyagents.flow.core.parser.ChainParser;
import org.springframework.stereotype.Component;
import tech.easyflow.ai.easyagentsflow.service.WorkflowDatacenterContentService;
import tech.easyflow.ai.entity.Workflow;
import tech.easyflow.ai.node.WorkflowNode;
import tech.easyflow.common.web.exceptions.BusinessException;

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

/**
 * 构建并校验 Agent 与 Skill 使用的 Workflow 冻结快照。
 *
 * <p>Agent Tool 当前按同步调用执行，因此发布投影只能接受不会依赖子工作流热读、
 * 也不会在内部等待人工确认的定义。独立 Workflow 的发布能力不受此组件限制。</p>
 */
@Component
public class AgentWorkflowSnapshotFactory {

    private final ChainParser chainParser;
    private final WorkflowDatacenterContentService contentService;

    /**
     * 创建 Workflow 冻结快照工厂。
     *
     * @param chainParser 工作流定义解析器
     * @param contentService 数据中枢内容准备服务
     */
    public AgentWorkflowSnapshotFactory(ChainParser chainParser,
                                        WorkflowDatacenterContentService contentService) {
        this.chainParser = chainParser;
        this.contentService = contentService;
    }

    /**
     * 编译并校验一份 Agent 可执行的 Workflow 定义。
     *
     * @param workflow 包含完整 content 的 Workflow
     * @return 已准备内容和解析后的定义
     * @throws BusinessException 快照不完整或包含同步 Tool 不支持的节点时抛出
     */
    public PreparedWorkflow prepare(Workflow workflow) {
        if (workflow == null || workflow.getId() == null
                || workflow.getContent() == null || workflow.getContent().isBlank()) {
            throw new BusinessException(409, 4092, "绑定工作流快照不完整，请重新发布工作流");
        }
        String preparedContent = contentService.prepareContent(workflow.getContent());
        ChainDefinition definition;
        try {
            definition = chainParser.parse(preparedContent);
        } catch (BusinessException exception) {
            throw exception;
        } catch (RuntimeException exception) {
            throw new BusinessException(409, 4092, "绑定工作流定义无效，请修复后重新发布", exception);
        }
        if (definition.getNodes() != null
                && definition.getNodes().stream().anyMatch(WorkflowNode.class::isInstance)) {
            throw new BusinessException(409, 4092, "Agent 或 Skill 绑定的工作流暂不支持子工作流节点");
        }
        if (definition.getNodes() != null
                && definition.getNodes().stream().anyMatch(ConfirmNode.class::isInstance)) {
            throw new BusinessException(409, 4092, "Agent 或 Skill 绑定的工作流暂不支持内部确认节点");
        }
        return new PreparedWorkflow(preparedContent, definition);
    }

    /**
     * 构建字段白名单 Workflow 冻结快照。
     *
     * @param workflow 已发布 Workflow
     * @return 仅包含 Runtime 所需字段的快照
     * @throws BusinessException Workflow 不兼容同步 Agent Tool 时抛出
     */
    public Map<String, Object> snapshot(Workflow workflow) {
        PreparedWorkflow prepared = prepare(workflow);
        Map<String, Object> snapshot = new LinkedHashMap<>();
        snapshot.put("id", workflow.getId());
        snapshot.put("title", workflow.getTitle());
        snapshot.put("description", workflow.getDescription());
        snapshot.put("englishName", workflow.getEnglishName());
        snapshot.put("revision", workflow.getRevision());
        snapshot.put("content", prepared.content());
        return snapshot;
    }

    /**
     * Agent 可执行 Workflow 的准备结果。
     *
     * @param content 已完成服务端占位处理的定义内容
     * @param definition 解析后的工作流定义
     */
    public record PreparedWorkflow(String content, ChainDefinition definition) {
    }
}
