package com.tzy.framework.pay.util;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.*;

@Slf4j
public final class FormatUtil {
	/** ==============IS Base=================== */
	/** 判断是否为整数(包括负数) */
	public static boolean isNumber(Object arg) {
		return NumberBo(0, toString(arg));
	}

	/** 判断是否为小数(包括整数,包括负数) */
	public static boolean isDecimal(Object arg) {
		return NumberBo(1, toString(arg));
	}

	/** 判断是否为空 ,为空返回true */
	public static boolean isEmpty(Object arg) {
		return toStringTrim(arg).length() == 0 ? true : false;
	}

	/** ==============TO Base=================== */
	/**
	 * Object 转换成 Int 转换失败 返回默认值 0 <br>
	 * 使用:toInt(值,默认值[选填])
	 */
	public static int toInt(Object... args) {
		int def = 0;
		if (args != null) {
			String str = toStringTrim(args[0]);
			// 判断小数情况。舍弃小数位
			int stri = str.indexOf('.');
			str = stri > 0 ? str.substring(0, stri) : str;
			if (args.length > 1)
				def = Integer.parseInt(args[args.length - 1].toString());
			if (isNumber(str))
				return Integer.parseInt(str);
		}
		return def;
	}

	/**
	 * Object 转换成 Long 转换失败 返回默认值 0 <br>
	 * 使用:toLong(值,默认值[选填])
	 */
	public static long toLong(Object... args) {
		Long def = 0L;
		if (args != null) {
			String str = toStringTrim(args[0]);
			if (args.length > 1)
				def = Long.parseLong(args[args.length - 1].toString());
			if (isNumber(str))
				return Long.parseLong(str);
		}
		return def;
	}

	/**
	 * Object 转换成 Double 转换失败 返回默认值 0 <br>
	 * 使用:toDouble(值,默认值[选填])
	 */
	public static double toDouble(Object... args) {
		double def = 0;
		if (args != null) {
			String str = toStringTrim(args[0]);
			if (args.length > 1)
				def = Double.parseDouble(args[args.length - 1].toString());
			if (isDecimal(str))
				return Double.parseDouble(str);
		}
		return def;
	}

	/**
	 * Object 转换成 BigDecimal 转换失败 返回默认值 0 <br>
	 * 使用:toDecimal(值,默认值[选填]) 特别注意: new BigDecimal(Double) 会有误差，得先转String
	 */
	public static BigDecimal toDecimal(Object... args) {
		return new BigDecimal(Double.toString(toDouble(args)));
	}

	/**
	 * Object 转换成 Boolean 转换失败 返回默认值 false <br>
	 * 使用:toBoolean(值,默认值[选填])
	 */
	public static boolean toBoolean(String bool) {
		if (isEmpty(bool) || (!bool.equals("1") && !bool.equalsIgnoreCase("true") && !bool.equalsIgnoreCase("ok")))
			return false;
		else
			return true;
	}

	/**
	 * Object 转换成 String 为null 返回空字符 <br>
	 * 使用:toString(值,默认值[选填])
	 */
	public static String toString(Object... args) {
		String def = "";
		if (args != null) {
			if (args.length > 1)
				def = toString(args[args.length - 1]);
			Object obj = args[0];
			if (obj == null)
				return def;
			return obj.toString();
		} else {
			return def;
		}
	}

	/**
	 * Object 转换成 String[去除所以空格]; 为null 返回空字符 <br>
	 * 使用:toStringTrim(值,默认值[选填])
	 */
	public static String toStringTrim(Object... args) {
		String str = toString(args);
		return str.replaceAll("\\s*", "");
	}

	/** ==============Other Base=================== */
	public static String getNowTime() {
		return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
	}

	/** 数字左边补0 ,obj:要补0的数， length:补0后的长度 */
	public static String leftPad(Object obj, int length) {
		return String.format("%0" + length + "d", toInt(obj));
	}

	/** 小数 转 百分数 */
	public static String toPercent(Double str) {
		StringBuffer sb = new StringBuffer(Double.toString(str * 100.0000d));
		return sb.append("%").toString();
	}

	/** 百分数 转 小数 */
	public static Double toPercent2(String str) {
		if (str.charAt(str.length() - 1) == '%')
			return Double.parseDouble(str.substring(0, str.length() - 1)) / 100.0000d;
		return 0d;
	}

