package com.foc.util;

import java.lang.reflect.Type;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TimeZone;
import java.util.UUID;
import java.util.Map.Entry;

import org.apache.commons.lang3.StringUtils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.foc.conf.GConstants;
import com.foc.fetcher.FetchEntity;
import com.foc.fetcher.HCFetcher;
import com.foc.fetcher.HttpClientUtil;
import com.foc.hrm.entity.User2RoleEntity;
import com.foc.phone.area.PhoneAreaEntity;
import com.foc.phone.area.PhoneAreaUtil;
import com.foc.sound.entity.CallPhoneInfoListEntity;
import com.foc.sound.entity.UserInfo;
import com.uc.entity.UserEntity;

public class Util {
    
    public static <T> List<T> arrayApi(String uri, Map<String, Object> contents, Class<T> clazz) {
        try {
            StringBuilder url = new StringBuilder(GConstants.getValue("foc.api.url", "http://127.0.0.1:8080/"))
                    .append(uri);
            
            JSONObject content = new JSONObject();
            content.put("platform", "PC");
            content.put("deviceToken", "");
            content.put("appCode", "10001");
            content.put("language", "zh_CN");
            content.put("versionName", "1.0");
            
            for(Entry<String, Object> param:contents.entrySet()){
                
                content.put(param.getKey(), param.getValue());
            }
            
            Map<String, Object> params = new HashMap<>();
            params.put("content", JSON.toJSONString(content));
            String sign = GlobalUtil.getParamsSignStr(GConstants.SIGN_PRIVATE_KEY, String.valueOf(params.get("content")));
            params.put("sign", sign);
            String res = HttpClientUtil.doPost(url.toString(), params, "UTF-8");
            if(res == null){
                res = HttpClientUtil.doPost(url.toString(), params, "UTF-8");
                if(res == null)
                    return null;
            }
            JSONObject result = JSON.parseObject(res);
            if("2000".equals(result.getString("status"))){
                
                return JSON.parseArray(result.getString("data"), clazz);
            }
        } catch (Exception e) {
            
            e.printStackTrace();
        }
        return null;
    }
    public static <T> T objectApi(String uri, Map<String, Object> contents, Class<T> clazz) {
        try {
            StringBuilder url = new StringBuilder(GConstants.getValue("foc.api.url", "http://127.0.0.1:8080/"))
                    .append(uri);
            
            JSONObject content = new JSONObject();
            content.put("platform", "PC");
            content.put("deviceToken", "");
            content.put("appCode", "10001");
            content.put("language", "zh_CN");
            content.put("versionName", "1.0");
            
            for(Entry<String, Object> param:contents.entrySet()){
                
                content.put(param.getKey(), param.getValue());
            }
            
            Map<String, Object> params = new HashMap<>();
            params.put("content", JSON.toJSONString(content));
            String sign = GlobalUtil.getParamsSignStr(GConstants.SIGN_PRIVATE_KEY, String.valueOf(params.get("content")));
            params.put("sign", sign);
            String res = HttpClientUtil.doPost(url.toString(), params, "UTF-8");
            if(res == null){
                res = HttpClientUtil.doPost(url.toString(), params, "UTF-8");
                if(res == null)
                    return null;
            }
            if("class com.alibaba.fastjson.JSONObject".equals(clazz.toString()))
                return JSON.parseObject(res, clazz);
            if("class java.lang.String".equals(clazz.toString()))
                return JSON.parseObject(res, clazz);
            JSONObject result = JSON.parseObject(res);
            if("2000".equals(result.getString("status"))){
                
                return JSON.parseObject(result.getString("data"), clazz);
            }
        } catch (Exception e) {
            
            e.printStackTrace();
        }
        return null;
    }
    public static String updateGroupAvatar(String groupId, String userCode) {
        try {
            if (StringUtils.isNotBlank(groupId)) {
                StringBuilder url = new StringBuilder(GConstants.getValue("foc.api.url", ""))
                        .append("/api/im/group/updateGroupAvatar");
                
                Map<String, Object> params = new HashMap<String, Object>();
                params.put("content", "{\"lang\":\"CN\",\"platform\":\"PC\",\"deviceToken\":\"deviceToken\","
                        + "\"appCode\":\"10001\",\"language\":\"zh_CN\",\"versionName\":\"1.0\",\"userCode\":\""
                        + (StringUtils.isBlank(userCode) ? "123" : userCode) + "\",\"groupId\":\"" + groupId + "\"}");
                
                String sign = GlobalUtil.getParamsSignStr(GConstants.SIGN_PRIVATE_KEY, String.valueOf(params.get("content")));
                params.put("sign", sign);
                String res = HttpClientUtil.doPost(url.toString(), params, "UTF-8");
//                System.out.println(res);
                JSONObject object = JSON.parseObject(res);
                if(object != null && object.containsKey("status")){
                    
                    return object.getString("status");
                }
            }
        } catch (Exception e) {
            // TODO: handle exception
        }
        return "4001";
    }
    /**
     * 设置图片全名称
     * 
     * @author renmb
     * @time  2016年12月11日
     * @param url
     * @param want
     * @return
     */
    public static String getAbsoluteUrl(String url, String want) {
        if(StringUtils.isBlank(url))
            return getAbsoluteUrl(want);
        if(url.startsWith("http://") || url.startsWith("https://"))// 绝对路径
            return url;
        if(GConstants.FILE_PREFIX_URL.endsWith("/") && url.startsWith("/"))// 相对路径
            return GConstants.FILE_PREFIX_URL+url.replaceAll("^/+", "");
        return GConstants.FILE_PREFIX_URL+url;
    }
    /**
     * 获取文件的绝对路径
     * 
     * @author renmb
     * @time  2016年9月1日
     * @param url
     * @return
     */
    public static String getAbsoluteUrl(String url) {
        if(StringUtils.isBlank(url))
            return "";
        if(url.startsWith("http://") || url.startsWith("https://"))// 绝对路径
            return url;
        if(GConstants.FILE_PREFIX_URL.endsWith("/") && url.startsWith("/"))// 相对路径
            return GConstants.FILE_PREFIX_URL+url.replaceAll("^/+", "");
        return GConstants.FILE_PREFIX_URL+url;
    }
    /**
     * 获取相对路径地址
     * 
     * @author renmb
     * @time  2017年1月13日
     * @param url
     * @return
     */
    public static String getRelativePath(String url) {
        if(StringUtils.isBlank(url))
            return "";
        return url.replaceAll(GConstants.FILE_PREFIX_URL, "");
//        return url;
    }
    public static Date utc2Local(String utcTime) {
        
        
        try {
            String pattern = null;
            if("yyyy-MM-dd HH:mm".length() == utcTime.length()){
                
                pattern = "yyyy-MM-dd HH:mm";
            } else if("yyyy-MM-dd HH:mm:ss".length() == utcTime.length()){
                
                pattern = "yyyy-MM-dd HH:mm:ss";
            } else if("yyyy-MM-dd".length() == utcTime.length()){
                
                pattern = "yyyy-MM-dd";
            }
            SimpleDateFormat utcFormater = new SimpleDateFormat(pattern);
            utcFormater.setTimeZone(TimeZone.getTimeZone("UTC"));
//            Date utcDate = null;
            Date utcDate = utcFormater.parse(utcTime);
            return utc2Local(utcDate);
//            SimpleDateFormat localFormater = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//            localFormater.setTimeZone(TimeZone.getTimeZone("GMT-8"));
//            String localTime = localFormater.format(gpsUTCDate.getTime());
//            return localTime;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    
    public static Date utc2Local(Date utcDate) {
        try {
    //        TimeZone bjtz = TimeZone.getTimeZone("Asia/Shanghai");
    //        TimeZone bjtz = TimeZone.getDefault();
            TimeZone oldZone = TimeZone.getTimeZone("UTC");
            TimeZone newZone = TimeZone.getTimeZone("GMT+08:00");
    //        int timeOffset = oldZone.getRawOffset() - newZone.getRawOffset();
            
            return changeTimeZone(utcDate, oldZone, newZone);
        } catch (Exception e) {
            // TODO: handle exception
        }
        return null;
    }
    /**
     * 
     * 
     * @author renmb
     * @time  2016年10月1日
     * @param date
     * @return
     */
    public static Date local2Utc(Date date) {
        try {
    //        TimeZone bjtz = TimeZone.getTimeZone("Asia/Shanghai");
    //        TimeZone bjtz = TimeZone.getDefault();
            TimeZone oldZone = TimeZone.getTimeZone("GMT+08:00");
            TimeZone newZone = TimeZone.getTimeZone("UTC");
    //        int timeOffset = oldZone.getRawOffset() - newZone.getRawOffset();
            
            return changeTimeZone(date, oldZone, newZone);
        } catch (Exception e) {
            // TODO: handle exception
        }
        return null;
    }
    /**
     * 时区转换
     * 
     * @author renmb
     * @time  2016年10月1日
     * @param date
     * @param oldZone
     * @param newZone
     * @return
     */
    public static Date changeTimeZone(Date date, TimeZone oldZone, TimeZone newZone) {
        try {
            
            GregorianCalendar localGregorianCalendar1 = new GregorianCalendar(oldZone);
            localGregorianCalendar1.setTime(date);
            
            GregorianCalendar localGregorianCalendar2 = new GregorianCalendar(newZone);
            localGregorianCalendar2.setTimeInMillis(localGregorianCalendar1.getTimeInMillis());
            
            return new Date(localGregorianCalendar2.getTimeInMillis());
        } catch (Exception e) {
            // TODO: handle exception
        }
        return null;
    }
    public static String getDurationTime(long time){
        
        String buffer = "";
        buffer = ":"+time%1000+"纳秒";
        time   = time/1000;//微秒
        buffer = ":"+time%1000+"微秒"+buffer;
        time   = time/1000;//毫秒
        buffer = ":"+time%1000+"毫秒"+buffer;
        time   = time/1000;//毫秒
        buffer = ":"+time%60+"秒"+buffer;
        time   = time/60;//秒
        buffer =time+"分钟"+buffer;
        return buffer;
    }
    /**
     * 格式化手机号
     * 
     * @author renmb
     * @time  2016年12月12日
     * @param mobile
     * @return
     */
    public static String formatedMobile(String mobile){
        if(mobile == null || mobile.length() == 0)
            return mobile;
        try {
            String[] species = mobile.split("\\s+");// 只使用第一个手机号
            if(species.length>1 && species[0].matches("1\\d+") && species[1].matches("1\\d+")){
                
                mobile = species[0];
            }
            mobile = mobile.replaceAll("＋", "+");// 处理错误字符
            mobile = mobile.replaceAll("[^0-9|+]+", "");// 将非电话号码替换为空
//            System.out.println("mobile:"+mobile);
            if(mobile.startsWith("+")){// 国外手机号，前面加拨3个0
                
                return "000"+mobile.replace("+", "");
            } else if(mobile.matches("\\d+")){
                PhoneAreaEntity area = PhoneAreaUtil.get360PhoneArea(mobile);
                if(area == null){// 二次请求
                    
                    area = PhoneAreaUtil.get360PhoneArea(mobile);
                }
                if(area != null && StringUtils.isNotBlank(area.getProvince())){// 能够查到省份信息
                    
                    if(area.getProvince().contains("北京")
                            || (StringUtils.isNotBlank(area.getCity()) 
                                    && area.getCity().contains("北京"))){// 北京前面加拨一个0
                        
                        return "0"+mobile;
                    } else {// 非北京号码加拨两个0
                        
                        return "00"+mobile;
                    }
                }
            }
        } catch (Exception e) {
            // TODO: handle exception
        }
        return mobile;
    }
    /**
     * 格式化座机号
     * 
     * @author renmb
     * @time  2016年12月12日
     * @param workPhone
     * @return
     */
    public static String formatedWorkPhone(String workPhone){
        if(workPhone == null || workPhone.length() == 0)
            return workPhone;
        try {
            workPhone = workPhone.replaceAll("[^\\d|+]+", "");
            if(workPhone.matches("0+")){ // 非座机号设置为空
                workPhone = "";
            } else if(workPhone.startsWith("0") == false){ // 非0开头的号码需要处理
                if(workPhone.startsWith("1") && workPhone.length() == 11){// 非座机号，是手机号，将号码处理为空
                    
                    workPhone = "";
                }
            }
            if(workPhone.startsWith("+") == false){// 去掉电话号码中间的加号
                
                workPhone = workPhone.replace("+", "");
            }
            if(workPhone.startsWith("0106961")){// 1、010 6961 xxxx    -> xxxx              内部号码，直接拨短号
                
                workPhone = workPhone.replace("0106961", "");
            } else if(workPhone.startsWith("06961")){// 2、06961 xxxx    -> xxxx              内部号码，直接拨短号
                
                workPhone = workPhone.replace("06961", "");
            } else if(workPhone.startsWith("6961")){// 2、6961 xxxx    -> xxxx              内部号码，直接拨短号
                
                workPhone = workPhone.replace("6961", "");
            } else if(workPhone.startsWith("010")){// 3、010 xxxx xxxx    -> 0 xxxx xxxx       北京号码，去掉区号，加拨0
                
                workPhone = workPhone.replace("010", "0");
            } else if(workPhone.startsWith("+")){// 4、+ xxxx xxxx    -> 000 xxxx xxxx       北京号码，去掉+号，加拨000
                
                workPhone = workPhone.replace("+", "000");
            } else {// 5、xxx xxxx xxxx    -> 0 xxx xxxx xxxx   国内非北京号码，加拨0
                
                workPhone = "0"+workPhone;
            }
            return workPhone;
        } catch (Exception e) {
            // TODO: handle exception
        }
        return workPhone;
    }
    /**
     * 获取堆栈信息
     * 
     * @author renmb
     * @time  2016年10月21日
     * @param e
     * @return
     */
    public static String getStackTrace(Throwable e) {
        
        String error = "";
        Writer errors = null;
        PrintWriter printWriter = null;
        try {
            
            errors = new StringWriter();
            printWriter = new PrintWriter(errors);
            
            e.printStackTrace(printWriter);
            error = errors.toString();
            printWriter.close();
            errors.close();
        } catch (Exception e1) {
            // TODO Auto-generated catch block
//            e1.printStackTrace();
        }
        return error;
    }
    /**
     * 获取文件的扩展名称
     * @param filename
     * @return
     */
    public static String getExtensionName(String filename) {
        if(filename == null || filename.length() == 0)
            return null;
        if(filename.contains(".")){
            String[] species = filename.split("\\.");
            return "."+species[species.length-1].toLowerCase();
        }
        return null;
    }
    
    /**
     * 新就版本进行比较，如果新版本比老版本高则返回true，否则返回false
     * 
     * @author renmb
     * @time  2016年8月3日
     * @param oldVersion
     * @param version
     * @return
     */
    public static boolean compareVersion(String oldVersion, String version) {
        
        if(version != null && oldVersion != null) {
            String checkVersion[] = version.split("\\.");
            String originalVersion[] = oldVersion.split("\\.");
            int maxlength = (originalVersion.length >= checkVersion.length)?originalVersion.length:checkVersion.length;
            // go through all Version-parts
            for(int i= 0; i < maxlength; i++) {
                // if the checked version is too short
                if ( checkVersion.length <= i 
                    && originalVersion[i].equals(0))
                    return true;
                else if (checkVersion.length <= i)
                    return false;
                // if the original version is long enough
                if(originalVersion.length > i) {
                    
                    // convert to integer
                    try {
                        int originalVersNumber = Integer.valueOf(originalVersion[i]).intValue();
                        int checkVersNumber = Integer.valueOf(checkVersion[i]).intValue();
                        
                        // check the numbers
                        if(checkVersNumber > originalVersNumber) {
                            return true;
                        } else if(checkVersNumber < originalVersNumber) {
                            return false;
                        }
                    } catch(Exception e) {
                        return false;
                    }
                }
                else {
                    return true;
                }
            }
            return true;
        }
        return false;
    }
    /**
     * 生成安全的密码，生成随机的16位salt并经过1024次 sha-1 hash
     */
    public static String entryptPassword(String plainPassword) {
        try {
            String plain = Encodes.unescapeHtml(plainPassword);
            byte[] salt = Digests.generateSalt(GConstants.SALT_SIZE);
            byte[] hashPassword = Digests.sha1(plain.getBytes(), salt, GConstants.HASH_INTERATIONS);
            return Encodes.encodeHex(salt)+Encodes.encodeHex(hashPassword);
        } catch (Exception e) {
            // TODO: handle exception
        }
        return null;
    }
    
    /**
     * 验证密码
     * @param plainPassword 明文密码
     * @param password 密文密码
     * @return 验证成功返回true
     */
    public static boolean validatePassword(String plainPassword, String password) {
        try {
            String plain = Encodes.unescapeHtml(plainPassword);
            byte[] salt = Encodes.decodeHex(password.substring(0,16));
            byte[] hashPassword = Digests.sha1(plain.getBytes(), salt, GConstants.HASH_INTERATIONS);
            return password.equals(Encodes.encodeHex(salt)+Encodes.encodeHex(hashPassword));
        } catch (Exception e) {
            // TODO: handle exception
        }
        return false;
    }

    public static String getGenericCode(){
        try {
            
            return UUID.randomUUID().toString().replaceAll("-", "").toLowerCase();
        } catch (Exception e) {
            // TODO: handle exception
        }
        return null;
    }
    
    public static boolean isrContainValues(JSONArray data, String... values) {
        if(data == null || values == null)
            return false;
        int count = 0;
        int len = data.size();
        for(String val:values){
            for(int j=0;j<len;j++){
                if(val !=null && val.equals(data.getString(j))){
                    count++;
                    if (count == values.length) {
                        return true;
                    }
                }
            }
        }
        return false;
    }
    
    public static boolean isPraramerValue(JSONObject data, String... colums) {
        if(data == null || colums == null)
            return false;
        for(String colum:colums){
            if(data.containsKey(colum) == false){
                return false;
            }
        }
        return true;
    }
    public static boolean isInValue(String val, String... vals) {
        if(val == null || vals == null)
            return false;
        for(String v:vals){
            if(val.equals(v)){
                return true;
            }
        }
        return false;
    }
    /**
     * 生成稳健的随机数
     * @param min
     * @param max
     * @return
     */
    public static int getRandom(int min, int max) {
        
        int randomNumber = (int)(Math.random()*(max-min+3)+min);
        while (randomNumber == min || randomNumber == max+2) {
            randomNumber = (int)(Math.random()*(max-min+3)+min);
        }
        return randomNumber-1;
    }
    public static double getRandom(double max) {
        
        double randomNumber = Math.random()*(max+2);
        while (randomNumber >= max+1) {
            randomNumber = Math.random()*(max+2);
        }
        return randomNumber;
    }

    /**
     * 得到Uc账号,判断规则，如果同时满足前缀，后缀，直接返回该账号。否则按照前缀，后缀规则，添加后返回账号
     * @return
     */
    public static String getUcAccount(String str) {
        if (StringUtils.isBlank(str)) {
            throw new RuntimeException("非法的账号信息");
        }
        //账号前缀
        String prefix = GConstants.getValue("huawei.uc.account.prefix", "");
        //账号后缀
        String suffix = GConstants.getValue("huawei.uc.account.suffix", "");
        if (!str.startsWith(prefix)) {
            str = prefix + str;
        }
        if (!str.endsWith(suffix)) {
            str += suffix;
        }
        return str;
    }
//    public static void main(String[] args){
//        Map<String, Object> contents = new HashMap<String, Object>();
//        contents.put("phoneNumer", "5161");
//        
//        List<CallPhoneInfoListEntity> list = Util.arrayApi("/api/call/findPhoneInfo", contents, CallPhoneInfoListEntity.class);
//        CallPhoneInfoListEntity info = list.get(0);
//        if(info != null && StringUtils.isNotEmpty(info.getUserId())){
//            
//            UserInfo userInfo = new UserInfo();
//            userInfo.setId(info.getUserId());
//            userInfo.setName(info.getName());
//            System.out.println(info.getUserId()+"getName"+info.getName());
//        }
        
//        Map<String, Object> contents = new HashMap<String, Object>();
//        contents.put("phoneNumer", "5161");
//        JSONObject object = Util.objectApi("/api/call/findPhoneInfo", contents, JSONObject.class);
//        System.out.println(object);
        
//        List<CallPhoneInfoListEntity> list = Util.arrayApi("/api/call/findPhoneInfo", contents, CallPhoneInfoListEntity.class);
//        for(CallPhoneInfoListEntity l:list){
//            
//            System.out.println(l.getUserId());
//            System.out.println(l.getName());
//        }
//        System.out.println(Util.updateGroupAvatar("4433", "793289947956154368"));
//    }
}
