package cn.ey.biz.module.system.util.engagement;

import cn.ey.biz.module.system.controller.engagement.business.vo.EngagementBusinessConditionVO;
import cn.ey.biz.module.system.controller.engagement.business.vo.EngagementBusinessSubConditionVO;
import cn.ey.biz.module.system.enums.engagement.CompareTypeEnum;
import cn.ey.biz.module.system.enums.engagement.SpecialConditionEnum;
import cn.ey.biz.module.system.enums.engagement.SubConditionEnum;
import cn.hutool.core.collection.CollectionUtil;

import javax.validation.Constraint;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import javax.validation.Payload;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import java.util.HashSet;
import java.util.List;
import java.util.stream.Collectors;

import static cn.ey.biz.module.system.enums.ErrorCodeConstants.*;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

@Documented
@Target({FIELD})
@Retention(RUNTIME)
@Constraint(validatedBy = BusinessFieldConditionCheck.Validator.class)
public @interface BusinessFieldConditionCheck {
    //当校验失败时默认返回的消息
    String message() default "";

    //分组校验时使用
    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};

    class Validator implements ConstraintValidator<BusinessFieldConditionCheck, List<EngagementBusinessConditionVO>> {

        @Override
        public void initialize(BusinessFieldConditionCheck businessFieldConditionCheck) {
            //不需要初始化
        }

        @Override
        public boolean isValid(List<EngagementBusinessConditionVO> list, ConstraintValidatorContext context) {
            if (CollectionUtil.isEmpty(list)) {
                return true;
            }
            //禁止默认消息返回
            context.disableDefaultConstraintViolation();
            for (EngagementBusinessConditionVO conditionVO : list) {
                //多租子业务线是否为空
                if (CollectionUtil.isEmpty(conditionVO.getServiceLine())) {
                    //输出设置的信息
                    context.buildConstraintViolationWithTemplate(SSL_CODE_NOT_NULL.getMsg()).addBeanNode().addConstraintViolation();
                    return false;
                }
                //特殊条件是否为空
                if (null == conditionVO.getSpecialCondition()) {
                    context.buildConstraintViolationWithTemplate(SPECIAL_CONDITION_NOT_NULL.getMsg()).addBeanNode().addConstraintViolation();
                    return false;
                }
                Boolean specialCondition = SpecialConditionEnum.isValidByValue(conditionVO.getSpecialCondition());
                //校验特殊条件类型：1.winRate 2.globalServiceCode 3.riskLevel 4.businessAmount 5.erpPercentage
                if (!specialCondition) {
                    context.buildConstraintViolationWithTemplate(SPECIAL_CONDITION_NOT_EXIST.getMsg()).addBeanNode().addConstraintViolation();
                    return false;
                }
                //当[特殊条件]=“无”时，[子条件] 的填写框置灰，不支持填写
                if (!conditionVO.getSpecialCondition().equals(SpecialConditionEnum.NO.getValue())) {
                    //子条件是否为空
                    if (CollectionUtil.isEmpty(conditionVO.getSubConditionVO())) {
                        context.buildConstraintViolationWithTemplate(SUB_CONDITION_NOT_NULL.getMsg()).addBeanNode().addConstraintViolation();
                        return false;
                    }

                    List<EngagementBusinessSubConditionVO> subCondition = conditionVO.getSubConditionVO();
                    for (EngagementBusinessSubConditionVO subConditionVO : subCondition) {
                        Boolean validByValue = SubConditionEnum.isValidByValue(subConditionVO.getSubCondition());
                        //校验子条件类型：1.winRate 2.globalServiceCode 3.riskLevel 4.businessAmount 5.erpPercentage
                        if (!validByValue) {
                            context.buildConstraintViolationWithTemplate(SUB_CONDITION_NOT_EXIST.getMsg()).addBeanNode().addConstraintViolation();
                            return false;
                        }
                        //比较类型是否为空
                        if (null == subConditionVO.getCompareType()) {
                            context.buildConstraintViolationWithTemplate(COMPARE_TYPE_NOT_NULL.getMsg()).addBeanNode().addConstraintViolation();
                            return false;
                        }


                        Boolean compareType = CompareTypeEnum.isValidByValue(subConditionVO.getCompareType());
                        //校验比较件类型：1.winRate 2.globalServiceCode 3.riskLevel 4.businessAmount 5.erpPercentage
                        if (!compareType) {
                            context.buildConstraintViolationWithTemplate(COMPARE_TYPE_NOT_EXIST.getMsg()).addBeanNode().addConstraintViolation();
                            return false;
                        }
                    }


                }
            }
            if (CollectionUtil.isNotEmpty(list)) {
                //若组A的[子业务线]和组B的[子业务线]相同或包含关系，且[子条件] 重复时提示
                List<EngagementBusinessConditionVO> collect = list.stream().filter(c -> (null != c.getSpecialCondition())
                        && !c.getSpecialCondition().equals(SpecialConditionEnum.NO.getValue())).collect(Collectors.toList());
                if (CollectionUtil.isNotEmpty(collect)) {
                    boolean hasDuplicatesOrContains = collect.stream()
                            .anyMatch(l1 -> (collect.stream()
                                    .filter(l -> l.getServiceLine() != l1.getServiceLine())
                                    .anyMatch(l2 -> new HashSet<>(l2.getServiceLine()).containsAll(l1.getServiceLine())
                                            || new HashSet<>(l1.getServiceLine()).containsAll(l2.getServiceLine())))
                                    && (collect.stream()
                                    .anyMatch(t1 -> collect.stream()
                                            .filter(t2 -> t2.getSubConditionVO() != t1.getSubConditionVO())
                                            .anyMatch(t2 -> new HashSet<>(t2.getSubConditionVO().stream().map(EngagementBusinessSubConditionVO::getSubCondition).collect(Collectors.toList()))
                                                    .containsAll(t1.getSubConditionVO().stream().map(EngagementBusinessSubConditionVO::getSubCondition).collect(Collectors.toList()))
                                                    || new HashSet<>(t1.getSubConditionVO().stream().map(EngagementBusinessSubConditionVO::getSubCondition).collect(Collectors.toList()))
                                                    .containsAll(t2.getSubConditionVO().stream().map(EngagementBusinessSubConditionVO::getSubCondition).collect(Collectors.toList()))))));
                    // 您选择的子条件有冲突，请重新选择
                    if (hasDuplicatesOrContains) {
                        //输出设置的信息
                        context.buildConstraintViolationWithTemplate(SUB_CONDITION_CONFLICT.getMsg()).addBeanNode().addConstraintViolation();
                        return false;
                    }
                }
            }
            return true;
        }

    }
}