	/**
	 * 将byte[] 转换成字符串
	 */
	public static String byte2Hex(byte[] srcBytes) {
		StringBuilder hexRetSB = new StringBuilder();
		for (byte b : srcBytes) {
			String hexString = Integer.toHexString(0x00ff & b);
			hexRetSB.append(hexString.length() == 1 ? 0 : "").append(hexString);
		}
		log.info("destBytes >>{} ",hexRetSB);
		return hexRetSB.toString();
	}

	/**
	 * 将16进制字符串转为转换成字符串
	 */
	public static byte[] hex2Bytes(String source) {
		byte[] sourceBytes = new byte[source.length() / 2];
		for (int i = 0; i < sourceBytes.length; i++) {
			sourceBytes[i] = (byte) Integer.parseInt(source.substring(i * 2, i * 2 + 2), 16);
		}
		return sourceBytes;
	}

	/** String 转 Money */
	public static String toMoney(Object str, String MoneyType) {
		DecimalFormat df = new DecimalFormat(MoneyType);
		if (isDecimal(str))
			return df.format(toDecimal(str)).toString();
		return df.format(toDecimal("0.00")).toString();
	}

	/** 获取字符串str 左边len位数 */
	public static String getLeft(Object obj, int len) {
		String str = toString(obj);
		if (len <= 0)
			return "";
		if (str.length() <= len)
			return str;
		else
			return str.substring(0, len);
	}

	/** 获取字符串str 右边len位数 */
	public static String getRight(Object obj, int len) {
		String str = toString(obj);
		if (len <= 0)
			return "";
		if (str.length() <= len)
			return str;
		else
			return str.substring(str.length() - len, str.length());
	}

	/**
	 * 首字母变小写
	 */
	public static String firstCharToLowerCase(String str) {
		Character firstChar = str.charAt(0);
		String tail = str.substring(1);
		str = Character.toLowerCase(firstChar) + tail;
		return str;
	}

	/**
	 * 首字母变大写
	 */
	public static String firstCharToUpperCase(String str) {
		Character firstChar = str.charAt(0);
		String tail = str.substring(1);
		str = Character.toUpperCase(firstChar) + tail;
		return str;
	}

	/**
	 * List集合去除重复值 只能用于基本数据类型，。 对象类集合，自己写
	 * */
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public static List delMoreList(List list) {
		Set set = new HashSet();
		List newList = new ArrayList();
		for (Iterator iter = list.iterator(); iter.hasNext();) {
			Object element = iter.next();
			if (set.add(element))
				newList.add(element);
		}
		return newList;
	}

	public static String formatParams(String message, Object[] params) {
		StringBuffer msg = new StringBuffer();
		String temp = "";
		for (int i = 0; i < params.length + 1; i++) {
			int j = message.indexOf("{}") + 2;
			if (j > 1) {
				temp = message.substring(0, j);
				temp = temp.replaceAll("\\{\\}", FormatUtil.toString(params[i]));
				msg.append(temp);
				message = message.substring(j);
			} else {
				msg.append(message);
				message = "";
			}
		}
		return msg.toString();
	}

	/** ============== END =================== */
	public final static class MoneyType {
		/** * 保留2位有效数字，整数位每3位逗号隔开 （默认） */
		public static final String DECIMAL = "#,##0.00";
		/** * 保留2位有效数字 */
		public static final String DECIMAL_2 = "0.00";
		/** * 保留4位有效数字 */
		public static final String DECIMAL_4 = "0.0000";
	}

	private static boolean NumberBo(int type, Object obj) {
		if (isEmpty(obj))
			return false;
		int points = 0;
		int chr = 0;
		String str = toString(obj);
		for (int i = str.length(); --i >= 0;) {
			chr = str.charAt(i);
			if (chr < 48 || chr > 57) { // 判断数字
				if (i == 0 && chr == 45) // 判断 - 号
					return true;
				if (i >= 0 && chr == 46 && type == 1) { // 判断 . 号
					++points;
					if (points <= 1)
						continue;
				}
				return false;
			}
		}
		return true;
	}
	
	
    /**
     * TreeMa集合2String
     *
     * @param data TreeMa
     * @return String
     */	
    public static String coverMap2String(Map<String, String> data) {
        StringBuilder sf = new StringBuilder();
        for (String key : data.keySet()) {
            if (!isBlank(data.get(key))) {
                sf.append(key).append("=").append(data.get(key).trim()).append("&");
            }
        }
        return sf.substring(0, sf.length() - 1);
    }

    /**
     * 空值判断
     * @param cs
     * @return
     */
    public static boolean isBlank(final CharSequence cs) {
        int strLen;
        if (cs == null || (strLen = cs.length()) == 0) {
            return true;
        }
        for (int i = 0; i < strLen; i++) {
            if (Character.isWhitespace(cs.charAt(i)) == false) {
                return false;
            }
        }
        return true;
    }
    
