package com.patzn.lims.common;

import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.patzn.lims.core.api.PtAssert;
import com.patzn.lims.core.enums.IBaseEnum;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;

import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author wwd
 */
public class StringHandleUtils {
    public static String getContinuousStringData(String[] intString, String stringPre) {

        StringBuffer result = new StringBuffer();
        if (null == intString || intString.length == 0) {
            return "";
        }
        if (intString.length == 1) {
            return stringPre + intString[0];
        }
        for (String string : intString) {
            try {
                Integer.parseInt(string);
            } catch (Exception e) {
                return "";
            }
        }
        int[] a = new int[intString.length];

        for (int i = 0; i < intString.length; i++) {
            a[i] = Integer.parseInt(intString[i]);
        }
        Arrays.sort(a);
        if (a[0] + 1 != a[1]) {
            result.append(stringPre + intString[0] + ",");
        } else {
            result.append(stringPre + intString[0] + "~");
        }
        for (int i = 1; i < a.length - 1; i++) {
            if ((a[i] - 1 != a[i - 1]) & (a[i] + 1 != a[i + 1])) {
                result.append(stringPre + intString[i] + ",");
            } else if ((a[i] - 1 == a[i - 1]) & (a[i] + 1 != a[i + 1])) {
                result.append(stringPre + intString[i] + ",");
            } else if ((a[i] - 1 == a[i - 1]) & (a[i] + 1 == a[i + 1])) {
                result.append("");
            } else {
                result.append(stringPre + intString[i] + "~");
            }
        }

        result.append(stringPre + intString[a.length - 1]);
        return result.toString();

    }

    public static String getNumFromString(String str) {
        String regEx = "[^0-9]";
        Pattern p = Pattern.compile(regEx);
        Matcher m = p.matcher(str);
        String outNum = m.replaceAll("").trim();
        return outNum;
    }

    public static String join(Collection<String> collection) {
        return join(collection, "、");
    }

    public static String join(Collection<String> collection, String sep) {
        if (CollectionUtils.isEmpty(collection)) {
            return "";
        }
        if (StringUtils.isEmpty(sep)) {
            sep = ",";
        }
        StringBuffer result = new StringBuffer();
        // 给内容去重
        Set<String> sets = Sets.newLinkedHashSet(collection);
        for (String s : sets) {
            result.append(s).append(sep);
        }
        return StringUtils.isEmpty(result) ? "" : result.deleteCharAt(result.toString().length() - 1).toString();
    }


    public static String joinNormal(Collection<String> collection, String sep) {
        if (CollectionUtils.isEmpty(collection)) {
            return "";
        }
        if (StringUtils.isEmpty(sep)) {
            sep = ",";
        }
        StringBuffer result = new StringBuffer();
        // 给内容去重
        Set<String> sets = Sets.newLinkedHashSet(collection);
        for (String s : sets) {
            result.append(s).append(sep);
        }
        return StringUtils.isEmpty(result) ? "" : result.toString();
    }



    public static String joinLong(Collection<Long> collection, String sep) {
        if (CollectionUtils.isEmpty(collection)) {
            return "";
        }
        if (StringUtils.isEmpty(sep)) {
            sep = ",";
        }
        StringBuffer result = new StringBuffer();
        // 给内容去重
        Set<Long> sets = Sets.newLinkedHashSet(collection);
        for (Long s : sets) {
            result.append(s).append(sep);
        }
        return StringUtils.isEmpty(result) ? "" : result.deleteCharAt(result.toString().length() - 1).toString();
    }

    public static String getReplacePreporty(String replace) {
        if (StringUtils.isBlank(replace)) {
            return "";
        }

        if (!replace.contains("${")) {
            return replace;
        }
        if (!replace.contains("}")) {
            return replace;
        }

        try {


            if (replace.contains(".")) {
                String replaced = replace.replace("}", "");
                String[] arrayReplaced = replaced.split("\\.");
                return arrayReplaced[1];
            } else {
                return replace.replace("$", "").replace("{", "").replace("}", "");
            }

        } catch (Exception e) {
            return replace;
        }


    }

