
package com.tmerclub.cloud.common.util;

import cn.hutool.core.util.StrUtil;
import com.tmerclub.cloud.common.constant.Constant;
import org.springframework.util.AntPathMatcher;

import java.util.regex.Pattern;

/**
 * 正则表达式工具
 *
 * @author tmerclub
 */
public class PrincipalUtil {

    /**
     * 以1开头，后面跟10位数
     */
    public static final String MOBILE_REGEXP = "1[0-9]{10}";

    /**
     * 带有星号的手机号码
     */
    public static final String MOBILE_REGEXP_WITH_ASTERISK = "^1[0-9]{2}([[0-9]*]{4})[0-9]{4}$";

    /**
     * 1. 用户名不能为纯数字 2. 由数字字母下划线 4-16位组成
     */
    public static final String USER_NAME_REGEXP = "(?!\\d+$)([a-zA-Z0-9_]{4,16})";

    /**
     * 字段名，数字字母下划线
     */
    public static final String FIELD_REGEXP = "([a-zA-Z0-9_]+)";

    /**
     * 由简单的字母数字拼接而成的字符串 不含有下划线，大写字母
     */
    public static final String SIMPLE_CHAR_REGEXP = "([a-z0-9]+)";

    /**
     * 邮箱正则
     */
    public static final String EMAIL_REGEXP = "[\\w!#$%&'*+/=?^_`{|}~-]+(?:\\.[\\w!#$%&'*+/=?^_`{|}~-]+)*@(?:[\\w](?:[\\w-]*[\\w])?\\.)+[\\w](?:[\\w-]*[\\w])?";

    /**
     * http协议正则
     */
    public static final String HTTP_PROTOCOL_REGEXP = "^((http[s]{0,1})://)";

    /**
     * 不等于0,只能输入数字，最多两位小数
     */
    public static final String UP_TO_TWO_DECIMAL = "^(-)?[1-9]\\d*$|^(-)?[1-9]\\d*\\.\\d\\d?$|^(-)?0\\.\\d\\d?$";

    /**
     * 只能输入数字字母
     */
    public static final String WITHOUT_CHINESE = "^[A-Za-z0-9]+$";

    /**
     * 是否是手机号
     *
     * @param value 输入值
     * @return 匹配结果
     */
    public static boolean isMobile(String value) {
        return isMatching(MOBILE_REGEXP, value);
    }

    public static boolean isAsteriskMobile(String value) {
        if(StrUtil.isBlank(value)) {
            return false;
        }
        return Pattern.matches(MOBILE_REGEXP_WITH_ASTERISK, value);
    }

    /**
     * 是否是用户名
     *
     * @param value 输入值
     * @return 匹配结果
     */
    public static boolean isUserName(String value) {
        return isMatching(USER_NAME_REGEXP, value);
    }

    /**
     * 是否符合字段规则
     *
     * @param value 输入值
     * @return 匹配结果
     */
    public static boolean isField(String value) {
        return !isMatching(FIELD_REGEXP, value);
    }

    /**
     * 是否是邮箱
     *
     * @param value 输入值
     * @return 匹配结果
     */
    public static boolean isEmail(String value) {
        return isMatching(EMAIL_REGEXP, value);
    }

    /**
     * 是否是由简单的字母数字拼接而成的字符串
     *
     * @param value 输入值
     * @return 匹配结果
     */
    public static boolean isSimpleChar(String value) {
        return isMatching(SIMPLE_CHAR_REGEXP, value);
    }

    /**
     * 是否是 最多是保留两位小数的数值
     *
     * @param value 输入值
     * @return 匹配结果
     */
    public static boolean isMaximumOfTwoDecimal(String value) {
        return isMatching(UP_TO_TWO_DECIMAL, value);
    }

    /**
     * 是否是HTTP协议
     *
     * @param value 输入值
     * @return 匹配结果
     */
    public static boolean isHttpProtocol(String value) {
        return isFind(HTTP_PROTOCOL_REGEXP, value);
    }

    public static boolean isMatching(String regexp, String value) {
        if (StrUtil.isBlank(value)) {
            return false;
        }
        return Pattern.matches(regexp, value);
    }

    public static boolean isFind(String regexp, String value) {
        if (StrUtil.isBlank(value)) {
            return false;
        }
        Pattern pattern = Pattern.compile(regexp);
        return pattern.matcher(value).find();
    }

    /**
     * 是否符合原数据库手机号码
     * @param phone 传入的手机号码
     * @param dbPhone 数据库存储的手机号码
     * @param canNull 手机号是否能为空
     * @return 匹配结果
     */
    public static boolean isDbPhone(String phone, String dbPhone, Boolean canNull) {
        if (StrUtil.isBlank(phone) || StrUtil.isBlank(dbPhone)) {
            return canNull;
        }
        if (!phone.contains(Constant.ASTERISK)) {
            // 不含星号默认修改成功
            return true;
        }
        // 最多的星号数量
        int limit = 4;
        AntPathMatcher pathMatcher = new AntPathMatcher();
        if (((phone.length() - phone.replace(Constant.ASTERISK, "").length()) <= limit)
                && pathMatcher.match(phone, dbPhone)) {
            return true;
        }
        return false;
    }
}
