package org.xyzh.common.utils.validation.method;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;

/**
 * @description 至少填几个字段校验方法
 * @filename MinFieldsValidateMethod.java
 * @author yslg
 * @copyright yslg
 * @since 2025-12-18
 */
public class MinFieldsValidateMethod implements ObjectValidateMethod {
    

    private final List<String> fieldNames;
    private final int minCount;
    private final String errorMessage;

    public MinFieldsValidateMethod(List<String> fieldNames, List<String> fieldLabels) {
        this(fieldNames, fieldLabels, 1);
    }

    public MinFieldsValidateMethod(List<String> fieldNames, List<String> fieldLabels, int minCount) {
        this.fieldNames = fieldNames;
        this.minCount = minCount;
        this.errorMessage = String.join("、", fieldLabels) + "至少填写" + minCount + "项";
    }

    @Override
    public Boolean validate(Object obj) {
        if (obj == null || fieldNames == null || fieldNames.isEmpty()) {
            return false;
        }

        int count = 0;
        for (String fieldName : fieldNames) {
            try {
                Object fieldValue = getFieldValue(obj, fieldName);
                if (fieldValue != null) {
                    if (fieldValue instanceof String) {
                        if (!((String) fieldValue).trim().isEmpty()) {
                            count++;
                        }
                    } else {
                        count++;
                    }
                }
            } catch (Exception e) {
                // 字段不存在，忽略
            }
        }
        return count >= minCount;
    }

    private Object getFieldValue(Object obj, String fieldName) throws Exception {
        if (obj instanceof Map) {
            return ((Map<?, ?>) obj).get(fieldName);
        }

        Class<?> clazz = obj.getClass();

        // 尝试getter方法
        try {
            String getterName = "get" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
            Method getter = clazz.getMethod(getterName);
            return getter.invoke(obj);
        } catch (NoSuchMethodException e) {
            // 尝试直接访问字段
            try {
                Field field = clazz.getDeclaredField(fieldName);
                field.setAccessible(true);
                return field.get(obj);
            } catch (NoSuchFieldException ex) {
                // 尝试父类
                Class<?> superClass = clazz.getSuperclass();
                if (superClass != null) {
                    Field field = superClass.getDeclaredField(fieldName);
                    field.setAccessible(true);
                    return field.get(obj);
                }
                throw ex;
            }
        }
    }

    @Override
    public String getErrorMessage() {
        return errorMessage;
    }

    @Override
    public String getName() {
        return "至少填" + minCount + "个校验";
    }
}
