package com.yidian.common.utils;

import android.app.Activity;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.widget.EditText;

import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.HashMap;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class StringUtils {

    private static final String TAG = "StringUtils";
    private static HashMap<Character, String> htmlEscapString = new HashMap<Character, String>(6);

    static {
        htmlEscapString.put(new Character('&'), "&amp;");
        htmlEscapString.put(new Character('<'), "&lt");
        htmlEscapString.put(new Character('>'), "&gt");
    }

    public static String htmlTextEscap(String str) {
        if (str != null && str.length() > 0) {
            StringBuilder strBuilder = null;
            int begin = 0;
            for (int i = 0; i < str.length(); ++i) {
                final char c = str.charAt(i);
                final String value = htmlEscapString.get(new Character(c));
                if (value != null) {
                    if (strBuilder == null) {
                        strBuilder = new StringBuilder(str.length() + 20);
                    }
                    strBuilder.append(str.substring(begin, i)).append(value);
                    begin = i + 1;
                }
            }

            if (begin != 0) {
                if (begin < str.length() - 1) {
                    strBuilder.append(str.substring(begin));
                }
                return strBuilder.toString();
            }
        }
        return str;
    }

    public static boolean equals(String str1, String str2, int ignoreLastCnt) {
        if (str1 == null && str2 == null) return true;  // 都为空
        if (str1 == null || str2 == null) return false; // 一个为空，另一个不为空
        if (str1.length() != str2.length()) return false;
        if (str1.length() <= ignoreLastCnt) return true;
        String subStr1 = str1.substring(0, str1.length() - ignoreLastCnt);
        String subStr2 = str2.substring(0, str1.length() - ignoreLastCnt);
        return subStr1.equals(subStr2);   // 两个都不为空
    }

    public static boolean equals(String str1, String str2) {
        if (str1 == null && str2 == null) return true;  // 都为空
        if (str1 == null || str2 == null) return false; // 一个为空，另一个不为空
        return str1.equals(str2);   // 两个都不为空
    }

    public static boolean isBlank(String value) {
        return value == null || value.trim().equals("");
    }

    public static boolean isNotBlank(String value) {
        return value != null && !value.trim().equals("");
    }

    public static boolean isBlankLoc(String lat, String lng) {
        if (isBlank(lat) || isBlank(lng)) {
            return true;
        }
        try {
            double la = Double.valueOf(lat);
            double ln = Double.valueOf(lng);

            if (Math.abs(la - 0.0) < 0.01 && Math.abs(ln - 0.0) < 0.01)
                return true;

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

    public static String parseFloat(double data) {
        NumberFormat numberFormat = NumberFormat.getNumberInstance();
        numberFormat.setMaximumFractionDigits(2);
        numberFormat.setMinimumFractionDigits(1);
        return numberFormat.format(data);
    }

    public static String formatVersion(String version) {
        int position = version.indexOf(".");
        if (position == -1) return version;
        position = version.indexOf(".", position + 1);
        if (position == -1) return version;
        return version.substring(0, position);
    }

    public static boolean isMobileNumber(String str) {
        if (isBlank(str)) return false;
        try {
            Pattern p = Pattern.compile("^1\\d{10}$");
//            Pattern p = Pattern.compile("^((13)|(14)|(15)|(18)|(17))\\d{9}$");
            Matcher m = p.matcher(str);
            return m.matches();
        } catch (Exception e) {
        }
        return false;
    }

    public static boolean isPhoneNumber(String str) {
        if (isBlank(str)) return false;
        if (str.length() < 3) return false;
        try {
            Pattern p = Pattern.compile("^(\\d|-| )+$");
            Matcher m = p.matcher(str);
            return m.matches();
        } catch (Exception e) {
        }
        return false;
    }

    public static boolean isVerifyCode(String str) {
        if (isBlank(str)) return false;
        return true;
    }

    public static boolean isAllNumber(String str) {
        if (isBlank(str)) return false;
        for (int i = 0; i < str.length(); ++i) {
            final char c = str.charAt(i);
            if (c < '0' || c > '9') return false;
        }
        return true;
    }

    public static String join(List<String> list, String join) {
        final StringBuilder paramList = new StringBuilder();
        for (String item : list) {
            paramList.append(item);
            if (isNotBlank(join)) {
                paramList.append(join);
            }
        }
        return paramList.toString();
    }

    public static String[] split(String s, String expr) {
        if (isBlank(s) || expr == null) {
            return null;
        }

        return s.split(expr);
    }

//    public static String getFirstElement(String str, String join) {
//        int idx = str.indexOf(join);
//
//        if(idx < 0)
//            return str;
//
//        if(idx == 0)
//            return getFirstElement(str.substring(join.length()), join);
//
//        return str.substring(0, idx);
//    }


//    /**
//     * 计算字符串的长度.
//     *
//     * @param src 需要计算的字符串
//     * @return -1 表示输入的src是null值
//     */
//    public static int fetchCharNumber(String src) {
//        int counter = -1;
//        if (src != null) {
//            counter = 0;
//            final int len = src.length();
//            for (int i = 0; i < len; i++) {
//                char sigleItem = src.charAt(i);
//                if (isAlphanumeric(sigleItem)) {
//                    counter++;
//                } else if (Character.isLetter(sigleItem)) {
//                    counter = counter + 2;
//                } else {
//                    counter++;
//                }
//            }
//        } else {
//            counter = -1;
//        }
//
//        return counter;
//    }

    /**
     * 判断字符是否为英文字母或者阿拉伯数字.
     *
     * @param ch char字符
     * @return true or false
     */
    public static boolean isAlphanumeric(char ch) {
        // 常量定义
        final int DIGITAL_ZERO = 0;
        final int DIGITAL_NINE = 9;
        final char MIN_LOWERCASE = 'a';
        final char MAX_LOWERCASE = 'z';
        final char MIN_UPPERCASE = 'A';
        final char MAX_UPPERCASE = 'Z';

        if ((ch >= DIGITAL_ZERO && ch <= DIGITAL_NINE)
                || (ch >= MIN_LOWERCASE && ch <= MAX_LOWERCASE)
                || (ch >= MIN_UPPERCASE && ch <= MAX_UPPERCASE)) {
            return true;
        } else {
            return false;
        }
    }

    public static String decodeSecret(String secret, String token) {
        if (isBlank(secret) || isBlank(token)) return null;

        char firstChar = token.charAt(0);
        int firstCharAscii = firstChar;
        int lengthMove = (firstCharAscii % 5) + 1;
        if (lengthMove > secret.length()) return null;

        String decodeSecret = secret.substring(lengthMove) + secret.substring(0, lengthMove);
        return decodeSecret;
    }

    public static boolean isNewIdLarger(String currentId, String newId, boolean defaultValue) {
        if (isBlank(currentId)) return defaultValue;
        try {
            long lCurrentId = Long.parseLong(currentId);
            long lNewId = Long.parseLong(newId);
            if (lNewId > lCurrentId) {
                return true;
            } else {
                return false;
            }
        } catch (Exception e) {
        }
        return defaultValue;
    }

    public static String getCoveredCardNum(String cardNum) {
        int frontLength = 4;
        int behindLength = 4;
        return formatStringWithCovered(cardNum, frontLength, behindLength);
    }

    public static String getCoveredPhoneNum(String phoneNum) {
        int frontLength = 3;
        int behindLength = 4;
        return formatStringWithCovered(phoneNum, frontLength, behindLength);
    }

    public static String formatStringWithCovered(String unCovered, int frontLength, int behindLength) {
        if (unCovered == null) {
            return "";
        }
        unCovered = unCovered.replace(" ", "");
        int middleLength = unCovered.length() - frontLength - behindLength;
        if (middleLength <= 0) {
            return "";
        }

        String middleCovered = "";
        for (int i = 0; i < middleLength; i++) {
            middleCovered = middleCovered + "*";
        }

        return unCovered.substring(0, frontLength) + middleCovered + unCovered.substring(frontLength + middleLength);
    }

    public static String formatPrice(float price) {
        //构造方法的字符格式这里如果小数不足2位,会以0补足.
        DecimalFormat decimalFormat = new DecimalFormat("0.00");
        //format 返回的是字符串
        String p = decimalFormat.format(price);
        return p;
    }

    public static String formatPrice(double price) {
        //构造方法的字符格式这里如果小数不足2位,会以0补足.
        DecimalFormat decimalFormat = new DecimalFormat("0.00");
        //format 返回的是字符串
        String p = decimalFormat.format(price);
        return p;
    }

    public static String formatPriceAutoCut(double price) {
        String formated = formatPrice(price);
        return formated.replace(".00", "");
    }

    public static String formatPriceFriend(double price) {
        if (price > 0.00) {
            if (price < 10000) {
                NumberFormat nf = new DecimalFormat("##.##");
                return nf.format(price);
            } else if (price >= 10000) {
                price = price / 10000.00;
                NumberFormat nf = new DecimalFormat("##.##");
                nf.setRoundingMode(RoundingMode.DOWN);
                return nf.format(price) + "万";
            }
        }
        return "0.00";
    }

    public static String formatCardTailNum(String cardNum) {
        if (isBlank(cardNum)) return "";
        int length = cardNum.length();
        if (length > 4) {
            return cardNum.substring(length - 4, length);
        }
        return cardNum;
    }

    public static String formatCardBitReplaceNum(String cardNum) {
        if (isBlank(cardNum)) return "";
        int length = cardNum.length();
        if (length > 4) {
//            int bitGroupCount = length / 4 - 1;
//            int bitLeftCount = length % 4;
//            String bitCardNum = "";
//            for (int i = 0; i < bitGroupCount; i++) {
//                bitCardNum += "**** ";
//            }
//
//            if (bitLeftCount > 0) {
//                for (int j = 0; j < bitLeftCount; j++) {
//                    bitCardNum += "*";
//                }
//                bitCardNum += " ";
//            }
//
//            return bitCardNum + cardNum.substring(length - 4, length);
            return "**** **** **** " + cardNum.substring(length - 4, length);
        }
        return cardNum;
    }

    public static String formatCardNum(String cardNum) {
        if (isBlank(cardNum)) return "";
        cardNum = cardNum.replace(" ", "");
        int length = cardNum.length();
        if (length > 4) {
            int groupCount = length / 4;
            int leftCount = length % 4;
            String cardNumFormat = "";
            for (int i = 0; i < groupCount; i++) {
                if (i != 0) {
                    cardNumFormat += " ";
                }
                cardNumFormat += cardNum.substring(i * 4, i * 4 + 4);
            }

            if (leftCount > 0) {
                cardNumFormat += " ";
                cardNumFormat += cardNum.substring(length - leftCount, length);
            }

            return cardNumFormat;
        }
        return cardNum;
    }

    private static int[] convertStrToInArr(String cardNo) {
        int index = cardNo.length();
        int[] cardNoArr = new int[cardNo.length()];
        for (char c : cardNo.toCharArray()) {
            cardNoArr[--index] = c - '0';
        }
        return cardNoArr;
    }

    /**
     * 校验的具体算法实现
     *
     * @param cardNoArr
     * @return
     */
    private static boolean luhnCheck(int[] cardNoArr) {
        if (cardNoArr.length != 16 && cardNoArr.length != 19) return false;
        for (int i = 1; i < cardNoArr.length; i += 2) {
            cardNoArr[i] <<= 1;
            cardNoArr[i] = cardNoArr[i] / 10 + cardNoArr[i] % 10;
        }
        int sum = 0;
        for (int i = 0; i < cardNoArr.length; i++) {
            sum += cardNoArr[i];
        }

        return sum % 10 == 0;
    }

    public static boolean isCardNumValid(String cardNum) {
        if (isBlank(cardNum)) return false;
        if (!isAllNumber(cardNum)) return false;
        return luhnCheck(convertStrToInArr(cardNum));
    }

    public static boolean isIDNumValid(String cardNum) {
        if (isBlank(cardNum)) return false;
        if (!isAllNumber(cardNum)) return false;
        return luhnCheck(convertStrToInArr(cardNum));
    }

    //
    public static String formatPrice(int price) {
        //构造方法的字符格式这里如果小数不足2位,会以0补足.
        DecimalFormat decimalFormat = new DecimalFormat("0.00");
        //format 返回的是字符串
//        Double newPrice = Double.valueOf(price);
        String p = decimalFormat.format(price);
        return p;
    }

    /**
     * 圈友劵价格转换字符串
     * @param price
     * @return
     */
    public static String formatTicketPrice(float price) {
        try {
            //字符格式如果小数超过2位则截断，如果小数后都是0 则只显示整数
            DecimalFormat decimalFormat = new DecimalFormat("#.##");
            String str = decimalFormat.format(price);
            if (str != null) {
                int num = 0;
                for (int i = str.length() - 1; i < str.length(); i--) {
                    if (!"0".equals(str.charAt(i)) || ".".equals(str.charAt(i))) {
                        break;
                    }
                    num++;
                }
                if (num > 0) {
                    str.substring(0, (str.length() - num));
                }
                if (str.endsWith(".")) {
                    str = str.substring(0, str.length() - 1);
                }
            }
            return str;
        } catch (Exception e) {
            XLog.getINSTANCE().e("StringUtils", " formatTicketPrice error", e);
        }
        return String.valueOf(price);
    }

    /**
     * 判断字符串中是否含有特殊字符
     *
     * @param string
     * @return
     */
    public static boolean isConSpeCharacters(String string) {
        if (string.replaceAll("[\u4e00-\u9fa5]*[a-z]*[A-Z]*\\d*-*_*\\s*", "").length() == 0) {
            //不包含特殊字符
            return false;
        }
        return true;
    }

    public static String getDistance(double lng1, double lat1, double lng2, double lat2) {
        double radLat1 = Math.toRadians(lat1);
        double radLat2 = Math.toRadians(lat2);
        double a = radLat1 - radLat2;
        double b = Math.toRadians(lng1) - Math.toRadians(lng2);
        double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) + Math.cos(radLat1)
                * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2)));
        s = s * 6378137.0;// 取WGS84标准参考椭球中的地球长半径(单位:m)
        s = Math.round(s * 10000) / 10000;

        String distance = "";

        if (s / 1000 < 1) {
            distance = (int) s + "m";
        } else if (s / 1000 <= 100) {
            DecimalFormat df = new DecimalFormat("#.0");
            distance = df.format(s / 1000) + "km";
        } else {
            distance = ">100km";
        }

        return distance;
    }

    public static String numFormat999(int num) {
        if (num > 999) {
            return "999+";
        }
        return String.valueOf(num);
    }

    public static String numFormat9999(int num) {
        if (num > 9999) {
            int i = num / 10000;
            return i + "万";
        }
        return String.valueOf(num);
    }

    public static boolean containUrl(String str) {
        return isNotBlank(str) &&
                (str.contains("http://") || str.contains("https://"));
    }

    public static void setInputPrice(EditText editText) {
        editText.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {

            }

            @Override
            public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {

            }

            @Override
            public void afterTextChanged(Editable editable) {
                String temp = editable.toString();
                int posDot = temp.indexOf(".");
                if (posDot <= 0) return;
                if (temp.length() - posDot - 1 > 2) {
                    editable.delete(posDot + 3, posDot + 4);
                }
            }
        });
    }

    public static String getFriendCommentsCount(int count) {
        if (count > 999) {
            return "999+";
        }
        return count + "";
    }

    private static final long K = 1024;
    private static final long M = K * K;
    private static final long G = M * K;
    private static final long T = G * K;

    public static String bytesToHuman(final long value) {
        final long[] dividers = new long[]{T, G, M, K, 1};
        final String[] units = new String[]{"TB", "GB", "MB", "KB", "B"};
        if (value < 1)
            return 0 + " " + units[units.length - 1];
        String result = null;
        for (int i = 0; i < dividers.length; i++) {
            final long divider = dividers[i];
            if (value >= divider) {
                result = format(value, divider, units[i]);
                break;
            }
        }
        return result;
    }

    private static String format(final long value,
                                 final long divider,
                                 final String unit) {
        final double result =
                divider > 1 ? (double) value / (double) divider : (double) value;
        return new DecimalFormat("#.##").format(result) + " " + unit;
    }

    /**
     * 转换关注数、粉丝数、点赞数
     *
     * @return
     */
    public static String numberOfConversion(int num) {
        try {
//            XLog.getINSTANCE().d(TAG, "numberOfConversion num : " + num);
            if (num < 10000) {
                return String.valueOf(num);
            }

            int mod = (int) (num / 1000);
            int remainder = (int) (num % 1000);
            float thousand = mod / 10f;
            DecimalFormat decimalFormat = new DecimalFormat("#.#");
            String str = decimalFormat.format(thousand);
//            XLog.getINSTANCE().d(TAG, "numberOfConversion mod ："+mod+"  remainder : "+remainder+"   thousand : " + thousand+"    str : "+str);
            if(remainder>0){
                return String.format("%1$sw+", str);
            }else {
                return String.format("%1$s万", str);
            }

        } catch (Exception e) {
            XLog.getINSTANCE().e(TAG, "numberOfConversion error ", e);
        }
        return "0";
    }


    /**
     * 判断字符长度 超过的截断返回 。。。
     * @param text 字符串
     * @param length  长度
     * @param symbol "..."
     * @return
     */
    public static String ellipsisText(String text, int length, String symbol) {
        try {
            return text.length() > length ?
                    (text.substring(0, length) + symbol)
                    : text;
        } catch (Exception e) {
            XLog.getINSTANCE().e(TAG, "ellipsisText error ", e);
        }
        return text;
    }


    /**
     *去除字符串最后一个符号
     * @return
     */
    public static String endsWithTrim(String s, String suffix) {
        if (isBlank(s)) {
            return "";
        }
        if (s.trim().endsWith(suffix)) {
            return s.substring(0, s.length() - 1);
        }
        return s;
    }

    /**
     * Json字符串特殊字符处理
     * @param str
     * @return
     */
    public static String JsonReplace(String str) {
        try {
            if(isBlank(str)){
                return "";
            }
            String json = str;
            json = json.replace("\\", "\\\\");
            json = json.replace("\"", "\\\"");
            json = json.replace("\'", "\\\'");
            json = json.replace("\n", "\\n");
            json = json.replace("\r", "\\r");
            json = json.replace("\f", "\\f");
            json = json.replace("\u2028", "\\u2028");
            json = json.replace("\u2029", "\\u2029");
            return json;
        }catch (Exception e){
            XLog.getINSTANCE().e(TAG,"JsonReplace error ",e);
        }
        return str;
    }


    /**
     * 获取剪切板内容
     *
     * @return
     */
    public static String getClipboardContent(Activity activity) {
        try {
            ClipboardManager cm = (ClipboardManager)activity.getSystemService(Context.CLIPBOARD_SERVICE);
            if (cm != null) {
                ClipData data = cm.getPrimaryClip();
                if (data != null && data.getItemCount() > 0) {
                    ClipData.Item item = data.getItemAt(0);
                    if (item != null) {
                        CharSequence sequence = item.coerceToText(activity);
                        if (sequence != null) {
                            return sequence.toString();
                        }
                    }
                }
            }
        } catch (Exception e) {
            XLog.getINSTANCE().e(TAG, "getClipboardContent error ", e);
        }
        return "";
    }
}