    public static boolean isYesOrNo(String str) {
        if (StringUtils.isEmpty(str)) {
            return false;
        }
        return "是".equals(str) || "否".equals(str);
    }


    public static String getChineseYesNo(String str) {
        if (StringUtils.isEmpty(str)) {
            return "";
        }
        if ("0".equals(str)) {
            return "否";
        } else if ("1".equals(str)) {
            return "是";
        } else {
            return "";
        }
    }


    public static boolean equals(String str, String param) {
        if (StringUtils.isEmpty(str)) {
            return false;
        }
        return str.equals(param);
    }


    public static String getExcepLastOne(String string) {
        if (StringUtils.isEmpty(string)) {
            return "";
        }
        return string.substring(0, string.length() - 1);
    }


    public static String getSnJoinString(Map<String, List<String>> snMap) {
        StringBuffer snBuffer = new StringBuffer();
        for (Map.Entry<String, List<String>> map : snMap.entrySet()) {
            String[] array = new String[map.getValue().size()];
            int length = map.getValue().size();
            for (int i = 0; i < length; i++) {
                array[i] = map.getValue().get(i);
            }

            Arrays.sort(array);
            snBuffer.append(StringHandleUtils.getContinuousStringData(array, map.getKey())).append(",");
        }
        return snBuffer.toString();
    }


    public static StringBuilder getAppendContent(StringBuilder builder, String content) {
        if (StringUtils.isEmpty(content)) {
            return builder;
        }
        if (builder.toString().contains(content)) {
            return builder;
        }
        builder.append(content);
        return builder;
    }

    public static List<String> compareSys() {
        List<String> compareList = new ArrayList<>();
        compareList.add("<");
        compareList.add(">");
        compareList.add("=");
        compareList.add("≥");
        compareList.add("≤");
        compareList.add("#");
        return compareList;
    }

    public static boolean compareIsOk(String compare) {
        if (StringUtils.isBlank(compare)) {
            return false;
        }
        return StringHandleUtils.compareSys().contains(compare);
    }

    public static boolean isInterval(String limitValue) {
        if (StringUtils.isBlank(limitValue)) {
            return false;
        }
        if (!limitValue.contains(StringStaticDataUtils.JING)) {
            return false;
        }

        if (limitValue.split(StringStaticDataUtils.JING).length != 2) {
            return false;
        }
        if (!NumberUtils.isDigits(limitValue.split(StringStaticDataUtils.JING)[0])) {
            return false;
        }
        if (!NumberUtils.isDigits(limitValue.split(StringStaticDataUtils.JING)[1])) {
            return false;
        }

        if (NumberUtils.createBigDecimal(limitValue.split(StringStaticDataUtils.JING)[0])
                .compareTo(NumberUtils.createBigDecimal(limitValue.split(StringStaticDataUtils.JING)[1])) > 0) {
            return false;
        }

        return true;
    }


    public static String getString(String string) {
        if (StringUtils.isEmpty(string)) {
            return "";
        }
        return string;
    }

    public static List<String> getDiffrent(Collection<String> list1, Collection<String> list2) {
        List<String> diff = new ArrayList<>();
        for (String str : list1) {
            if (!list2.contains(str)) {
                diff.add(str);
            }
        }
        return diff;
    }


    public static String getAttributesFromCodeRules(String code) {
        String[] codeArray = code.split("\\.");
        if (codeArray.length < 2) {
            return "";
        }
        return StringHandleUtils.getExcepLastOne(codeArray[1]);
    }


    public static String getFieldValueByFieldName(String fieldName, Object o) {
        try {
            String firstLetter = fieldName.substring(0, 1).toUpperCase();
            String getter = "get" + firstLetter + fieldName.substring(1);
            Method method = o.getClass().getMethod(getter, new Class[]{});
            Object value = method.invoke(o, new Object[]{});
            if (value instanceof Date) {
                return DateUtils.toYearMonthDay((Date) value);
            }
            return value.toString();
        } catch (Exception e) {
            return "";
        }
    }


