package org.wcs.utils;

import ch.qos.logback.core.util.MD5Util;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.TypeReference;
import org.wcs.model.bo.tuple.Tuple2;

import java.io.UnsupportedEncodingException;
import java.util.Base64;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class AppStringUtils {

    private static final Pattern pattern = Pattern.compile("-?[0-9]+(\\\\.[0-9]+)?");


    /**
     * 判断字符串是否为空
     * @param str 字符串
     * @return 结果
     */
    public static boolean isEmpty(String str) {
        return str == null || str.isEmpty();
    }

    /**
     * 判断字符串是否不为空
     * @param str 字符串
     * @return 结果
     */
    public static boolean isNotEmpty(String str) {
        return !isEmpty(str);
    }

    /**
     * 去除空格
     * @param str 字符串
     * @return 结果
     */
    public static String trim(String str) {
        return str == null ? "" : str.trim();
    }

    /**
     * 判断字符串是否为空或空格
     * @param str 字符串
     * @return 结果
     */
    public static boolean isNullOrEmptyChar(String str) {
        String ts = trim(str);
        return isEmpty(ts);
    }

    /**
     * 判断字符串是否为空或空格，如果是则返回默认值
     * @param str 字符串
     * @param defaultValue 默认值
     * @return 结果
     */
    public static String isEmptyOr(String str, String defaultValue) {
        return isEmpty(str) ? defaultValue : str;
    }

    /**
     * 判断字符串是否为整数，不是则返回默认值
     * @param str 字符串
     * @param defaultValue 默认值
     * @return 结果
     */
    public static Integer toIntegerOrDefault(String str, Integer defaultValue) {
        if (isNullOrEmptyChar(str)) {
            return defaultValue;
        }
        try {
            return Integer.parseInt(str); // 待改进
        } catch (Exception e) {
            return defaultValue;
        }
    }

    /**
     * 判断字符串是否为整数
     * @param str 字符串
     * @return 结果
     */
    public static boolean isNumber(String str) {
        if (isNullOrEmptyChar(str)) {
            return false;
        }
        Matcher m = pattern.matcher(str);
        return m.matches();
    }

    /**
     * 填充字符串长度到固定长度，超出的自动舍弃
     * @param str 源字符串
     * @param length 长度
     * @param fillChar 填充字符
     * @return 结果
     */
    public static String toFixLength(String str, int length, char fillChar) {
        if(isEmpty(str)) {
            return String.valueOf(fillChar).repeat(length);
        }

        if(str.length() >= length) {
            return str.substring(0, length);
        }
        return str.concat(String.valueOf(fillChar).repeat(length - str.length()));
    }


    /**
     * 加密密码
     * @param pwd 要加密的密码
     * @return 加密后的密码
     */
    public static String encryptPwd(String pwd){
        if(isEmpty(pwd)) {
            return null;
        }
        String returnString = "";
        try {
            MD5Util md5Util = new MD5Util();
            while (returnString.length() < 255) {
                String encryptPwd = isEmpty(returnString)? pwd : returnString;
                byte[] md5Hash = md5Util.md5Hash(encryptPwd);
                String encoded = Base64.getEncoder().encodeToString(md5Hash);
                returnString = returnString.concat(encoded.replaceAll("\\W", ""));
            }
            return returnString.substring(0, 255).toUpperCase();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 强制转换字符串为int,（去掉非数字，控制长度），转换失败返回0
     * @param str 字符串
     * @return int
     */
    public static int forceToInt(String str) {
        if(isEmpty(str)) {
            return 0;
        }
        String replaceStr = str.replace("\\D", "");
        if(!isNumber(str)) {
            return 0;
        }
        if(replaceStr.length() >= 9) {
            replaceStr = replaceStr.substring(replaceStr.length() - 9, 9);
        }
        return Integer.parseInt(replaceStr);
    }

    /**
     * 强制转换字符串为short
     * @param str 字符串
     * @return  short
     */
    public static short forceToShort(String str) {
        if(isEmpty(str)) {
            return 0;
        }
        String replaceStr = str.replace("\\D", "");
        if(!isNumber(str)) {
            return 0;
        }
        if(replaceStr.length() >= 5) {
            replaceStr = replaceStr.substring(replaceStr.length() - 5, 5);
        }
        return Short.parseShort(replaceStr);
    }


    /**
     * 获取哈希码
     * @param str 字符串
     * @return 结果
     */
    public static String getHashCode(String str) {
        return String.valueOf(str.hashCode());
    }

    /**
     * 对象转字符串
     * @param obj 对象
     * @return 转换结果
     */
    public static String objectToString(Object obj) {
        if (obj == null) {
            return "";
        }
        return JSON.toJSONString(obj);
    }

    /**
     * 字符串转对象
     * @param str 字符串
     * @param clazz 类
     * @return 转换结果
     */
    public static <T> T stringToObject(String str, Class<T> clazz) {
        if (str == null) {
            return null;
        }
        return JSON.parseObject(str, clazz);
    }



    public static <T> T stringToObjectWithType(String str, Class<T> clazz) {
        if (str == null) {
            return null;
        }
        return JSON.parseObject(str, new TypeReference<T>(){});
    }


    /**
     * 将字符串以GBK方式转换
     * @param string 字符串
     * @return 转换结果
     */
    public static byte[] toByteArrayGBK(String string) {
        try {
            return string.getBytes("GBK");
        } catch (UnsupportedEncodingException e) {
            return null;
        }
    }

    /**
     * 在左边补充字符到指定长度
     * @param str 要补充的字符串
     * @param c 补充的字符
     * @param length 长度
     * @return 结果
     */
    public static String padLeft(String str, String c, int length) {
        if(isEmpty(str)) {
            return c.repeat(length);
        }
        return c.repeat(Math.max(0, length - str.length())) + str;
    }

    /**
     * 在右边补充字符到指定长度
     * @param str 要补充的字符串
     * @param c 补充的字符
     * @param length 长度
     * @return 结果
     */
    public static String padRight(String str, String c, int length) {
        if(isEmpty(str)) {
            return c.repeat(length);
        }
        return str + c.repeat(Math.max(0, length - str.length()));
    }

}
