package cn.wisenergy.common.utils;

import org.apache.commons.lang3.StringUtils;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;

import java.util.*;

/**
 * 字符串工具类
 */
@Component("springUtils")
@Lazy(false)
public final class StringUtil implements ApplicationContextAware,
        DisposableBean  {



    /**
     * String转为Integer
     *
     * @param str
     * @return
     */
    public static Integer stringToInteger(String str) {
        if (str != null && !str.equalsIgnoreCase("")) {
            try {
                return new Integer(str);
            } catch (NumberFormatException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    /**
     * String转为Long
     *
     * @param str
     * @return
     */
    public static Long stringToLong(String str) {
        if (str != null && !str.equalsIgnoreCase("")) {
            try {
                return new Long(str);
            } catch (NumberFormatException e) {
            }
        }
        return null;
    }

    /**
     * 将字符串数组转化成Long数组
     *
     * @param strArr
     * @return
     */
    public static Long[] strArrToLongArr(String[] strArr) {
        Long[] longArr = new Long[strArr.length];
        for (int i = 0; i < strArr.length; i++) {
            longArr[i] = stringToLong(strArr[i]);
        }
        return longArr;
    }

    /**
     * 将字符串转化为Boolean类型
     *
     * @param str
     * @return
     */
    public static Double stringToDouble(String str) {
        if (str != null && !str.equalsIgnoreCase("")) {
            try {
                return new Double(str);
            } catch (NumberFormatException e) {
            }
        }
        return null;
    }

    /**
     * 将字符串转化为BigDecimal
     *
     * @param str
     * @return
     */
    public static BigDecimal stringToDecimal(String str) {
        if (StringUtils.isNotEmpty(str)) {
            try {
                return new BigDecimal(str);
            } catch (NumberFormatException e) {
            }
        }
        return null;
    }

    /**
     * 是否为BigDecimal类型
     *
     * @param str
     * @return
     */
    public static boolean isDecimal(String str) {
        boolean res = true;
        if (StringUtils.isEmpty(str)) {
            return false;
        }
        try {
            new BigDecimal(str);
        } catch (NumberFormatException e) {
            res = false;
        }
        return res;
    }

    /**
     * 格式化double为字符串
     *
     * @param num
     * @param pattern
     * @return
     */
    public static String formatNumToString(double num, String pattern) {
        DecimalFormat format = new DecimalFormat(pattern);
        return format.format(num);
    }

    /**
     * 格式化long为字符串
     *
     * @param num
     * @param pattern
     * @return
     */
    public static String formatNumToString(long num, String pattern) {
        DecimalFormat format = new DecimalFormat(pattern);
        return format.format(num);
    }

    /**
     * 格式化BigDecimal为字符串
     *
     * @param num
     * @param pattern
     * @return
     */
    public static String formatNumToString(BigDecimal num, String pattern) {
        DecimalFormat format = new DecimalFormat(pattern);
        return format.format(num.doubleValue());
    }

    /**
     * 格式化BigDiemal为固定格式的字符串
     *
     * @param num
     * @return
     */
    public static String formatNumToString(BigDecimal num) {
        return formatNumToString(num, "#,###.##");
    }

    /**
     * 格式化日期
     *
     * @param date
     * @param pattern
     * @return
     */
    public static Date formatDate(Date date, String pattern) {
        SimpleDateFormat dsf = new SimpleDateFormat(pattern);
        String dateStr = dsf.format(date);
        try {
            return dsf.parse(dateStr);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return date;
    }

    /**
     * 将字符串做重复多次的拼接
     *
     * @param str
     * @param n
     * @return
     */
    public static String dupStr(String str, int n) {
        StringBuffer sb = new StringBuffer("");
        for (int i = 1; i <= n; i++) {
            sb.append(str);
        }
        return sb.toString();
    }

    public static String dateToString(Date date) {
        return dateToString(date, "yyyy-MM-dd");
    }

    public static String datetimeToString(Date date) {
        return dateToString(date, "yyyy-MM-dd HH:mm:ss");
    }

    public static String dateToString(Date date, String pattern) {
        if (date != null) {
            SimpleDateFormat sdf = new SimpleDateFormat(pattern);
            return sdf.format(date);
        } else {
            return null;
        }
    }

    public static Date stringToDate(String str) {
        return stringToDate(str, "yyyy-MM-dd");
    }

    public static Date stringToDatetime(String str) {
        return stringToDate(str, "yyyy-MM-dd HH:mm:ss");
    }

    public static Date stringToDate(String str, String pattern) {
        if (StringUtils.isNotEmpty(str)) {
            SimpleDateFormat sdf = new SimpleDateFormat(pattern);
            try {
                return sdf.parse(str);
            } catch (ParseException e) {
                return null;
            }
        } else {
            return null;
        }
    }

    /**
     * double类型精度的四舍五入
     *
     * @param v
     * @param scale
     * @return
     */
    public static double round(double v, int scale) {
        if (scale < 0) {
            throw new IllegalArgumentException(
                    "The scale must be a positive integer or zero");
        } else {
            BigDecimal b = new BigDecimal(Double.toString(v));
            BigDecimal one = new BigDecimal("1");
            return b.divide(one, scale, 4).doubleValue();
        }
    }

    /**
     * 根据长度截取字符串，超过长度截取，否则不截取
     *
     * @param str
     * @param len
     * @return
     */
    public static String subStrByLen(String str, int len) {
        if (StringUtils.isNotEmpty(str)) {
            return str.trim().length() > len ? str.trim().substring(0, len)
                    : str.trim();
        }
        return str;
    }

    /**
     * 转换数组为字符串，中间用split隔开
     *
     * @param arr
     * @param split
     * @return
     */
    public static String arrayToString(String[] arr, String split) {
        if (arr == null || arr.length == 0)
            return "";

        StringBuffer buffer = new StringBuffer("");

        for (int i = 0; i < arr.length; i++) {

            if (StringUtils.isEmpty(arr[i]))
                continue;

            buffer.append(arr[i]);
            buffer.append(split);
        }

        return buffer.length() > 0 ? buffer.substring(0, buffer.length() - 1)
                : buffer.toString();
    }

    /**
     * 转换字符串数组为字符串，默认用逗号隔开
     *
     * @param arr
     * @return
     */
    public static String arrToString(String arr[]) {
        return arrayToString(arr, ",");
    }

    /**
     * 将\r\n转化为<br/>，主要用于视图页面的显示
     *
     * @param str
     * @return
     */
    public static String converRNToBR(String str) {
        if (StringUtils.isEmpty(str)) {
            return "";
        }
        return str.replaceAll("\r\n", "<br/>");
    }

    /**
     * 判断char类型的字符是否不为表情字符
     *
     * @param codePoint
     * @return
     */
    private static boolean isNotEmojiCharacter(char codePoint) {
        return (codePoint == 0x0) ||
                (codePoint == 0x9) ||
                (codePoint == 0xA) ||
                (codePoint == 0xD) ||
                ((codePoint >= 0x20) && (codePoint <= 0xD7FF)) ||
                ((codePoint >= 0xE000) && (codePoint <= 0xFFFD)) ||
                ((codePoint >= 0x10000) && (codePoint <= 0x10FFFF));
    }

    /**
     * 过滤emoji 或者 其他非文字类型的字符
     *
     * @param source
     * @return
     */
    public static String filterEmoji(String source) {
        if (source == null) {
            return null;
        }
        int len = source.length();
        StringBuilder buf = new StringBuilder(len);
        for (int i = 0; i < len; i++) {
            char codePoint = source.charAt(i);
            if (isNotEmojiCharacter(codePoint)) {
                buf.append(codePoint);
            }
        }
        return buf.toString();
    }

    /**
     * 去除字符串中的双引号
     *
     * @param str
     * @return
     */
    public static String trimDoubleQuotations(String str) {
        if (str == null) {
            return null;
        }
        return str.replaceAll("\"", "");
    }

    /**
     * 判断字符是否为中文
     *
     * @param c
     * @return
     */
    public static boolean isChinese(char c) {
        Character.UnicodeBlock ub = Character.UnicodeBlock.of(c);
        if (ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS || ub == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS
                || ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A || ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B
                || ub == Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION || ub == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS
                || ub == Character.UnicodeBlock.GENERAL_PUNCTUATION) {
            return true;
        }
        return false;
    }

    /**
     * 判断字符串是否包括中文
     *
     * @param strName
     * @return
     */
    public static boolean isContainsChinese(String strName) {
        char[] ch = strName.toCharArray();
        for (int i = 0; i < ch.length; i++) {
            char c = ch[i];
            if (isChinese(c)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 获取字符串长度（汉子算两位）
     *
     * @param s
     * @return
     */
    public static int getLength(String s) {
        int length = 0;
        char[] ch = s.toCharArray();
        for (char c : ch) {
            if (StringUtil.isChinese(c)) {
                length += 2;
            } else {
                length += 1;
            }
        }
        return length;
    }


    /**
     * 获取字符串长度（汉子算两位）
     *
     * @param s
     * @return
     */
    public static int getLengthByUtf8(String s) {
        int length = 0;
        char[] ch = s.toCharArray();
        for (char c : ch) {
            if (StringUtil.isChinese(c)) {
                length += 3;
            } else {
                length += 1;
            }
        }
        return length;
    }

    /**
     * 指定长度后面补指定字符
     *
     * @param s
     * @param len
     * @param item
     * @return
     */
    public static String addChars(String s, int len, String item) {
        if (StringUtils.isBlank(s)) {
            return "";
        }

        int length = getLength(s);

        if (length >= len) {
            return s;
        } else {
            int count = len - length;
            StringBuilder sb = new StringBuilder(s);
            for (int i = 0; i < count; i++) {
                sb.append(item);
            }
            return sb.toString();
        }

    }

    /**
     * 指定长度后面补空格
     *
     * @param s
     * @param len
     * @return
     */
    public static String addSpace(String s, int len) {
        return addChars(s, len, " ");
    }

    /**
     * 指定字节长度后面补空格
     *
     * @param s
     * @param len
     * @return
     */
    public static String addSpaceByByteLen(String s, int len) {
        if ("".equals(s)) {
            return StringUtils.rightPad(s, len);
        }
        int length = org.apache.commons.codec.binary.StringUtils.getBytesUtf8(s).length;

        int strLength = getLength(s);

        if (len <= length) {
            return s;
        }
        return StringUtils.rightPad(s, len - (length - strLength));
    }

    /**
     * 指定空格前面补空格
     *
     * @param s
     * @param len
     * @return
     */
    public static String addLeftSpace(String s, int len) {
        int length = getLength(s);
        if (length >= len) {
            return s;
        } else {
            int count = len - length;
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < count; i++) {
                sb.append(" ");
            }
            sb.append(s);
            return sb.toString();
        }
    }

    /**
     * 指定长度两头加空格
     *
     * @param s
     * @param len
     * @return
     */
    public static String addBothSpace(String s, int len) {
        int length = getLength(s);

        if (length >= len) {
            return s;
        } else {
            int count = len - length;
            count = count / 2;
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < count; i++) {
                sb.append(" ");
            }
            StringBuilder sb2 = new StringBuilder();
            sb2.append(sb.toString());
            sb2.append(s);
            sb2.append(sb.toString());
            return sb2.toString();
        }
    }

    /**
     * 把 "1,2,3,4,5,6,7"  转化为list
     *
     * @param s 入参
     * @return 结果
     */
    public static List<Integer> strToArray(String s) {
        if (StringUtils.isEmpty(s)) {
            return new ArrayList<>();
        }

        List<Integer> result = new ArrayList<>();
        String[] str = s.split(",");
        for (String string : str) {
            result.add(Integer.valueOf(string));
        }
        return result;
    }

    /**
     * applicationContext
     */
    private static ApplicationContext applicationContext;


//    public static void setApplicationContext(ApplicationContext applicationContext) {
//        StringUtil.applicationContext = applicationContext;
//    }

    /**
     * 不可实例化
     */
    private StringUtil() { }

//    public void setApplicationContext(ApplicationContext applicationContext) {
//        SpringUtils.applicationContext = applicationContext;
//    }

    public void destroy() throws Exception {
        applicationContext = null;
    }

    /**
     * 获取applicationContext
     *
     * @return applicationContext
     */
    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }

    /**
     * 获取实例
     *
     * @param name
     *            Bean名称
     * @return 实例
     */
    @SuppressWarnings("deprecation")
    public static Object getBean(String name) {
        Assert.hasText(name);
        return applicationContext.getBean(name);
    }

    /**
     * 获取实例
     *
     * @param name
     *            Bean名称
     * @param type
     *            Bean类型
     * @return 实例
     */
    @SuppressWarnings("deprecation")
    public static <T> T getBean(String name, Class<T> type) {
        Assert.hasText(name);
        Assert.notNull(type);
        return applicationContext.getBean(name, type);
    }

    /**
     * 根据传入的字符串和切割方式返回一个Long的集合
     * @param s
     * @param cut
     * @return
     */
    public static Set<Long> string2LongSet(String s, String cut) {
        if(StringUtils.isBlank(s) ){
            return null;
        }
        if(StringUtils.isBlank(cut)){
            cut = Constants.Connnector.COMMA_;
        }
        String s_temp = s.trim();
        String[] arr = s_temp.split(cut);
        Set<Long> list = new HashSet<Long>();
        if(arr==null || arr.length<=0){
            return null;
        }
        for(String l : arr){
            if(!StringUtils.isBlank(l)){
                try {
                    list.add(Long.parseLong(l));
                } catch (NumberFormatException e) {
                    e.printStackTrace();
                    continue;
                }
            }
        }
        return list;
    }
    /**
     * 根据传入的字符串和切割方式返回一个object的集合
     * @param s
     * @param cut
     * @return
     * @author:
     * @date:
     */
    public static List<String> string2StringList(String s, String cut) {
        if(StringUtils.isBlank(s)){
            return null;
        }
        if(StringUtils.isBlank(cut)){
            cut = Constants.Connnector.COMMA_;
        }
        String s_temp = s.trim();
        String[] arr = s_temp.split(cut);
        List<String> list = new ArrayList<String>();
        if(arr==null || arr.length<=0){
            return null;
        }
        for(String l : arr){
            if(!StringUtils.isBlank(l)){
                list.add(l);
            }
        }
        return list;
    }
    /**
     * 根据出入的参数创建一个key
     * @return 如果参数为空，那么返回null
     */
    public static String formatKeys(String ... args){
        if (args != null && args.length > 0){
            StringBuilder key = new StringBuilder();
            for (String s: args){
                key.append(s).append(Constants.Connnector.UNDERLINE);
            }
            return key.toString();
        }
        return null;
    }

    /**
     * 根据出入的参数创建一个Redis key，自动拼接前缀
     * @return 如果参数为空，那么返回null
     */
    public static String formatKeyWithPrefix(String ... args){
        if (args != null && args.length > 0){
            StringBuffer key=new StringBuffer("");
            for (String s: args){
                key.append(s).append(Constants.Connnector.COLON);
            }
            return key.toString();
        }
        return null;
    }


    /**
     * Description: 创建一个简单的map对象
     * @param key
     * @param value
     * @return
     * @Author
     * @since
     */
    public static Map<String,Object> createSimpleMap(String key, Object value){
        Map<String,Object> conditions = null;
        if(key !=null && !key.equals("")){
            conditions = new HashMap<String,Object>();
            conditions.put(key, value);
        }
        return conditions;
    }
    /***
     * 判断字符串是否为空
     * @param temp
     * @return
     */
    public static boolean isBlank(String temp){
        return StringUtils.isBlank(temp);
    }

    /**
     * 返回一个没有中划线的32位字符串
     * @return
     */
    public static String createToken(){
        return UUID.randomUUID().toString().replace("-","");
    }


    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        StringUtil.applicationContext = applicationContext;
    }
}
