package com.njcn.roma.utils;

import cn.hutool.json.JSONObject;

import java.lang.reflect.Field;
import java.time.Instant;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Random;

public class JsonValueFluctuator {
    private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd'T'HHmmssX");


    private static final Random random = new Random();

    /**
     * 模拟给定JSON字符串中数值属性的值上下浮动10%
     * @param jsonString JSON字符串
     * @return 修改后的JSON字符串
     */
    public static JSONObject fluctuateValuesInJson(String jsonString) {
        JSONObject jsonObject = new JSONObject(jsonString);

        // 遍历JSONObject的键值对
        jsonObject.keySet().forEach(key -> {
            Object value = jsonObject.get(key);
            if(key.equals("time")){
                ZonedDateTime dateTime = ZonedDateTime.parse(value.toString(), formatter);
                dateTime = dateTime.minusHours(8);
                Instant instant = dateTime.toInstant();
                jsonObject.put(key,instant);
            }else {
                // 假设只有Double类型（或可以转换为Double的）值需要变动
                if (value instanceof Number) {
                    double numberValue = ((Number) value).doubleValue();
                    double fluctuatedValue = fluctuateValue(numberValue);
                    jsonObject.put(key, fluctuatedValue);
                }
            }

        });

        return jsonObject;
    }


    /**
     * 将对象中所有数字类型的null值字段设置为0（对于包装类型）
     * 注意：此方法不处理基本数据类型，因为基本数据类型不能是null
     *
     * @param obj 要处理的对象
     */
    public static void setNullNumberFieldsToZero(Object obj) {
        if (obj == null) {
            return;
        }

        Field[] fields = obj.getClass().getDeclaredFields();
        for (Field field : fields) {
            // 确保我们可以访问私有字段
            field.setAccessible(true);

            try {
                // 检查字段是否为数字类型的包装类
                if(Integer.class.isAssignableFrom(field.getType())){
                    field.set(obj, 0);
                } else if (Number.class.isAssignableFrom(field.getType())) {
                    // 对于包装类型，我们可以安全地调用get和set
                    // 如果字段为null，则设置为0
                    if (field.get(obj) == null) {
                        field.set(obj, 0.00);
                    }
                }
            } catch (IllegalAccessException e) {
                // 处理反射访问异常
                e.printStackTrace();
            }
        }
    }

    /**
     * 对给定数值进行上下10%的随机浮动
     * @param value 原始数值
     * @return 浮动后的数值
     */
    private static double fluctuateValue(double value) {
        double factor = 1.0 + (random.nextDouble() * 0.2) - 0.1; // 随机产生0.9到1.1之间的因子
        return value * factor;
    }
}
