package com.eactive.testmaster.loadtest.service;

import com.eactive.testmaster.client.dto.internal.ScenarioNode;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.HashMap;
import java.util.Map;

public class LoadTestGraphBuilder {

    public static ScenarioNode getTopNode(String data) {
        try {
            Map<String, ScenarioNode> graphData = loadData(data);
            return getHead(extractGraphFromStart(graphData));
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static Map<String, ScenarioNode> loadData(String data) throws JsonProcessingException {
        Map<String, ScenarioNode> graphData;
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        graphData = objectMapper.readValue(data, new TypeReference<Map<String, ScenarioNode>>() {
        });
        return graphData;
    }



    public static ScenarioNode getHead(Map<String, ScenarioNode> graphData) {
        for (ScenarioNode node : graphData.values()) {
            if ("start".equals(node.getClassName())) {
                return node;
            }
        }
        return null;
    }

    public static Map<String, ScenarioNode> extractGraphFromStart(Map<String, ScenarioNode> graphData) {
        Map<String, ScenarioNode> graph = new HashMap<>();

        // Helper function to recursively build the graph
        graphData.forEach((nodeId, node) -> {
            if ("start".equals(node.getClassName())) {
                buildGraph(nodeId, graph, graphData);
                return; // Break the forEach loop assuming there's only one start node
            }
        });

        return graph;
    }

    private static void buildGraph(String nodeId, Map<String, ScenarioNode> graph, Map<String, ScenarioNode> graphData) {
        ScenarioNode node = graphData.get(nodeId);
        if (node == null || graph.containsKey(nodeId)) {
            return;
        }

        graph.put(nodeId, node);

        if (node.getOutputs() != null) {
            node.getOutputs().values().forEach(outputList -> {
                outputList.getConnections().forEach(output -> {
                    ScenarioNode v = graphData.get(output.getNode());
                    graph.get(nodeId).addNode(v);
                    buildGraph(output.getNode(), graph, graphData); // Recurse
                });
            });
        }
    }

    public static void main(String[] args) {
        try {
            Map<String, ScenarioNode> graphData = loadData(testData);
            LoadTestGraphBuilder graphBuilder = new LoadTestGraphBuilder();
            Map<String, ScenarioNode> graph = graphBuilder.extractGraphFromStart(graphData);
            ScenarioNode start = graphBuilder.getHead(graph);

            System.out.println(start);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
    }

    private static String testData = "{\n"
        + "    \"1\": {\n"
        + "        \"id\": 1,\n"
        + "        \"name\": \"Start\",\n"
        + "        \"data\": {},\n"
        + "        \"class\": \"start\",\n"
        + "        \"html\": \"\\n                        <div>\\n                            <div><i class=\\\"fas fa-play\\\"></i> Start </div>\\n                        </div>\\n                    \",\n"
        + "        \"typenode\": false,\n"
        + "        \"inputs\": {},\n"
        + "        \"outputs\": {\n"
        + "            \"output_1\": {\n"
        + "                \"connections\": [\n"
        + "                    {\n"
        + "                        \"node\": \"2\",\n"
        + "                        \"output\": \"input_1\"\n"
        + "                    }\n"
        + "                ]\n"
        + "            }\n"
        + "        },\n"
        + "        \"pos_x\": 100,\n"
        + "        \"pos_y\": 100\n"
        + "    },\n"
        + "    \"2\": {\n"
        + "        \"id\": 2,\n"
        + "        \"name\": \"잔액조회\",\n"
        + "        \"data\": {\n"
        + "            \"collection\": \"b9748a16-bbb7-4dcc-8521-88e76a0b2ee8\",\n"
        + "            \"id\": \"51351280-a72f-4886-8426-70d2932a2f48\",\n"
        + "            \"index\": \"2\",\n"
        + "            \"nodeType\": \"api\",\n"
        + "            \"name\": \"잔액조회\"\n"
        + "        },\n"
        + "        \"class\": \"api\",\n"
        + "        \"html\": \"<div><div class=\\\"title-box\\\">API</div><div class=\\\"box\\\">잔액조회</div></div>\",\n"
        + "        \"typenode\": false,\n"
        + "        \"inputs\": {\n"
        + "            \"input_1\": {\n"
        + "                \"connections\": [\n"
        + "                    {\n"
        + "                        \"node\": \"1\",\n"
        + "                        \"input\": \"output_1\"\n"
        + "                    }\n"
        + "                ]\n"
        + "            }\n"
        + "        },\n"
        + "        \"outputs\": {\n"
        + "            \"output_1\": {\n"
        + "                \"connections\": [\n"
        + "                    {\n"
        + "                        \"node\": \"3\",\n"
        + "                        \"output\": \"input_1\"\n"
        + "                    }\n"
        + "                ]\n"
        + "            }\n"
        + "        },\n"
        + "        \"pos_x\": 328,\n"
        + "        \"pos_y\": 184\n"
        + "    },\n"
        + "    \"3\": {\n"
        + "        \"id\": 3,\n"
        + "        \"name\": \"거래내역조회\",\n"
        + "        \"data\": {\n"
        + "            \"collection\": \"b9748a16-bbb7-4dcc-8521-88e76a0b2ee8\",\n"
        + "            \"id\": \"3f156dc1-f71b-4a26-a778-64a2ddd2b54f\",\n"
        + "            \"index\": \"3\",\n"
        + "            \"nodeType\": \"api\",\n"
        + "            \"name\": \"거래내역조회\"\n"
        + "        },\n"
        + "        \"class\": \"api\",\n"
        + "        \"html\": \"<div><div class=\\\"title-box\\\">API</div><div class=\\\"box\\\">거래내역조회</div></div>\",\n"
        + "        \"typenode\": false,\n"
        + "        \"inputs\": {\n"
        + "            \"input_1\": {\n"
        + "                \"connections\": [\n"
        + "                    {\n"
        + "                        \"node\": \"2\",\n"
        + "                        \"input\": \"output_1\"\n"
        + "                    }\n"
        + "                ]\n"
        + "            }\n"
        + "        },\n"
        + "        \"outputs\": {\n"
        + "            \"output_1\": {\n"
        + "                \"connections\": []\n"
        + "            }\n"
        + "        },\n"
        + "        \"pos_x\": 654,\n"
        + "        \"pos_y\": 301\n"
        + "    }\n"
        + "}";
}