    public static Object getObjectValue(Object object) {
        if (null == object) {
            return "";
        }
        if (object instanceof Integer) {
            if (object.toString().equalsIgnoreCase(StringStaticDataUtils.ONE)) {
                return "是";
            }
            if (object.toString().equalsIgnoreCase(StringStaticDataUtils.ZERO)) {
                return "否";
            }
        }
        if (object instanceof IBaseEnum) {
            return ((IBaseEnum) object).getDisplay();
        }
        return object;
    }


    public static boolean isOnlyZeroOne(String string) {
        if (StringUtils.isBlank(string)) {
            return false;
        }
        return StringStaticDataUtils.ONE.equals(string) || StringStaticDataUtils.ZERO.equals(string);
    }

    public static String getObjectDifferent(String title, Map<String, String> propertyNameMap, Map<String, List<Object>>... intArray) {
        return StringHandleUtils.getObjectDifferent(title, propertyNameMap, Arrays.asList(intArray));
    }


    public static String getObjectDifferent(String title, Map<String, String> propertyNameMap, List<Map<String, List<Object>>> intArray) {
        int length = 0;
        for (Map<String, List<Object>> map : intArray) {
            length += map.size();
        }
        if (length == 0) {
            return "";
        }
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append(title);
        for (Map<String, List<Object>> map : intArray) {
            for (Map.Entry<String, List<Object>> content : map.entrySet()) {
                stringBuilder.append(propertyNameMap.get(content.getKey())).append("由").append(StringHandleUtils.getObjectValue(content.getValue().get(1))).append("修改为").append(StringHandleUtils.getObjectValue(content.getValue().get(0))).append("、");
            }
        }
        return StringHandleUtils.getExcepLastOne(stringBuilder.toString());
    }


    public static String getObjectFromMap(Map<Integer, String> map, Integer key) {
        for (Map.Entry<Integer, String> m : map.entrySet()) {
            if (m.getKey().equals(key)) {
                return m.getValue().replace("{", "").replace("}", "")
                        .replace("(", "").replace(")", "")
                        .replace("#", "").replace("&", "")
                        .replace("*", "")
                        .replace("$", "")
                        .replace("@", "");
            }
        }
        return "";
    }

    public static String getSameElement(List<String> list) {
        String[] indexArr;
        Map<String, String> map = new HashMap<>();
        for (int i = 0; i < list.size(); i++) {
            String key = list.get(i);
            String old = map.get(key);
            if (old != null) {
                map.put(key, old + "," + (i + 1));
            } else {
                map.put(key, "" + (i + 1));
            }
        }
        Iterator<String> it = map.keySet().iterator();
        int index = -1;
        List<String> repeatList = Lists.newArrayList();
        while (it.hasNext()) {
            String key = it.next();
            String value = map.get(key);
            if (value.indexOf(",") != -1) {
                repeatList.add(key);
                indexArr = value.split(",");
                for (int i = 0; i < indexArr.length; i++) {
                    index = Integer.parseInt(indexArr[i]) - 1;
                    list.set(index, list.get(index) + (1 + i));
                }
            }
        }
        return StringHandleUtils.join(repeatList);
    }


    public static boolean containsString(String text, String... strings) {
        for (String str : strings) {
            if (text.contains(str)) {
                return true;
            }
        }
        return false;
    }

    public static <T extends Comparable<T>> boolean compareListEqual(List<T> a, List<T> b) {
        if (a.size() != b.size())
            return false;
        Collections.sort(a);
        Collections.sort(b);
        for (int i = 0; i < a.size(); i++) {
            if (!a.get(i).equals(b.get(i)))
                return false;
        }
        return true;
    }

    public static boolean isNumeric(String str) {
        String regex = "-[0-9]+(.[0-9]+)?|[0-9]+(.[0-9]+)?";
        if (str == null || !str.matches(regex)) {
            return false;
        }
        return true;
    }

