package easydo.technology.utils;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.util.*;
import java.util.stream.IntStream;

/**
 * 字符串工具类
 * 
 * @author Ready 2012-10-17
 */
public class StringUtil {

    /**
     * 如果字符串为空，则返回空字符""
     *
     * @param str
     * @return
     */
    public static String stringNullToEmpty(String str) {
        return str == null ? "" : str;
    }

    /**
     * 如果字符串为空，则返回null
     *
     * @param str
     * @return
     */
    public static String stringEmptyToNull(String str) {
        if (str == null)
            return null;
        return "".equals(str.trim()) ? null : str.trim();
    }

    public static String getPre(int count, String c) {
        StringBuilder result = new StringBuilder("");
        for (int i = 0; i < count; i++) {
            result.append(c);
        }
        return result.toString();
    }

    public static String disponseStr(String str) {
        if (str != null) {
            return str.trim();
        }
        return str;
    }

    /**
     * 是否为空，如果为null或者""，返回false，不为空返回true
     *
     * @param target
     * @return
     */
    public static boolean isNotEmpty(Object target) {
        if (target == null || "".equals(target.toString().trim())
                || "null".equals(target.toString().toLowerCase().trim())) {
            return false;
        }
        return true;
    }

    /**
     * 判断字符串是否为空，如果为空返回true
     *
     * @param target
     * @return
     */
    public static boolean isEmpty(Object target) {
        return !isNotEmpty(target);
    }

    /**
     * @param length是随机数长度
     * @return String
     * @throws 无
     * @author jchen.Kevin
     * @date 2015年04月04日
     * @description 生成长度为length的随机数
     * @version 1.0.0
     */
    public static String getRandom(int length) {
        if (length < 1) {
            return null;
        }
        StringBuffer str = new StringBuffer();
        Random random = new Random();
        for (int i = 0; i < length; i++) {
            str.append(String.valueOf(random.nextInt(10)));
        }
        return str.toString();
    }

    /**
     * @param length是验证码长度
     * @return String
     * @throws 无
     * @author lkang
     * @date 2014年5月27日
     * @description 生成长度为length的16进制字符串验证码
     * @version 1.0.0
     */
    public static String getValidateString(int length) {
        /*
         * 以时间为随机种子
         */
        Date d = new Date();
        long lseed = d.getTime();
        StringBuffer ramdomCode = new StringBuffer();
        Random r = new Random(lseed);

        /*
         * 产生16进制验证码字符串
         */
        for (int i = 0; i < length; i++) {
            ramdomCode.append(Integer.toHexString(r.nextInt(15)));
        }
        return ramdomCode.toString();
    }

    /**
     * @param length是验证码长度
     * @return String
     * @throws 无
     * @author lkang
     * @date 2014年5月27日
     * @description 生成长度为length的16进制数字验证码
     * @version 1.0.0
     */
    public static String getValidateNumber(int length) {
        /*
         * 以时间为随机种子
         */
        Date d = new Date();
        long lseed = d.getTime();
        StringBuffer ramdomCode = new StringBuffer();
        Random r = new Random(lseed);

        /*
         * 产生数字验证码
         */
        for (int i = 0; i < length; i++) {
            ramdomCode.append(Integer.toString(r.nextInt(9)));
        }
        return ramdomCode.toString();
    }

    /**
     * @param source     要填充的字符串
     * @param length     字符串填充后满足的长度
     * @param fillString 填充物
     * @return 填充后的字符串
     * @throws
     * @author yldong.water
     * @date 2014年8月25日
     * @description 填充特定字符串以满足指定长度
     * @version 1.0.0
     */
    public static String fill(String source, int length, String fillString) {
        if (isNotEmpty(source)) {
            int sourceLength = source.length();
            if (sourceLength < length) {
                source = getPre(length - sourceLength, fillString) + source;
            }
        } else {
            source = getPre(length, fillString);
        }
        return source;
    }

    /**
     * 格式化文件大小
     *
     * @param target
     * @return
     */
    public static String formatFileSize(double size) {
        size /= 1024;
        if (size >= 1024) {
            size /= 1024;
            double a = Math.round(size * 100);
            return a / 100 + "MB";
        } else {
            double a = Math.round(size * 100);
            return a / 100 + "KB";
        }
    }

    /**
     * 校验中英文的长度
     *
     * @param target
     * @return
     */
    public static int lenString(String str) {
        if (isNotEmpty(str)) {
            int l = 0;
            for (int i = 0; i < str.length(); i++) {
                if (str.charAt(i) < 255) {
                    l++;
                } else {
                    l += 2;
                }
            }
            return l;
        } else {
            return 0;
        }
    }

    /**
     * 截取字符串
     *
     * @param target
     * @return
     */
    public static String splitString(String str, int len, boolean flag) {
        if (isNotEmpty(str)) {
            if (lenString(str) > len) {
                int l = 0;
                int splitLen = 0;
                for (int i = 0; i < str.length(); i++) {
                    if (str.charAt(i) < 255) {
                        l++;
                    } else {
                        l += 2;
                    }
                    if (l >= len) {
                        splitLen = i;
                        break;
                    }
                }
                if (flag) {
                    return str.substring(0, splitLen + 1);
                } else {
                    return str.substring(0, splitLen + 1) + "...";
                }
            } else {
                return str;
            }
        } else {
            return null;
        }
    }

    /**
     * @param String
     * @return boolean
     * @author jchen.Kevin
     * @date 2015年01月28日
     * @description 判断是否是固定电话
     * @version 1.0.0
     */
    public static boolean isTel(String str) {
        return str
                .matches("(^(\\d{3,4}-)?\\d{7,8})$|(13[0-9]{9})|(1[0-9]{10})");
    }

