package com.gci.boot.annotation.repeat.handle;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.baomidou.mybatisplus.extension.service.IService;
import com.gci.boot.annotation.repeat.FieldRepeat;
import com.gci.boot.common.util.LambdaFunctionUtil;
import com.gci.boot.common.util.SpringContextUtil;
import org.apache.poi.ss.formula.functions.T;

import javax.validation.ConstraintValidatorContext;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.List;

/**
 * @author 24642
 */
public class TableRepeatUtils {
    
    public static boolean fieldRepeat(Object o, Class<T> cClass, ConstraintValidatorContext context) {
        HashMap<String, Object> stringObjectHashMap = new HashMap<>();
        SFunction sFunction = null;
        Object idValue = null;
        //去除默认的提示消息
        context.disableDefaultConstraintViolation();
        String message = "";
        Field[] fields = ReflectUtil.getFields(cClass);
        if (ObjectUtil.isEmpty(fields)) {
            return true;
        }
        LambdaQueryWrapper<T> queryWrapper = new LambdaQueryWrapper<>();
        for (Field field : fields) {
            queryWrapper.clear();
            boolean accessible = field.isAccessible();
            //设置后操作速度更快
            field.setAccessible(true);
            Object fieldValue = ReflectUtil.getFieldValue(o, field);
            if (ObjectUtil.isEmpty(fieldValue)) {
                continue;
            }
            TableId annotation = field.getAnnotation(TableId.class);
            if (null != annotation && ObjectUtil.isNotEmpty(fieldValue)) {
                sFunction = LambdaFunctionUtil.getFunctionField(cClass,field.getName());
                idValue = fieldValue;
            }
            FieldRepeat fieldRepeat = field.getAnnotation(FieldRepeat.class);
            if (null == fieldRepeat) {
                continue;
            }
            String fieldName = !"".equals(fieldRepeat.PropName()) ? fieldRepeat.PropName() : field.getName();
            queryWrapper.eq(LambdaFunctionUtil.getFunctionField(cClass,fieldName),fieldValue);
            if (ObjectUtil.isNotEmpty(sFunction)) {
                queryWrapper.ne(sFunction,idValue);
            }
            String other = fieldRepeat.other();
            if (StrUtil.isNotBlank(other)) {
                List<String> split = StrUtil.split(other, ',');
                for (String s : split) {
                    Object orDefault = stringObjectHashMap.getOrDefault(s, null);
                    if (orDefault == null) {
                        orDefault = ReflectUtil.getFieldValue(o,s);
                    }
                    if (ObjectUtil.isNotEmpty(orDefault)) {
                        stringObjectHashMap.put(s,orDefault);
                        queryWrapper.eq(LambdaFunctionUtil.getFunctionField(cClass,s),orDefault);
                    }
                }
            }
            int count = ((IService) SpringContextUtil.getBean(StrUtil.lowerFirst(cClass.getSimpleName()) + "ServiceImpl")).count(queryWrapper);
            if (count >0) {
                message = fieldRepeat.message();
                context.buildConstraintViolationWithTemplate(message).addConstraintViolation();
                return false;
            }
            field.setAccessible(accessible);
        }
        return true;
    }
}
