package cn.axzo.workflow.common.constraint;

import cn.axzo.workflow.common.enums.AttachmentTypeEnum;
import cn.axzo.workflow.common.model.request.bpmn.task.AttachmentDTO;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.util.List;

/**
 * 附件校验器
 *
 * @author wangli
 * @since 2024/4/22 15:15
 */
public class AttachmentConstraintValidator implements ConstraintValidator<AttachmentValidator, List<AttachmentDTO>> {

    private AttachmentTypeValidator[] typeConstraints;

    @Override
    public void initialize(AttachmentValidator constraintAnnotation) {
        this.typeConstraints = constraintAnnotation.types();
    }

    @Override
    public boolean isValid(List<AttachmentDTO> attachments, ConstraintValidatorContext context) {
        if (attachments == null || attachments.isEmpty()) {
            return true; // No attachments, so no validation needed
        }
        boolean isValid = true;

        for (AttachmentTypeValidator typeConstraint : typeConstraints) {
            AttachmentTypeEnum type = typeConstraint.type();
            int minAllowed = typeConstraint.min();
            int maxAllowed = typeConstraint.max();
            int count = getCountOfType(attachments, type);

            // Check if min or max is not limited
            boolean minNotLimited = minAllowed == -1;
            boolean maxNotLimited = maxAllowed == Integer.MAX_VALUE;

            if (!minNotLimited && count < minAllowed) {
                addErrorMessage(context, typeConstraint.type().getDesc() + "数量最小支持" + minAllowed + "个");
                isValid = false; // Validation failed due to min limit
            }

            if (!maxNotLimited && count > maxAllowed) {
                addErrorMessage(context, typeConstraint.type().getDesc() + "数量最大支持" + maxAllowed + "个");
                isValid = false; // Validation failed due to max limit
            }
        }

        return isValid; // Validation passed
    }

    // Helper method to count attachments of a specific type
    private int getCountOfType(List<AttachmentDTO> attachments, AttachmentTypeEnum type) {
        int count = 0;
        for (AttachmentDTO attachment : attachments) {
            if (attachment.getType().equals(type)) {
                count++;
            }
        }
        return count;
    }

    private void addErrorMessage(ConstraintValidatorContext context, String message) {
        context.disableDefaultConstraintViolation();
        context.buildConstraintViolationWithTemplate(message)
                .addConstraintViolation();
    }
}
