package com.trade.common.validate;

import cn.hutool.core.util.ReflectUtil;
import com.trade.common.constant.HttpStatus;
import com.trade.common.core.domain.BaseEntity;
import com.trade.common.core.domain.BizBaseEntity;
import com.trade.common.core.domain.CommonEntity;
import com.trade.common.core.dto.BaseDTO;
import com.trade.common.exception.ServiceException;
import com.trade.common.exception.ValidatorException;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Map;

/**
 * 验证数据
 */
public class ValidatorUtil {

    /**
     * 验证数据是否合法
     *
     * @param type 验证类型
     * @param baseEntity 被验证实体
     */
    @SuppressWarnings("rawtypes")
    public static void validator(ValidatorGroup.ValidatorType type, BaseEntity baseEntity) {
        validatorBase(type, baseEntity);
    }

    /**
     * 验证数据是否合法
     *
     * @param type 验证类型
     * @param baseEntity 被验证实体
     */
    @SuppressWarnings("rawtypes")
    public static void validator(ValidatorGroup.ValidatorType type, BizBaseEntity baseEntity) {
        validatorBase(type, baseEntity);
    }

    /**
     * 验证数据是否合法
     *
     * @param type 验证类型
     * @param baseEntity 被验证实体
     */
    @SuppressWarnings("rawtypes")
    public static void validator(ValidatorGroup.ValidatorType type, CommonEntity baseEntity) {
        validatorBase(type, baseEntity);
    }

    /**
     * 验证数据是否合法
     *
     * @param type 验证类型
     * @param baseDTO 被验证实体
     */
    public static void validator(ValidatorGroup.ValidatorType type, BaseDTO baseDTO) {
        validatorBase(type, baseDTO);
    }

    public static void validator(ValidatorGroup.ValidatorType type, CommonEntity baseEntity, int rows) {
        validatorBase(type, baseEntity, rows);
    }

    @SuppressWarnings("unchecked")
    private static void validatorBase(ValidatorGroup.ValidatorType type, Object obj) {
        if (obj == null) {
            throw new ValidatorException(HttpStatus.BAD_REQUEST, "空数据");
        }
        try {
            Method validator = ReflectUtil.getMethod(obj.getClass(), "validator", ValidatorGroup.ValidatorType.class);
            validator.invoke(obj, type);
            Method hasErrors = ReflectUtil.getMethod(obj.getClass(), "hasErrors");
            if ((Boolean) hasErrors.invoke(obj)) {
                Method getErrors = ReflectUtil.getMethod(obj.getClass(), "getErrors");
                Map<String, String> map = (Map<String, String>) getErrors.invoke(obj);
                for (String key : map.keySet()) {
                    throw new ValidatorException(HttpStatus.BAD_REQUEST, map.get(key));
                }
            }
        } catch (IllegalAccessException | InvocationTargetException e) {
            throw new ServiceException("数据合法性验证出异常啦！" + e.getMessage(), HttpStatus.ERROR);
        }
    }

    private static void validatorBase(ValidatorGroup.ValidatorType type, Object obj, int rows) {
        if (obj == null) {
            throw new ValidatorException(HttpStatus.BAD_REQUEST, "空数据");
        }
        try {
            Method validator = ReflectUtil.getMethod(obj.getClass(), "validator", ValidatorGroup.ValidatorType.class);
            validator.invoke(obj, type);
            Method hasErrors = ReflectUtil.getMethod(obj.getClass(), "hasErrors");
            if ((Boolean) hasErrors.invoke(obj)) {
                Method getErrors = ReflectUtil.getMethod(obj.getClass(), "getErrors");
                Map<String, String> map = (Map<String, String>) getErrors.invoke(obj);
                for (String key : map.keySet()) {
                    throw new ValidatorException(HttpStatus.BAD_REQUEST, "第" + rows + "行" + map.get(key));
                }
            }
        } catch (IllegalAccessException | InvocationTargetException e) {
            throw new ServiceException("数据合法性验证出异常啦！" + e.getMessage(), HttpStatus.ERROR);
        }
    }
}
