package tech.easyflow.ai.node;

import com.easyagents.core.util.StringUtil;
import com.easyagents.flow.core.chain.Chain;
import com.easyagents.flow.core.chain.Parameter;
import com.easyagents.flow.core.node.BaseNode;
import tech.easyflow.common.util.SpringContextUtil;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 工作流文件内容提取节点。
 *
 * <p>节点输入为统一文件对象，桥接支持的文档类型优先交给统一文档解析服务，
 * 其他类型继续走默认文档读取器。</p>
 *
 * @author Codex
 * @since 2026-04-14
 */
public class DocNode extends BaseNode {

    /**
     * 执行文件内容提取。
     *
     * @param chain 当前流程链
     * @return 节点输出
     */
    @Override
    public Map<String, Object> execute(Chain chain) {
        Map<String, Object> map = chain.getState().resolveParameters(this);
        DocNodeFileContentExtractor extractor = SpringContextUtil.getBean(DocNodeFileContentExtractor.class);
        List<DocNodeFileContentExtractor.DocExtractedDocument> documents = extractor.extractDocuments(map.get("file"));

        List<Map<String, Object>> documentMaps = new ArrayList<>();
        for (DocNodeFileContentExtractor.DocExtractedDocument document : documents) {
            documentMaps.add(document.toMap());
        }

        Map<String, String> outputKeyMapping = resolveOutputKeyMapping();
        Map<String, Object> res = new HashMap<>();
        res.put(outputKeyMapping.get("documents"), documentMaps);
        return res;
    }

    /**
     * 根据节点输出定义解析运行态输出键名。
     *
     * @return 逻辑字段到实际输出键名的映射
     */
    private Map<String, String> resolveOutputKeyMapping() {
        Map<String, String> mapping = new HashMap<>();
        mapping.put("documents", "documents");

        List<Parameter> outputDefs = getOutputDefs();
        if (outputDefs == null || outputDefs.isEmpty()) {
            return mapping;
        }

        String[] logicalKeys = {"documents"};
        for (int i = 0; i < outputDefs.size() && i < logicalKeys.length; i++) {
            Parameter outputDef = outputDefs.get(i);
            String name = outputDef == null ? null : outputDef.getName();
            if (StringUtil.hasText(name)) {
                mapping.put(logicalKeys[i], name);
            }
        }
        return mapping;
    }
}