    /**
     * @param String
     * @return boolean
     * @author jchen.Kevin
     * @date 2015年01月28日
     * @description 判断是否是手机号码
     * @version 1.0.0
     */
    public static boolean isPhone(String str) {
        return str.matches("^1[0-9][0-9]\\d{8}$");
    }

    /**
     * @param String
     * @return boolean
     * @author jchen.Kevin
     * @date 2015年01月28日
     * @description 判断是否是邮箱
     * @version 1.0.0
     */
    public static boolean isEmail(String str) {
        return str
                .matches("^[A-Za-z\\d]+([-_.][A-Za-z\\d]+)*@([A-Za-z\\d]+[-.])+[A-Za-z\\d]{2,5}$");
    }

    /**
     * @param String
     * @return boolean
     * @author jchen.Kevin
     * @date 2015年01月28日
     * @description 判断是否是中国邮政编码(6位)
     * @version 1.0.0
     */
    public static boolean isZipCode(String str) {
        return str.matches("^[1-9][0-9]{5}$");
    }

    /**
     * @param String
     * @return boolean
     * @author jchen.Kevin
     * @date 2015年01月28日
     * @description 判断是否是腾讯QQ号
     * @version 1.0.0
     */
    public static boolean isQQ(String str) {
        return str.matches("[1-9][0-9]{4,}");
    }

    /**
     * @param String
     * @return boolean
     * @author jchen.Kevin
     * @date 2015年01月28日
     * @description 判断是否是身份证(15位或18位)
     * @version 1.0.0
     */
    public static boolean isIdcard(String str) {
        return str.matches("\\d{15}|\\d{18}");
    }


    /*
     * 得到两个数组中相同元素
     */
    public static Set<Integer> getSames(Integer[] a, Integer[] b) {
        Set<Integer> sames = new HashSet<Integer>();
        Set<Integer> set = new HashSet<Integer>(Arrays.asList(a));

        for (Integer i : b) {
            if (!set.add(i))
                sames.add(i);
        }

        return sames;
    }

    /*
     * 得到两个数组中相同元素
     */
    public static Set<Integer> getDefferent(Integer[] a, Integer[] b) {
        Set<Integer> defferents = new HashSet<Integer>();
        Set<Integer> set = new HashSet<Integer>(Arrays.asList(a));

        for (Integer i : b) {
            if (set.add(i))
                defferents.add(i);
        }

        return defferents;
    }

    /*
     * String数组转int数组
     */
    public static Integer[] StringToInt(String[] stringArr) {
        Integer[] intArr = new Integer[stringArr.length];
        for (int i = 0; i < stringArr.length; i++) {
            intArr[i] = Integer.parseInt(stringArr[i]);
        }
        return intArr;
    }

    /**
     * 使用 Java 8 Stream API 的替代实现
     */
    public static Object getNextFieldValueStream(JSONObject json, String path) {
        try {
            String[] keys = path.split("\\.");

            // 使用reduce来处理嵌套访问
            Optional<Object> result = Arrays.stream(keys)
                    .reduce(Optional.of(json),
                            (currentOpt, key) -> currentOpt
                                    .filter(JSONObject.class::isInstance)
                                    .map(JSONObject.class::cast)
                                    .flatMap(obj -> Optional.ofNullable(obj.get(key))),
                            (opt1, opt2) -> opt2 // 在并行流中合并，但这里不需要
                    );

            return result.orElse(null);

        } catch (Exception e) {
            return null;
        }
    }

    public static boolean setNextFieldValueStream(JSONObject json, String path, Object newValue) {
        try {
            String[] keys = path.split("\\.");

            if (keys.length == 0) {
                return false;
            }
            // 获取最后一个键之前的对象
            String[] parentKeys = Arrays.copyOfRange(keys, 0, keys.length - 1);
            String lastKey = keys[keys.length - 1];
            // 找到父级对象
            Optional<Object> parentOpt = Arrays.stream(parentKeys)
                    .reduce(Optional.of(json),
                            (currentOpt, key) -> currentOpt
                                    .filter(JSONObject.class::isInstance)
                                    .map(JSONObject.class::cast)
                                    .flatMap(obj -> Optional.ofNullable(obj.get(key))),
                            (opt1, opt2) -> opt2);

            // 如果父级对象存在且是JSONObject，则设置新值
            if (parentOpt.isPresent() && parentOpt.get() instanceof JSONObject) {
                JSONObject parent = (JSONObject) parentOpt.get();
                parent.put(lastKey, newValue);
                return true;
            }
            return false;

        } catch (Exception e) {
            return false;
        }
    }

    public static String extractNumberBeforeHdLive(String url) {
        String target = ".hd.live";

        // 查找 ".hd.live" 的位置
        int hdLiveIndex = url.indexOf(target);
        if (hdLiveIndex == -1) {
            return null; // 未找到 ".hd.live"
        }

        // 从 ".hd.live" 开始向前查找最近的 '/'
        int lastSlashBeforeHdLive = url.lastIndexOf('/', hdLiveIndex - 1);
        if (lastSlashBeforeHdLive == -1) {
            return null; // 在所需位置之前未找到 '/'
        }

        // 截取两个位置之间的子字符串（从斜杠后开始，到 ".hd.live" 前结束）
        String numberStr = url.substring(lastSlashBeforeHdLive + 1, hdLiveIndex);

        // 可选：验证截取的部分是否全为数字
        if (!numberStr.matches("\\d+")) {
            return null; // 包含非数字字符
        }

        return numberStr;
    }
}