package com.cyksj.service.corp.msg;


import com.cyksj.model.request.corp.CorpXmlMessage;
import com.cyksj.model.request.corp.CorpXmlOutMessage;
import com.cyksj.service.corp.CorpService;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.util.*;
import java.util.regex.Pattern;

/**
 * @author chan
 * @date 2022-03-14 下午4:16
 */
@Data
@Slf4j
public class CorpMessageRouterRule {
	private final CorpMessageRouter routerBuilder;

	private boolean async = true;

	private String fromUser;

	private String msgType;

	private String event;

	private String eventKey;

	private String eventKeyRegex;

	private String content;

	private String rContent;

	private String infoType;

	private String changeType;

	private CorpMessageMatcher matcher;

	private boolean reEnter = false;

	private Integer agentId;

	private List<CorpMessageHandler> handlers = new ArrayList<>();

	private List<CorpMessageInterceptor> interceptors = new ArrayList<>();


	protected CorpMessageRouterRule(CorpMessageRouter routerBuilder) {
		this.routerBuilder = routerBuilder;
	}

	/**
	 * 设置是否异步执行，默认是true
	 */
	public CorpMessageRouterRule async(boolean async) {
		this.async = async;
		return this;
	}

	/**
	 * 如果agentId匹配
	 */
	public CorpMessageRouterRule agentId(Integer agentId) {
		this.agentId = agentId;
		return this;
	}

	/**
	 * 如果msgType等于某值
	 */
	public CorpMessageRouterRule msgType(String msgType) {
		this.msgType = msgType;
		return this;
	}

	/**
	 * 如果event等于某值
	 */
	public CorpMessageRouterRule event(String event) {
		this.event = event;
		return this;
	}

	/**
	 * 如果eventKey等于某值
	 */
	public CorpMessageRouterRule eventKey(String eventKey) {
		this.eventKey = eventKey;
		return this;
	}

	/**
	 * 如果eventKey匹配该正则表达式
	 */
	public CorpMessageRouterRule eventKeyRegex(String regex) {
		this.eventKeyRegex = regex;
		return this;
	}

	/**
	 * 如果content等于某值
	 */
	public CorpMessageRouterRule content(String content) {
		this.content = content;
		return this;
	}

	/**
	 * 如果content匹配该正则表达式
	 */
	public CorpMessageRouterRule rContent(String regex) {
		this.rContent = regex;
		return this;
	}

	/**
	 * 如果fromUser等于某值
	 */
	public CorpMessageRouterRule fromUser(String fromUser) {
		this.fromUser = fromUser;
		return this;
	}

	/**
	 * infoType
	 */
	public CorpMessageRouterRule changeType(String changeType) {
		this.changeType = changeType;
		return this;
	}

	/**
	 * 如果消息匹配某个matcher，用在用户需要自定义更复杂的匹配规则的时候
	 */
	public CorpMessageRouterRule matcher(CorpMessageMatcher matcher) {
		this.matcher = matcher;
		return this;
	}

	/**
	 * 设置微信消息拦截器
	 */
	public CorpMessageRouterRule interceptor(CorpMessageInterceptor interceptor) {
		return interceptor(interceptor, (CorpMessageInterceptor[]) null);
	}

	/**
	 * 设置微信消息拦截器
	 */
	public CorpMessageRouterRule interceptor(CorpMessageInterceptor interceptor, CorpMessageInterceptor... otherInterceptors) {
		this.interceptors.add(interceptor);
		if (otherInterceptors != null && otherInterceptors.length > 0) {
			Collections.addAll(this.interceptors, otherInterceptors);
		}
		return this;
	}

	/**
	 * 设置微信消息处理器
	 */
	public CorpMessageRouterRule handler(CorpMessageHandler handler) {
		return handler(handler, (CorpMessageHandler[]) null);
	}

	/**
	 * 设置微信消息处理器
	 */
	public CorpMessageRouterRule handler(CorpMessageHandler handler, CorpMessageHandler... otherHandlers) {
		this.handlers.add(handler);
		if (otherHandlers != null && otherHandlers.length > 0) {
			Collections.addAll(this.handlers, otherHandlers);
		}
		return this;
	}

	/**
	 * 规则结束，代表如果一个消息匹配该规则，那么它将不再会进入其他规则
	 */
	public CorpMessageRouter end() {
		this.routerBuilder.getRules().add(this);
		return this.routerBuilder;
	}

	/**
	 * 规则结束，但是消息还会进入其他规则
	 */
	public CorpMessageRouter next() {
		this.reEnter = true;
		return end();
	}

	/**
	 * Test boolean.
	 *
	 * @param message the wx message
	 * @return the boolean
	 */
	protected boolean test(CorpXmlMessage message) {
		return
				(this.fromUser == null || this.fromUser.equals(message.getFromUserName()))
						&&
						(this.agentId == null || this.agentId.equals(message.getAgentId()))
						&&
						(this.msgType == null || this.msgType.equalsIgnoreCase(message.getMsgType()))
						&&
						(this.event == null || this.event.equalsIgnoreCase(message.getEvent()))
						&&
						(this.eventKey == null || this.eventKey.equalsIgnoreCase(message.getEventKey()))
						&&
						(this.eventKeyRegex == null || Pattern.matches(this.eventKeyRegex, StringUtils.trimToEmpty(message.getEventKey())))
						&&
						(this.content == null || this.content.equals(StringUtils.trimToNull(message.getContent())))
						&&
						(this.rContent == null || Pattern.matches(this.rContent, StringUtils.trimToEmpty(message.getContent())))
						&&
						(this.matcher == null || this.matcher.match(message))
						&&
						(this.changeType == null || this.changeType.equals(message.getChangeType()))
				;
	}

	/**
	 * 处理微信推送过来的消息
	 */
	protected CorpXmlOutMessage service(CorpXmlMessage message,
	                                    Map<String, Object> context,
	                                    CorpService corpService) {

		if (context == null) {
			context = new HashMap<>();
		}

		try {
			// 如果拦截器不通过
			for (CorpMessageInterceptor interceptor : this.interceptors) {
				if (!interceptor.intercept(message, context, corpService)) {
					return null;
				}
			}

			// 交给handler处理
			CorpXmlOutMessage res = null;
			for (CorpMessageHandler handler : this.handlers) {
				// 返回最后handler的结果
				res = handler.handle(message, context, corpService);
			}
			return res;

		} catch (Exception e) {
			//TODO 处理异常
			log.error("企业微信推送 路由处理错误 error:{}", e);
		}

		return null;

	}


}
