package com.wms_main.repository.utils;

import com.alibaba.fastjson2.JSON;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.util.DigestUtils;

/**
 * 字符串工具类
 */
public class StringUtils {

    private static final String CHARS_AZ = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    private static final String CHARS_az = "abcdefghijklmnopqrstuvwxyz";
    private static final String CHARS_09 = "0123456789";

    /** 下划线 */
    private static final char SEPARATOR = '_';

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

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

    /**
     * 在左边补充字符到指定长度
     * @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()));
    }

    /**
     * 判断一个字符串是否为数字
     * @param str 要判断的字符串
     * @return 结果
     */
    public static boolean isNumber(String str) {
        if (isEmpty(str)) return false;
        return str.matches("^\\d+$");
    }

    public static boolean isDecimal(String str) {
        if (isEmpty(str)) return false;
        return str.matches("^\\d+\\.?\\d*$");
    }

    /**
     * 加密密码所用的一种方式，理论上不可逆向
     * @param password 要加密的密码
     * @return 加密结果
     */
    public static String encryptPassword(String password) {
        StringBuilder result = new StringBuilder();
        int count = 0;
        String needEncryptStr = password;
        while (result.length() < 255) {
            count ++;
            String md5 = DigestUtils.md5DigestAsHex(needEncryptStr.getBytes()).toUpperCase();
            if(count % 2 == 0 || result.length() < count * 2) {
                result.append(md5);
            } else {
                result.insert(count * 2, md5);
            }
            needEncryptStr = md5;
        }
        return result.substring(0, 255);
    }

    /**
     * 驼峰转下划线命名
     * @param str 转换前的驼峰方式命名的字符串
     * @return 转换后的下划线方式命名的字符串
     * 例：userName->user_name
     */
    public static String toUnderScoreCase(String str) {
        if (str == null) {
            return null;
        }
        StringBuilder sb = new StringBuilder();
        // 前置字符是否大写
        boolean preCharIsUpperCase = true;
        // 当前字符是否大写
        boolean curreCharIsUpperCase = true;
        // 下一个字符是否大写
        boolean nexteCharIsUpperCase = true;
        for (int i = 0; i < str.length(); i++)
        {
            char c = str.charAt(i);
            if (i > 0) {
                preCharIsUpperCase = Character.isUpperCase(str.charAt(i - 1));
            } else {
                preCharIsUpperCase = false;
            }
            curreCharIsUpperCase = Character.isUpperCase(c);
            if (i < (str.length() - 1)) {
                nexteCharIsUpperCase = Character.isUpperCase(str.charAt(i + 1));
            }
            if (preCharIsUpperCase && curreCharIsUpperCase && !nexteCharIsUpperCase) {
                sb.append(SEPARATOR);
            } else if ((i != 0 && !preCharIsUpperCase) && curreCharIsUpperCase) {
                sb.append(SEPARATOR);
            }
            sb.append(Character.toLowerCase(c));
        }
        return sb.toString();
    }

    /**
     * 驼峰式命名法
     * 例如：user_name->userName
     */
    public static String toCamelCase(String s) {
        if (s == null) {
            return null;
        }
        if (s.indexOf(SEPARATOR) == -1) {
            s = s.toLowerCase();
            return s;
        }
        s = s.toLowerCase();
        StringBuilder sb = new StringBuilder(s.length());
        boolean upperCase = false;
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            if (c == SEPARATOR) {
                upperCase = true;
            } else if (upperCase) {
                sb.append(Character.toUpperCase(c));
                upperCase = false;
            } else {
                sb.append(c);
            }
        }
        return sb.toString();
    }

    /**
     * 将对象转为字符串
     * @param t 实体类
     * @param clazz 类型
     * @return 字符串
     */
    public static <T> String objectToStringWithClassName(T t, Class<T> clazz) {
        return clazz.getSimpleName() + JSON.toJSONString(t);
    }

    /**
     * 将对象转为字符串
     * @param t 实体类
     * @return 字符串
     */
    public static <T> String objectToString(T t) {
        return JSON.toJSONString(t);
    }

    /**
     * 将字符串转为对象
     * @param s 字符串
     * @param clazz 类型
     * @return 转化后的对象
     */
    public static <T> T stringToObject(String s, Class<T> clazz) {
        if (s.startsWith(clazz.getSimpleName())) {
            return JSON.parseObject(s.substring(clazz.getSimpleName().length()), clazz);
        } else {
            return JSON.parseObject(s, clazz);
        }
    }

    /**
     * 将字母转化为对应的数字
     * @param letter 字母
     * @return 转化后的数字
     */
    public static int letterToNumber(char letter) {
        if ('a' <= letter && letter <= 'z') {
            return letter - 'a' + 1;
        } else if ('A' <= letter && letter <= 'Z') {
            return letter - 'A' + 1;
        } else {
            return -1;
        }
    }

    /**
     * 获取请求的ip地址
     * @param request 请求
     * @return ip地址
     */
    public static String getIpAddr(HttpServletRequest request) {
        String ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        if (ip != null && ip.indexOf(",") > 0) {
            String[] parts = ip.split(",");
            for (String part : parts) {
                if (!part.isEmpty() && !"unknown".equalsIgnoreCase(part)) {
                    ip = part.trim();
                    break;
                }
            }
        }
        if ("0:0:0:0:0:0:0:1".equals(ip)) {
            ip = "127.0.0.1";
        }
        return ip;
    }
}
