package com.energy.manage.service.test;

import com.energy.manage.service.domain.dto.analysis.AnalysisDto;
import com.energy.manage.service.property.analysis.AlgorithmProperties;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.IntNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import io.swagger.util.Json;
import org.apache.commons.lang3.StringUtils;

import java.lang.reflect.Field;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

/**
 * @author chy
 * @date 2024/6/2 19:06
 * @desc
 */
public class TestJson {

    private static  ObjectMapper mapper = new ObjectMapper();


    public static void main(String[] args) throws JsonProcessingException {
        String jsonString = "{\n" +
                "    \"dataContractType\": {\n" +
                "        \"type\": \"analysisExecuteOrder\",\n" +
                "        \"version\": \"1.2.0\"\n" +
                "    },\n" +
                "    \"dataContract\": {\n" +
                "        \"autoOrManual\": \"automatic\",\n" +
                "        \"dataFilter\": {\n" +
                "            \"powerFarmID\": \"010-00001\",\n" +
                "            \"turbines\": null,\n" +
                "            \"dataBatchNum\": \"B2024042211-0\",\n" +
                "            \"beginTime\": \"2023-01-01 00:00:00\",\n" +
                "            \"endTime\": \"2023-12-31 23:59:59\",\n" +
                "            \"excludingMonths\": null,\n" +
                "            \"customFilter\": {\n" +
                "                \"valueWindSpeed\": {\n" +
                "                    \"min\": null,\n" +
                "                    \"max\": null\n" +
                "                },\n" +
                "                \"valuePitchAngle\": {\n" +
                "                    \"min\": null,\n" +
                "                    \"max\": null\n" +
                "                },\n" +
                "                \"valueActivePower\": {\n" +
                "                    \"min\": null,\n" +
                "                    \"max\": null\n" +
                "                },\n" +
                "                \"valueGeneratorSpeed\": {\n" +
                "                    \"min\": null,\n" +
                "                    \"max\": null\n" +
                "                }\n" +
                "            }\n" +
                "        },\n" +
                "        \"configAnalysis\": [],\n" +
                "        \"graphSets\": {\n" +
                "            \"DgeneratorSpeed\": {\n" +
                "                \"step\": 5,\n" +
                "                \"min\": 0,\n" +
                "                \"max\": 30\n" +
                "            },\n" +
                "            \"DgeneratorTorque\": {\n" +
                "                \"step\": 10000,\n" +
                "                \"min\": 0,\n" +
                "                \"max\": 100000\n" +
                "            },\n" +
                "            \"IgeneratorSpeed\": {\n" +
                "                \"step\": 200,\n" +
                "                \"min\": 1000,\n" +
                "                \"max\": 2000\n" +
                "            },\n" +
                "            \"IgeneratorTorque\": {\n" +
                "                \"step\": 2000,\n" +
                "                \"min\": 0,\n" +
                "                \"max\": 12000\n" +
                "            },\n" +
                "            \"cp\": {\n" +
                "                \"step\": 0.5,\n" +
                "                \"min\": 0,\n" +
                "                \"max\": 2\n" +
                "            },\n" +
                "            \"tsr\": {\n" +
                "                \"step\": 5,\n" +
                "                \"min\": 0,\n" +
                "                \"max\": 30\n" +
                "            },\n" +
                "            \"pitchAngle\": {\n" +
                "                \"step\": 1,\n" +
                "                \"min\": -1,\n" +
                "                \"max\": 20\n" +
                "            },\n" +
                "            \"activePower\": {\n" +
                "                \"step\": 250,\n" +
                "                \"min\": 0,\n" +
                "                \"max\": 2000\n" +
                "            }\n" +
                "        }\n" +
                "    }\n" +
                "}";
        JsonNode rootNode = mapper.readTree(jsonString);
//        AnalysisDto dto = new AnalysisDto();
//        dto.setBeginTime("1234-12-12 00:00:12");
//        updateNodesByPropertyName(rootNode, "beginTime", dto);
//        String propertyNameToFind = "beginTime";
//        List<JsonNode> matchingNodes = findNodesByPropertyName(rootNode, propertyNameToFind);
//
//        for (JsonNode node : matchingNodes) {
//            System.out.println("Found matching node: " + mapper.writerWithDefaultPrettyPrinter().writeValueAsString(node));
//        }

        AnalysisDto dto = new AnalysisDto();
        dto.setScada("all");
        dto.setAutoOrManual("manual");
        dto.setBeginTime("1234-12-12 00:00:12");
        dto.setExcludingMonths(Arrays.asList("1","2","3"));
        dto.setTurbines(Arrays.asList("456","789"));
        dto.setValueActivePower(Arrays.asList(1.2,2.3));
        dto.setConfigAnalysis(Arrays.asList("algorithm.powerOscillationAnalyst|PowerOscillationAnalyst|executeAnalysis|minute","algorithm.pitchTSRCpAnalyst|PitchTSRCpAnalyst|executeAnalysis|second"));
        setValue(dto,rootNode);
        for (JsonNode node : rootNode) {
            System.out.println("Found matching node: " + mapper.writerWithDefaultPrettyPrinter().writeValueAsString(node));
        }

    }

