package com.sino.mci.inbound.engine;

import com.sino.mci.shared.util.JsonUtils;

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

/**
 * 流程定义 JSON 解析器。
 *
 * <p>将 {@code mci_flow_definition.definition_json} 中的 {@code nodes} 与 {@code edges}
 * 解析为 {@link FlowNode} 与 {@link FlowEdge} 对象。</p>
 */
public final class FlowDefinitionParser {

    private FlowDefinitionParser() {
    }

    @SuppressWarnings("unchecked")
    public static List<FlowNode> parseNodes(String definitionJson) {
        Map<String, Object> definition = JsonUtils.fromJson(definitionJson, Map.class);
        if (definition == null) {
            return List.of();
        }
        Object nodesObj = definition.get("nodes");
        if (!(nodesObj instanceof List<?>)) {
            return List.of();
        }
        List<FlowNode> nodes = new ArrayList<>();
        for (Object item : (List<?>) nodesObj) {
            if (!(item instanceof Map<?, ?> map)) {
                continue;
            }
            String id = toString(map.get("id"));
            String type = toString(map.get("type"));
            if (id == null || type == null) {
                continue;
            }
            nodes.add(new FlowNode(id, type, toConfigMap(map.get("config"))));
        }
        return nodes;
    }

    @SuppressWarnings("unchecked")
    public static List<FlowEdge> parseEdges(String definitionJson) {
        Map<String, Object> definition = JsonUtils.fromJson(definitionJson, Map.class);
        if (definition == null) {
            return List.of();
        }
        Object edgesObj = definition.get("edges");
        if (!(edgesObj instanceof List<?>)) {
            return List.of();
        }
        List<FlowEdge> edges = new ArrayList<>();
        for (Object item : (List<?>) edgesObj) {
            if (!(item instanceof Map<?, ?> map)) {
                continue;
            }
            String source = toString(map.get("source"));
            String target = toString(map.get("target"));
            if (source == null || target == null) {
                continue;
            }
            edges.add(new FlowEdge(source, target, toString(map.get("label"))));
        }
        return edges;
    }

    private static Map<String, Object> toConfigMap(Object configObj) {
        if (!(configObj instanceof Map<?, ?> map)) {
            return new HashMap<>();
        }
        Map<String, Object> config = new HashMap<>();
        for (Map.Entry<?, ?> entry : map.entrySet()) {
            config.put(String.valueOf(entry.getKey()), entry.getValue());
        }
        return config;
    }

    private static String toString(Object value) {
        return value != null ? value.toString() : null;
    }
}
