package cn.meowrain.aioj.backend.question.dto.chains;

import cn.meowrain.aioj.backend.framework.core.designpattern.chains.AbstractChianHandler;
import cn.meowrain.aioj.backend.framework.core.errorcode.ErrorCode;
import cn.meowrain.aioj.backend.framework.core.exception.ClientException;
import cn.meowrain.aioj.backend.question.common.enums.ChainMarkEnums;
import cn.meowrain.aioj.backend.question.dto.req.QuestionCreateRequestDTO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import java.util.List;

/**
 * 题目标签校验责任链处理器
 */
@Component
@Slf4j
public class QuestionTagsVerifyChain implements AbstractChianHandler<QuestionCreateRequestDTO> {

	/**
	 * 最大标签数量
	 */
	private static final int MAX_TAGS_COUNT = 10;

	/**
	 * 最小标签数量
	 */
	private static final int MIN_TAGS_COUNT = 1;

	/**
	 * 单个标签最大长度
	 */
	private static final int MAX_TAG_LENGTH = 20;

	@Override
	public void handle(QuestionCreateRequestDTO requestParam) {
		List<String> tags = requestParam.getTags();

		// 标签可以为空，但如果提供了则进行校验
		if (tags == null || tags.isEmpty()) {
			log.debug("题目标签为空，跳过校验");
			return;
		}

		// 校验标签数量
		if (tags.size() > MAX_TAGS_COUNT) {
			throw new ClientException(
				String.format("标签数量不能超过 %d 个", MAX_TAGS_COUNT),
				ErrorCode.PARAMS_ERROR
			);
		}

		// 校验每个标签
		for (String tag : tags) {
			// 校验标签不为空
			if (StringUtils.isBlank(tag)) {
				throw new ClientException("标签不能为空", ErrorCode.PARAMS_ERROR);
			}

			// 校验标签长度
			if (tag.trim().length() > MAX_TAG_LENGTH) {
				throw new ClientException(
					String.format("标签长度不能超过 %d 个字符", MAX_TAG_LENGTH),
					ErrorCode.PARAMS_ERROR
				);
			}

			// 校验标签不包含特殊字符（可以根据需求调整）
			if (tag.contains(",") || tag.contains(";") || tag.contains("|")) {
				throw new ClientException(
					String.format("标签 '%s' 包含非法字符", tag),
					ErrorCode.PARAMS_ERROR
				);
			}
		}

		log.debug("题目标签校验通过，共 {} 个标签", tags.size());
	}

	@Override
	public String mark() {
		return ChainMarkEnums.QUESTION_CREATE_PARAM_VERIFY_CHAIN.getMark();
	}

	@Override
	public int getOrder() {
		return 50;
	}
}
