package org.jeecg.modules.bytedance.common.utils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author jeecg-boot
 * 2019年12月5日19:57:58
 */
public class StringUtils {
    private static final Pattern LINE_PATTERN = Pattern.compile("_(\\w)");
    private static final Pattern HUMP_PATTERN = Pattern.compile("[A-Z]");
    public static final String COMMA = ",";

    /**
     * 获取请求地址中的某个参数
     * @param url
     * @param name
     * @return
     */
    public static String getParamFromUrl(String url, String name) {
        return urlSplit(url).get(name);
    }

    /**
     * 去掉url中的路径，留下请求参数部分
     * @param url url地址
     * @return url请求参数部分
     */
    private static String truncateUrlPage(String url) {
        String strAllParam = null;
        String[] arrSplit = null;
        url = url.trim().toLowerCase();
        arrSplit = url.split("[?]");
        if (url.length() > 1) {
            if (arrSplit.length > 1) {
                for (int i = 1; i < arrSplit.length; i++) {
                    strAllParam = arrSplit[i];
                }
            }
        }
        return strAllParam;
    }

    /**
     * 将参数存入map集合
     * @param url  url地址
     * @return url请求参数部分存入map集合
     */
    public static Map<String, String> urlSplit(String url) {
        Map<String, String> mapRequest = new HashMap<String, String>();
        String[] arrSplit = null;
        String strUrlParam = truncateUrlPage(url);
        if (strUrlParam == null) {
            return mapRequest;
        }
        arrSplit = strUrlParam.split("[&]");
        for (String strSplit : arrSplit) {
            String[] arrSplitEqual = null;
            arrSplitEqual = strSplit.split("[=]");
            //解析出键值
            if (arrSplitEqual.length > 1) {
                //正确解析
                mapRequest.put(arrSplitEqual[0], arrSplitEqual[1]);
            } else {
                if (arrSplitEqual[0] != "") {
                    //只有参数没有值，不加入
                    mapRequest.put(arrSplitEqual[0], "");
                }
            }
        }
        return mapRequest;
    }


    public static ArrayList<String> stringCutFromBrace(String origin) {
        String pattern = "(?<=\\{)(.+?)(?=\\})";
        Pattern p = Pattern.compile(pattern);
        ArrayList<String> list = new ArrayList<>();
        Matcher m = p.matcher(origin);
        while (m.find()) {
            list.add(m.group());
        }
        return list;
    }
    /**
     * 将下划线风格转换为驼峰风格
     * @param inputString
     * @return
     */
    public static String underlineToCamehunp(String inputString){
        StringBuilder sb = new StringBuilder();
        boolean nextUppercase = false;
        for (int i = 0; i < inputString.length(); i++) {
            char c = inputString.charAt(i);
            if (c == '_') {
                if (sb.length()>0) {
                    nextUppercase = true;
                }
            }else {
                if (nextUppercase) {
                    sb.append(Character.toUpperCase(c));
                    nextUppercase = false;
                }else {
                    sb.append(Character.toLowerCase(c));
                }
            }
        }
        return sb.toString();
    }

    /** 下划线转驼峰 */
    public static String lineToHump(String str) {
        str = str.toLowerCase();
        Matcher matcher = LINE_PATTERN.matcher(str);
        StringBuffer sb = new StringBuffer();
        while (matcher.find()) {
            matcher.appendReplacement(sb, matcher.group(1).toUpperCase());
        }
        matcher.appendTail(sb);
        return sb.toString();
    }

    /** 驼峰转下划线(简单写法，效率低于{@link #humpToLine2(String)}) */
    public static String humpToLine(String str) {
        return str.replaceAll("[A-Z]", "_$0").toLowerCase();
    }

    /** 驼峰转下划线,效率比上面高 */
    public static String humpToLine2(String str) {
        Matcher matcher = HUMP_PATTERN.matcher(str);
        StringBuffer sb = new StringBuffer();
        while (matcher.find()) {
            matcher.appendReplacement(sb, "_" + matcher.group(0).toLowerCase());
        }
        matcher.appendTail(sb);
        return sb.toString();
    }

    //中文转Unicode
    public static String cnToUnicode(String cn) {
        char[] chars = cn.toCharArray();
        String returnStr = "";
        for (int i = 0; i < chars.length; i++) {
            returnStr += "\\u" + Integer.toString(chars[i], 16);
        }
        return returnStr;
    }