    public static List<JsonNode> findNodesByPropertyName(JsonNode node, String propertyName) {
        List<JsonNode> result = new ArrayList<>();
        findNodesByPropertyNameRecursive(node, propertyName, result);
        return result;
    }

    private static void findNodesByPropertyNameRecursive(JsonNode node, String propertyName, List<JsonNode> result) {
        if (node.isObject()) {
            node.fields().forEachRemaining(entry -> {
                if (entry.getKey().equals(propertyName)) {
                    // 匹配到属性名称，添加节点到结果列表
                    result.add(entry.getValue());
                }
                // 递归搜索子节点
                findNodesByPropertyNameRecursive(entry.getValue(), propertyName, result);
            });
        }
    }

    private static void updateNodesByPropertyName(JsonNode rootNode, String propertyName,Object value,String scada) {
        if (rootNode.isObject()) {
            rootNode.fields().forEachRemaining(entry -> {
                // 匹配到属性名称，进行值的修改
                if (entry.getKey().equals(propertyName)) {
                    //如果当前节点没有子节点直接复制
                    if(!entry.getValue().fields().hasNext() && !propertyName.equals("configAnalysis")){
                        if(StringUtils.endsWithAny(propertyName,"turbines","excludingMonths")){
                            ArrayNode arrayNode = mapper.createArrayNode();
                            ((List<String>)value).stream().forEach(item-> arrayNode.add(item));
                            ((ObjectNode) rootNode).set(propertyName,arrayNode);
                        }else{
                            ((ObjectNode) rootNode).put(propertyName, value.toString());
                        }
                    }else {
                        try {
                            assignmentByPropertyName(entry.getValue(), propertyName, value,scada);
                        } catch (JsonProcessingException e) {
                            e.printStackTrace();
                        }
                    }
                }
                // 递归搜索子节点
                updateNodesByPropertyName(entry.getValue(), propertyName, value,scada);
            });
        }
    }

    /**
     * 获取前端参数
     * @param analysisDto
     * @return
     */
    private static void setValue(AnalysisDto analysisDto,JsonNode rootNode) {
        //前端入参类
        Field[] analysisFields = analysisDto.getClass().getDeclaredFields();
        Arrays.asList(analysisFields).stream().forEach(field -> {
            field.setAccessible(true);
            try {
                if(field.get(analysisDto) != null){
                    updateNodesByPropertyName(rootNode, field.getName(), field.get(analysisDto),analysisDto.getScada());
                }
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        });
    }


    private static void  assignmentByPropertyName(JsonNode subNode, String propertyName, Object newValue,String scada) throws JsonProcessingException {
        //图像设置特殊处理
        if("valueActivePower".contains(propertyName)){
//        if(AlgorithmProperties.graphSetsProperties.contains(propertyName)){
            List<Integer> list = (List) newValue;
            AtomicInteger index = new AtomicInteger(0);
            subNode.fields().forEachRemaining(entry -> {
                System.out.println(entry.getKey() + "======");
                ((ObjectNode) subNode).put(entry.getKey(), list.get(index.get()));
                index.incrementAndGet();
            });
            return ;
        }
        //分析类型特殊处理
//        if("turbines".equals(propertyName)){
//            dealArrayNode(subNode, newValue);
//            return;
//        }
        //分析类型特殊处理
        if("configAnalysis".equals(propertyName)){
            dealConfigAnalysis(subNode, newValue,scada);
            return;
        }

    }


    private static String json = "{\n" +
            "    \"package\": \"\",\n" +
            "    \"className\": \"\",\n" +
            "    \"methodName\": \"\",\n" +
            "    \"scada\": \"\"\n" +
            "}";



    /**
     * 数组类型处理
     * @param subNode
     * @param newValue
     */
    private static void dealArrayNode(JsonNode subNode, Object newValue) throws JsonProcessingException {
        ArrayNode arrayNode = (ArrayNode) subNode;
        List<String> tu = (List) newValue;
        tu.stream().forEach(item -> arrayNode.add(item));
    }

    /**
     * 分析类型处理
     * @param subNode
     * @param newValue
     */
    private static void dealConfigAnalysis(JsonNode subNode, Object newValue,String scada) throws JsonProcessingException {
        ArrayNode arrayNode = (ArrayNode) subNode;
        List<String> analysisTypes = (List) newValue;
        for(int i = 0 ; i < analysisTypes.size() ; i++){
            JsonNode childNode = mapper.readTree(json);
            //分析类型解析
            String[] types = analysisTypes.get(i).split("\\|");
            AtomicInteger index =  new AtomicInteger(0);
            childNode.fields().forEachRemaining(entry-> {
                if(StringUtils.isNotBlank(scada) && entry.getKey().equals("scada")){
                    ((ObjectNode)childNode).put(entry.getKey(), scada);
                }else{
                    ((ObjectNode)childNode).put(entry.getKey(), types[index.get()]);
                }
                index.incrementAndGet();
            });
            arrayNode.add(childNode);
        }
    }
}