    public static boolean stringIsLong(String id) {
        try {
            Long.parseLong(id);
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    public static String parse(CharSequence cs) {
        return parse(cs, "");
    }

    public static String parse(CharSequence cs, String defVal) {
        if (StringUtils.isEmpty(defVal)) {
            defVal = "";
        }
        return StringUtils.isEmpty(cs) ? defVal : cs.toString();
    }


    public static String[] getArrayFromStringBySplit(String string, String split) {
        if (StringUtils.isBlank(string)) {
            return null;
        }
        return string.split(split);
    }


    public static String getRepeatDataFromList(List<String> list) {
        Map<String, Integer> map = new HashMap<String, Integer>();
        for (String str : list) {
            Integer count = 1;
            if (map.get(str) != null) {
                count = map.get(str) + 1;
            }
            map.put(str, count);
        }

        StringBuffer buffer = new StringBuffer();
        for (String key : map.keySet()) {
            if (map.get(key) > 1) {
                buffer.append(key).append("、");
            }
        }
        return StringHandleUtils.getExcepLastOne(buffer.toString());
    }


    public static String getBigNum(String NumStr) {

        String HanDigiStr[] = new String[]{"零", "壹", "贰", "叁", "肆", "伍",
                "陆", "柒", "捌", "玖"};

        String HanDiviStr[] = new String[]{"", "拾", "佰", "仟", "万", "拾", "佰", "仟", "亿", "拾", "佰", "仟", "万", "拾", "佰", "仟", "亿", "拾", "佰", "仟", "万", "拾", "佰", "仟"};

        String RMBStr = "";
        boolean lastzero = false;
        boolean hasvalue = false; // 亿、万进位前有数值标记
        int len, n;
        len = NumStr.length();
        if (len > 15) {
            return "";
        }

        for (int i = len - 1; i >= 0; i--) {
            if (NumStr.charAt(len - i - 1) == ' ') {
                continue;
            }

            n = NumStr.charAt(len - i - 1) - '0';
            if (n < 0 || n > 9) {
                return "";
            }


            if (n != 0) {
                if (lastzero) {
                    RMBStr += HanDigiStr[0]; // 若干零后若跟非零值，只显示一个零
                }

                // 除了亿万前的零不带到后面
                // if( !( n==1 && (i%4)==1 && (lastzero || i==len-1) ) ) //
                // 如十进位前有零也不发壹音用此行
                if (!(n == 1 && (i % 4) == 1 && i == len - 1)) {
                    RMBStr += HanDigiStr[n];
                    RMBStr += HanDiviStr[i]; // 非零值后加进位，个位为空
                    hasvalue = true; // 置万进位前有值标记
                }


            } else {
                if ((i % 8) == 0 || ((i % 8) == 4 && hasvalue)) { // 亿万之间必须有非零值方显示万
                    RMBStr += HanDiviStr[i]; // “亿”或“万”
                }
            }
            if (i % 8 == 0) {
                hasvalue = false; // 万进位前有值标记逢亿复位
                lastzero = (n == 0) && (i % 4 != 0);
            }

        }

        if (RMBStr.length() == 0) {
            return HanDigiStr[0]; // 输入空字符或"0"，返回"零"
        }

        return RMBStr;
    }

    public static String getSmallChineseNum(Integer num) {
        if (null == num) {
            return "";
        }
        String NumStr = String.valueOf(num);
        String HanDigiStr[] = new String[]{"零", "一", "二", "三", "四", "五",
                "六", "七", "八", "九"};
        String HanDiviStr[] = new String[]{"", "十", "百", "千", "万", "十", "百", "千", "亿", "十", "百", "千", "万", "十", "百", "千", "亿", "十", "百", "千", "万", "十", "百", "千"};

        String RMBStr = "";
        boolean lastzero = false;
        boolean hasvalue = false; // 亿、万进位前有数值标记
        int len, n;
        len = NumStr.length();
        if (len > 15) {
            return "";
        }

        for (int i = len - 1; i >= 0; i--) {
            if (NumStr.charAt(len - i - 1) == ' ') {
                continue;
            }

            n = NumStr.charAt(len - i - 1) - '0';
            if (n < 0 || n > 9) {
                return "";
            }


            if (n != 0) {
                if (lastzero) {
                    RMBStr += HanDigiStr[0]; // 若干零后若跟非零值，只显示一个零
                }

                // 除了亿万前的零不带到后面
                // if( !( n==1 && (i%4)==1 && (lastzero || i==len-1) ) ) //
                // 如十进位前有零也不发壹音用此行
                if (!(n == 1 && (i % 4) == 1 && i == len - 1)) {
                    RMBStr += HanDigiStr[n];
                    RMBStr += HanDiviStr[i]; // 非零值后加进位，个位为空
                    hasvalue = true; // 置万进位前有值标记
                }


            } else {
                if ((i % 8) == 0 || ((i % 8) == 4 && hasvalue)) { // 亿万之间必须有非零值方显示万
                    RMBStr += HanDiviStr[i]; // “亿”或“万”
                }
            }
            if (i % 8 == 0) {
                hasvalue = false; // 万进位前有值标记逢亿复位
                lastzero = (n == 0) && (i % 4 != 0);
            }

        }

        if (RMBStr.length() == 0) {
            return HanDigiStr[0]; // 输入空字符或"0"，返回"零"
        }

        return RMBStr;
    }

    public static String convertBlankString(String str, String replace) {
        return StringUtils.isBlank(str) ? replace : str;
    }


    public static String getCentreValue(String xdata, String pre, String suffix) {
        try {
            return xdata.substring(xdata.indexOf(pre) + pre.length(), xdata.lastIndexOf(suffix)).trim();
        } catch (Exception e) {
            return "";
        }

    }


    public static String getAfterStrFirstNum(String xdata, String pre) {
        try {
            String[] array = xdata.split(pre);
            if (array.length > 1) {
                String itemAfter = array[1].trim();
                int length = itemAfter.length();
                StringBuffer sb = new StringBuffer();
                for (int i = 0; i < length; i++) {
                    char a = itemAfter.charAt(i);
                    String v = String.valueOf(a);
                    if (".".equals(v) || Character.isDigit(a)) {
                        sb.append(v);
                    } else {
                        break;
                    }

                }
                return sb.toString();
            }
        } catch (Exception e) {
            return "";
        }
        return "";
    }


    public static void emptyArrayJudge(Long[] ids) {
        if (ArrayUtils.isEmpty(ids)) {
            PtAssert.fail("请选择待提交的数据！");
        }
    }

    public static void preportyIsNotBlank(String name,String tips) {
        if (StringUtils.isBlank(name)) {
            PtAssert.fail(tips);
        }
    }

    public static void objectIsNotBlank(Object obj,String tips) {
        if(null==obj){
            PtAssert.fail(tips);
            return;
        }
        if(obj instanceof String){
            if (StringUtils.isBlank(obj.toString())) {
                PtAssert.fail(tips);
            }
        }else if(obj instanceof Integer){
            if ( (Integer)obj<=0) {
                PtAssert.fail(tips);
            }
        }
    }




    /**
     * 统计srcStr中indexStr的出现次数
     *
     * @param srcStr   源文本
     * @param indexStr 要查找的文本
     * @return 出现次数
     */
    public static int countAppearStr(String srcStr, String indexStr) {
        if (StringUtils.isBlank(srcStr) || StringUtils.isBlank(indexStr)) {
            return 0;
        }
        int count = 0;
        int index = 0;
        while ((index = srcStr.indexOf(indexStr, index)) != -1) {
            index = index + indexStr.length();
            count++;
        }
        return count;
    }


    public static String deleteIndexChar(String str, int index) {
        if (StringUtils.isBlank(str)) {
            return str;
        }

        StringBuilder sb = new StringBuilder();
        int length = str.length();

        for (int j = 0; j < length; j++) {
            if (j != index) {
                sb.append(str.charAt(j));

            }
        }
        return sb.toString();
    }


    public static int compareBig(String one, String two) {
       return new BigDecimal(one).compareTo(new BigDecimal(two));

    }
}