    //Unicode转中文方法
    public static String unicodeToCn(String unicode) {
        /** 以 \ u 分割，因为java注释也能识别unicode，因此中间加了一个空格*/
        String[] strs = unicode.split("\\\\u");
        String returnStr = "";
        // 由于unicode字符串以 \ u 开头，因此分割出的第一个字符是""。
        for (int i = 1; i < strs.length; i++) {
            returnStr += (char) Integer.valueOf(strs[i], 16).intValue();
        }
        return returnStr;
    }

    public static String replaceBlank(String str) {
        String dest = "";
        if (str!=null) {
            Pattern p = Pattern.compile("\\s*|\t|\r|\n");
            Matcher m = p.matcher(str);
            dest = m.replaceAll("");
        }
        return dest;
    }

    /**
     * 使用正则表达式提取中括号中的内容
     * @param msg
     * @return
     */
    public static List<String> extractMessageByRegular(String msg){

        List<String> list=new ArrayList<String>();
        Pattern p = Pattern.compile("\\{([^}]*)\\}");
        Matcher m = p.matcher(msg);
        while(m.find()){
            list.add(m.group().substring(1, m.group().length()-1));
        }
        return list;
    }

    public static void main(String[] args) {
        String msg = "PerformanceManager{第1个中括号}Product{第2个中括号}<{第3个中括号}79~";
        List<String> list = extractMessageByRegular(msg);
        for (int i = 0; i < list.size(); i++) {
            System.out.println(i+"-->"+list.get(i));
        }
    }


    /**
     *
     * 获取目标转化出价
     *
     * @param type 智能投放计划创建出价方式
     *             固定出价 FIX ;
     *             随机出价 RAND;
     *             阶梯出价 STEP
     * @param maxBid 转化出价最大值
     * @param minBid 转化出价最小值
     * @param stepBid 浮动间隔
     * @param lastBid 上次创建计划出价
     * @author zianY
     */
    public static BigDecimal  getRandomAdCpaBid(String type,BigDecimal maxBid,BigDecimal minBid,BigDecimal stepBid,BigDecimal lastBid,BigDecimal strategyCpaBid){
        BigDecimal reuslt = null;
        //固定出价
        if("FIX".equalsIgnoreCase(type)){
            reuslt = strategyCpaBid.setScale(2,RoundingMode.DOWN);
        }
        //随机出价
        if("RAND".equalsIgnoreCase(type)){
            double max = maxBid.doubleValue();
            double min = minBid.doubleValue();
            double randResult = min + (Math.random() * (max - min));
            randResult = (double) Math.round(randResult * 100) / 100;
            reuslt = new BigDecimal(randResult).setScale(2, RoundingMode.DOWN);
        }
        //当出价为阶梯出价时，创建的出价为 最低出价 + N * 浮动间隔 < 最高出价
        if ("STEP".equalsIgnoreCase(type)){
            double max = maxBid.doubleValue();
            double min = minBid.doubleValue();
            double last = lastBid.doubleValue();
            double step = stepBid.doubleValue();
            if(last>max||last<min){
                //如果不在出价范围内，设定为最低出价
                reuslt = minBid.setScale(2, RoundingMode.DOWN);
            }else if((last-min)%step!=0){
                //表示上次是随机出价转变为阶梯出价
                reuslt = minBid.setScale(2, RoundingMode.DOWN);
            }else if(last+step>max){
                reuslt = minBid.setScale(2, RoundingMode.DOWN);
            }else{
                reuslt = lastBid.add(stepBid).setScale(2, RoundingMode.DOWN);
            }
        }
        return reuslt;
    }

    public static int lengthAsSlogan(String a)  {
        char[] c = a.toCharArray();
        int count=0;
        for (char d : c) {
            Character.UnicodeBlock ub = Character.UnicodeBlock.of(d);
            if (ub == Character.UnicodeBlock.GENERAL_PUNCTUATION
                    || ub == Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION
                    || ub == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS
                    || ub == Character.UnicodeBlock.CJK_COMPATIBILITY_FORMS
                    || ub == Character.UnicodeBlock.VERTICAL_FORMS
                    || ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS
                    || ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A
                    || ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B
                    || ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_C
                    || ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_D
                    || ub == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS
                    || ub == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS_SUPPLEMENT) {
                count++;
            }

        }
        BigDecimal strNum = new BigDecimal(count);
        BigDecimal strlen = new BigDecimal(a.length());
        BigDecimal res = strlen.subtract(strNum).divide(new BigDecimal(2),0, BigDecimal.ROUND_UP).add(strNum);
        return res.intValue();
    }

