package cn.ysk.cashier.utils;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map;

public class MD5Util {


    private static final Logger log = LoggerFactory.getLogger(MD5Util.class);

    private static final String hexDigIts[] = {"0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"};

    public static String encrypt(String plainText) {
        try {
            return encrypt(plainText,true);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            log.error("MD5加密异常:",e);
            return null;
        }
    }

    /**
     * @Title: encrypt
     * @Description: TODO(16位或32位密码)
     * @param @param
     *            plainText
     * @param @param
     *            flag true为32位,false为16位
     * @throws UnsupportedEncodingException
     */
    public static String encrypt(String plainText, boolean flag) throws UnsupportedEncodingException {
        try {
            if (ObjectUtil.isEmpty(plainText)) {
                return null;
            }
            MessageDigest md = MessageDigest.getInstance("MD5");
            String encrStr = byteArrayToHexString(md.digest(plainText.getBytes("UTF-8")));
            if (flag)
                return encrStr;
            else
                return encrStr.substring(8, 24);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
            return null;
        }

    }

    @SuppressWarnings("unchecked")
    public static String encrypt(Object obj,String privateKey){
        if(obj==null){
            return null;
        }
        Map<String, Object> map = new HashMap<String,Object>();
        if(obj instanceof Map){
            map=(Map<String, Object>) obj;
        }else{
            map = BeanUtil.transBean2Map(obj);
        }
        return encrypt(map,privateKey,true);
    }

    /**
     * @Title: encrypt
     * @Description: TODO(16位或32位密码)
     * @param @param
     *            plainText
     * @param @param
     *            flag true为32位,false为16位
     * @throws UnsupportedEncodingException
     */
    public static String encrypt(Map<String, Object> map, String privateKey,boolean flag) {
        String param = null;
        map.remove("sign");
        map.remove("encrypt");
        String result = BeanUtil.mapOrderStr(map);
        if (StringUtils.isEmpty(result)) {
            return null;
        }
        param = encrypt(encrypt(result)+privateKey);
        if (flag) {
            return param;
        } else {
            param = param.substring(8, 24);
        }
        return param;
    }

    public static Map<String, Object> resultMap = new HashMap<String, Object>();
    @SuppressWarnings("unchecked")
    public static Map<String, Object> mapFn(Map<String, Object> map) {
        for (String key : map.keySet()) {
            if (map.get(key) != null && map.get(key) != "" && (!key.equals("BTYPE") && !key.equals("SIGN"))) {
                if (key.equals("INPUT")) {
                    if (map.get(key) != null) {
                        mapFn((Map<String, Object>) map.get(key));
                    }
                } else {
                    resultMap.put(key, map.get(key));
                }
            }
        }
        return resultMap;
    }

    @SuppressWarnings("unchecked")
    public static boolean check(Object obj,String privateKey){
        Map<String,Object> map=new HashMap<String,Object>();
        if(obj==null){
            return false;
        }
        if(obj instanceof Map){
            map=(Map<String, Object>) obj;
        }else{
            map = BeanUtil.transBean2Map(obj);
        }
        System.out.println("check:"+ JSONUtil.toJsonStr(map));
        String sign=(String)map.get("sign");
        if(sign==null){
            return false;
        }
        String str=encrypt(obj,privateKey);
        System.out.println("check: "+str);

        return sign.equals(str)?true:false;
    }

    public static String byteArrayToHexString(byte b[]){
        StringBuffer resultSb = new StringBuffer();
        for(int i = 0; i < b.length; i++){
            resultSb.append(byteToHexString(b[i]));
        }
        return resultSb.toString();
    }

    public static String byteToHexString(byte b){
        int n = b;
        if(n < 0){
            n += 256;
        }
        int d1 = n / 16;
        int d2 = n % 16;
        return hexDigIts[d1] + hexDigIts[d2];
    }



}
