package com.hdkj.lt.modle.dto.util;

import com.alibaba.fastjson.parser.DefaultJSONParser;
import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.*;

import java.io.IOException;
import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.math.RoundingMode;

/**
 * @author luorui
 * @date 2025/7/7 21:10
 */
public class CurrentValueJsonUtil {


    /**
     * 对电流值解析处理 序列化
     * 1.可能为 null
     * 2.可能是NaN
     * 3.浮点型小数
     * 4.科学计数法
     * 要求四舍五入保留2位小数
     */
    public static class CurrentValueSerializer extends JsonSerializer<Double> {
        @Override
        public void serialize(Double value, JsonGenerator generator, SerializerProvider provider) throws IOException {
            //1.可能为 null
            if (value == null) {
                generator.writeNull();
                return;
            }
            //2.可能是NaN
            if (Double.isNaN(value)) {
                generator.writeNull();
                return;
            }
            //3.浮点型小数 4.科学计数法
            try{
                //使用BigDecimal处理科学计数法并确保精度
                BigDecimal bd= new BigDecimal(value.toString());
                BigDecimal rounded = bd.setScale(2, RoundingMode.HALF_UP);
                //输出格式化后的字符串，避免科学计数法
                generator.writeString(rounded.toPlainString());
            }catch (Exception e){
                generator.writeNull();
            }
        }
    }

    /**  反序列化工具 jackson
     * 对电流值解析处理
     * 1.可能为 null
     * 2.可能是NaN
     * 3.浮点型小数
     * 4.科学计数法
     * 要求四舍五入保留2位小数
     */
    public static class CurrentValueDeserializer extends JsonDeserializer<Double> {
        @Override
        public Double deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
            JsonNode node = jsonParser.getCodec().readTree(jsonParser);
            //1.可能为 null
            if (node.isNull() || node.isTextual() && node.asText().trim().isEmpty()) {
                return null;
            }
            //2.可能是NaN
            if (node.isTextual() && "NaN".equalsIgnoreCase(node.asText().trim())) {
                return null;
            }
            //3.浮点型小数 4.科学计数法
            try{
                //使用BigDecimal处理科学计数法并确保精度
                String value = node.asText();
                BigDecimal bd= new BigDecimal(value.toString());
                BigDecimal rounded = bd.setScale(2,RoundingMode.HALF_UP);
                //输出格式化后的字符串，避免科学计数法
                return rounded.doubleValue();
            } catch (Exception e){
                //无法解析的情况
                return null;
            }
        }
    }

    /**  反序列化工具 fastJson
     * 对电流值解析处理
     * 1.可能为 null
     * 2.可能是NaN
     * 3.浮点型小数
     * 4.科学计数法
     * 要求四舍五入保留2位小数
     */
    public static class CurrentValueDeserializerFastJson implements ObjectDeserializer {
        @Override
        public Double deserialze(DefaultJSONParser defaultJSONParser, Type type, Object o) {
            Object value = defaultJSONParser.parse();
            //1.可能为 null
            if (value==null || value.toString().trim().isEmpty() ||"null".equalsIgnoreCase(value.toString().trim())) {
                return null;
            }
            //2.可能是NaN
            if ("NaN".equalsIgnoreCase(value.toString().trim())) {
                return null;
            }
            //3.浮点型小数 4.科学计数法
            try{
                //使用BigDecimal处理科学计数法并确保精度
                BigDecimal bd= new BigDecimal(value.toString());
                BigDecimal rounded = bd.setScale(2,RoundingMode.HALF_UP);
                //输出格式化后的字符串，避免科学计数法
//                String str = bd.toPlainString();
                Double d = rounded.doubleValue();
                return d;
            } catch (Exception e){
                //无法解析的情况
                return null;
            }
        }

        @Override
        public int getFastMatchToken() {
            return 0;
        }
    }

}
