package thyyxxk.webserver.utils;

import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import thyyxxk.webserver.config.ColumnName;

import java.lang.reflect.Field;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author xc
 */
@Slf4j
public class CampareObject {

    public static JSONObject getChangedFieldsOfObject(Object oldObj, Object newObj) {
        JSONObject resultObject = new JSONObject();
        if (oldObj != null && newObj != null) {
            Field[] fields = oldObj.getClass().getDeclaredFields();
            for (Field f : fields) {
                // 获取字段名 在实体类中是什么样子这里就是什么样子
                String key = f.getName();
                try {
                    boolean annotationPresent2 = f.isAnnotationPresent(ColumnName.class);
                    if (annotationPresent2) {
                        Object oldValue = EntityStringTrim.getFieldValue(oldObj, key);
                        ColumnName name = f.getAnnotation(ColumnName.class);
                        // 获取注解值
                        String nameStr = name.name();
                        if (StringUtil.isBlank(nameStr)) {
                            nameStr = humpToUnderline(key);
                        }
                        Object newValue = EntityStringTrim.getFieldValue(newObj, key);
                        if (!Objects.equals(newValue, oldValue)) {
                            resultObject.put(nameStr, newValue);
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        return resultObject;
    }

    public static String getChangedFieldsOfSql(Object oldObj, Object newObj) {
        StringBuilder stringBuilder = new StringBuilder();
        if (oldObj != null && newObj != null) {
            Field[] fields = oldObj.getClass().getDeclaredFields();
            for (Field f : fields) {
                // 获取字段名 在实体类中是什么样子这里就是什么样子
                String key = f.getName();
                try {
                    boolean annotationPresent2 = f.isAnnotationPresent(ColumnName.class);
                    if (annotationPresent2) {
                        Object oldValue = EntityStringTrim.getFieldValue(oldObj, key);
                        ColumnName name = f.getAnnotation(ColumnName.class);
                        // 获取注解值
                        String nameStr = name.name();
                        if (StringUtil.isBlank(nameStr)) {
                            nameStr = humpToUnderline(key);
                        }
                        Object newValue = EntityStringTrim.getFieldValue(newObj, key);

                        if (!Objects.equals(newValue, oldValue)) {
                            if ("java.lang.String".equals(newValue.getClass().getTypeName())) {
                                if (StringUtil.isBlank((String) newValue)) {
                                    newValue = null;
                                }
                            }
                            if (null == newValue) {
                                nameStr = nameStr + "=" + null;
                                stringBuilder.append(nameStr).append(",");
                            } else {
                                stringBuilder.append(nameStr).append("='").append(newValue).append("',");
                            }
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        String sql = stringBuilder.toString();
        if (StringUtil.isBlank(sql)) {
            return sql;
        }
        return sql.substring(0, stringBuilder.length() - 1);
    }

    public static String humpToUnderline(String str) {
        String regex = "([A-Z])";
        Matcher matcher = Pattern.compile(regex).matcher(str);
        while (matcher.find()) {
            String target = matcher.group();
            str = str.replaceAll(target, "_" + target.toLowerCase());
        }
        return str;
    }

}