    public static String replaceCreativeWordPackageText(String str){
        int left = str.indexOf("{");
        int right = str.indexOf("}");
        if(left < 0){
            return null;
        }
        String newStr = str.substring(left+1, right);
        return newStr;
    }



    /**
     * 获取字符串的长度，如果有中文，则每个中文字符计为2位
     * @param value 指定的字符串
     * @return 字符串的长度
     */
    public static int length(String value) {
        int valueLength = 0;
        String chinese = "[\u0391-\uFFE5]";
        Pattern number = Pattern.compile("^[-\\+]?[\\d]*$");
        /* 获取字段值的长度，如果含中文字符，则每个中文字符长度为2，否则为1 */
        for (int i = 0; i < value.length(); i++) {
            /* 获取一个字符 */
            String temp = value.substring(i, i + 1);
            /* 判断是否为中文字符 */
            if (temp.matches(chinese)) {
                valueLength += 2;
            }else {
                /* 其他字符长度为1 */
                valueLength += 1;
            }
        }
        return valueLength;
    }


    /**
     * 字符串（如果是中文则占2个字符 的 字符串） 截取
     * @param str 如果是中文则占2个字符 的 字符串
     * @param length 要截取的长度
     * @return
     * @throws Exception
     */
    public static String subStr50(String str, int length) throws Exception {
        byte[] bytes = str.getBytes("Unicode");
        int n = 0; // 表示当前的字节数
        int i = 2; // 要截取的字节数，从第3个字节开始
        for (; i < bytes.length && n < length; i++) {
            // 奇数位置，如3、5、7等，为UCS2编码中两个字节的第二个字节
            if (i % 2 == 1) {
                n++; // 在UCS2第二个字节时n加1
            }
            else {
                // 当UCS2编码的第一个字节不等于0时，该UCS2字符为汉字，一个汉字算两个字节
                if (bytes[i] != 0) {
                    n++;
                }
            }
        }
        // 如果i为奇数时，处理成偶数
        if (i % 2 == 1) {
            // 该UCS2字符是汉字时，去掉这个截一半的汉字
            if (bytes[i - 1] != 0){
                i = i - 1;
                // 该UCS2字符是字母或数字，则保留该字符
            }else{
                i = i + 1;
            }
        }
        return new String(bytes, 0, i, "Unicode");
    }


    /**
     * 计划名称 中的 素材名称 截取
     * @param adName
     * @return
     * @throws Exception
     */
    public static String adNameSubMaterial(String adName){
        try {
            //String a = "20210814-促活-站内-RTA-sf_jrtt_huichuangch_ptb_297571-ocpm-[这是这是这是这这是这是这是这是这是这是这是这是这这是这是这是这是这是]-0728";
            //获取[] 中的内容 --素材名称
            if (adName.contains("[") && adName.contains("]")){
                String materialName = adName.substring(adName.indexOf("["),adName.indexOf("]")+1);
                //广告计划名称 总长度（1个中文 占 2个字符）
                int adNameLength = length(adName.replaceAll("[\\[\\]]", ""));
                //素材名称 长度 （1个中文 占 2个字符）
                int materialLength = length(materialName.replaceAll("[\\[\\]]", ""));
                // 计划名称 字符总长度
                int totalLength = (adNameLength / 2) + (adNameLength % 2);
                //不能超过 47个长度
                if (totalLength > 47){
                    //要截取的素材名称的长度
                    int sub = (totalLength - 47) * 2 ;
                    // 去除 [] 并截取素材名称
                    String mateName = materialName.replaceAll("[\\[\\]]", "");
                    String rep = subStr50(mateName,materialLength - sub);
                    return adName.replace(materialName, rep);
                }else {
                    return adName.replaceAll("[\\[\\]]", "");
                }
            }else {
                return adName;
            }


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


}