    /**
     * 返回参数处理
     * @return
     * @throws Exception 
     */
    public static Map<String,String> getParm(String Rstr) throws Exception{
    	Map<String,String> DateArry = new TreeMap<String,String>();
    	String[] ListObj=Rstr.split("&");    	
    	for(String Temp:ListObj){    		
    		if(Temp.matches("(.+?)=(.+?)")){
    			String[] TempListObj=Temp.split("=");    			
    			DateArry.put(TempListObj[0], TempListObj[1]);   			
    		}else if(Temp.matches("(.+?)=")){
    			String[] TempListObj=Temp.split("=");
    			DateArry.put(TempListObj[0],"");
    		}else{
    			throw new Exception("参数无法分解！");
    		}
    	}    	
    	return DateArry;
    }
    
    /**
     * 获取密钥
     * @param KeyStr
     * @return
     * @throws Exception
     */
    public static String getAesKey(String KeyStr) throws Exception{
    	String[] ListKeyObj=KeyStr.split("\\|");
    	if(ListKeyObj.length == 2){
    		if(!ListKeyObj[1].trim().isEmpty()){
    			return ListKeyObj[1];
    		}else{
    			throw new Exception("Key is Null!");
    		}
    	}else{
    		throw new Exception("Data format is incorrect!");    		
    	}
    }
    
    /**
     * byte数组转换成十六进制字符串
     * @param bArray
     * @return
     */
    public static final String bytesToHexString(byte[] bArray) {
    	  StringBuffer sb = new StringBuffer(bArray.length);
    	  String sTemp;
    	  for (int i = 0; i < bArray.length; i++) {
    	   sTemp = Integer.toHexString(0xFF & bArray[i]);
    	   if (sTemp.length() < 2)
    	    sb.append(0);
    	   sb.append(sTemp.toUpperCase());
    	  }
    	  return sb.toString();
   }
    
    
    /**
     * 把16进制字符串转换成字节数组
     * @param hex
     * @return byte[]
     */
    public static byte[] hexString2Bytes(String hex) {
        
        if ((hex == null) || (hex.equals(""))){
            return null;
        }
        else if (hex.length()%2 != 0){
            return null;
        }
        else{                
            hex = hex.toUpperCase();
            int len = hex.length()/2;
            byte[] b = new byte[len];
            char[] hc = hex.toCharArray();
            for (int i=0; i<len; i++){
                int p=2*i;
                b[i] = (byte) (charToByte(hc[p]) << 4 | charToByte(hc[p+1]));
            }
          return b;
        }
    }
    
	/*
	 * 字符转换为字节
	 */
	private static byte charToByte(char c) {
            return (byte) "0123456789ABCDEF".indexOf(c);
         }

	/**
	 * 格式化签名串
	 * @param formatString
	 * @param DicObject
	 * @return
	 * @throws Exception
	 */
	public static String formatVerify(String formatString,Map<String, Object> DicObject) throws Exception{
		String[] keyList = formatString.split("\\|");
		for(String key : keyList){
			if(DicObject.containsKey(key)&&!isEmpty(DicObject.get(key))) {
				formatString = formatString.replace(key, DicObject.get(key).toString());
			}else{
				formatString = formatString.replace(key, "");// 当字段为空时不参与延签
			}
		}
		return formatString;
	}

	/**
	 * 判断参数是否存在
	 * @param KeyStr
	 * @param DicObject
	 * @throws Exception
	 */
	public static void ContainsKeyExists(String KeyStr,Map<String,String> DicObject) throws Exception{
		String[] KeyValueS = KeyStr.split("\\|");
		for(String TempValue:KeyValueS){
			if (!DicObject.containsKey(TempValue)) {
				throw new Exception(TempValue + " is not found");
			}
		}
	}
	/**
	 * 按格式输出验签串
	 * @param VString
	 * @param DicObject
	 * @return
	 * @throws Exception
	 */
	public static String VerifyString(String VString,Map<String, String> DicObject) throws Exception{
		ContainsKeyExists(VString,DicObject);
		String[] ParmList = VString.split("\\|");
		for(String TempValue:ParmList){
			if(StringUtils.isNotBlank(DicObject.get(TempValue))){
				VString = VString.replace(TempValue.trim(), DicObject.get(TempValue).toString());
			}else{
				VString = VString.replace(TempValue.trim()+"|", "");
			}
		}
		return VString;
	}

}