package com.zhaohaoting.framework.utils;

import android.app.Activity;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.res.AssetManager;
import android.graphics.Rect;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.provider.ContactsContract;
import android.provider.Settings;
import android.telephony.PhoneNumberUtils;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewTreeObserver;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.LinearLayout;

import com.zhaohaoting.framework.ZhtLibrary;

import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.ObjectOutputStream;
import java.math.BigDecimal;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.List;
import java.util.Locale;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * author：Created by ZHT on 2017/11/1 11:37
 * email：526309416@qq.com
 * desc：
 */
public class Utils {
    public static boolean isEmpty(Object value) {
        if (value == null) {
            return true;
        }
        if ("".equals(value.toString()) || "null".equals(value.toString())) {
            return true;
        }
        return false;
    }

    public static String getJson(Context context, String fileName) {

        StringBuilder stringBuilder = new StringBuilder();
        try {
            AssetManager assetManager = context.getAssets();
            BufferedReader bf = new BufferedReader(new InputStreamReader(
                    assetManager.open(fileName)));
            String line;
            while ((line = bf.readLine()) != null) {
                stringBuilder.append(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return stringBuilder.toString();
    }

    public static boolean listIsEmpty(List list) {
        if (list == null || list.size() == 0) return true;
        return false;
    }

    /**
     * 是否在wifi状态下
     *
     * @param mContext
     * @return
     */
    public static boolean isWifi(Context mContext) {
        ConnectivityManager connectivityManager = (ConnectivityManager) mContext
                .getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo activeNetInfo = connectivityManager.getActiveNetworkInfo();
        if (activeNetInfo != null
                && activeNetInfo.getType() == ConnectivityManager.TYPE_WIFI) {
            return true;
        }
        return false;
    }

    /**
     * 隐藏手机号展示
     *
     * @param phone 手机号
     * @return
     */
    public static String hidePhoneNumber(String phone) {
        if (TextUtils.isEmpty(phone)) {
            return phone;
        }
        if (phone.length() < 7) {
            return phone;
        }
        return phone.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2");
    }

    /**
     * 银行卡号尾号
     *
     * @param bankCard 银行卡号
     * @return
     */
    public static String hideBankcardNumber(String bankCard) {
        if (TextUtils.isEmpty(bankCard)) {
            return bankCard;
        }
        if (bankCard.length() < 15) {
            return bankCard;
        }
        return bankCard.substring(bankCard.length() - 4, bankCard.length());
    }

    /**
     * addLayoutListener方法如下
     *
     * @param main   根布局
     * @param scroll 需要显示的最下方View
     *               例子：处理全屏activity和弹出键盘的兼容
     */
    public static void addLayoutListener(final View main, final View scroll, final View view) {
        main.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                Rect rect = new Rect();
                //1、获取main在窗体的可视区域
                main.getWindowVisibleDisplayFrame(rect);
                //2、获取main在窗体的不可视区域高度，在键盘没有弹起时，main.getRootView().getHeight()调节度应该和rect.bottom高度一样
                int mainInvisibleHeight = main.getRootView().getHeight() - rect.bottom;
                int height = main.getHeight();
//                int screenHeight = main.getRootView().getHeight();//屏幕高度
                //3、不可见区域大于屏幕本身高度的1/4：说明键盘弹起了
                LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) view.getLayoutParams();
                layoutParams.height = height;
                if (mainInvisibleHeight > height / 4) {
                    int[] location = new int[2];
                    scroll.getLocationInWindow(location);
                    // 4､获取Scroll的窗体坐标，算出main需要滚动的高度
                    int srollHeight = (location[1] + scroll.getHeight()) - rect.bottom;
                    //5､让界面整体上移键盘的高度
                    scroll.layout(0, height - srollHeight - scroll.getHeight(), scroll.getWidth(), height - srollHeight);
//                    main.scrollTo(0, srollHeight);
                } else {
                    //3、不可见区域小于屏幕高度1/4时,说明键盘隐藏了，把界面下移，移回到原有高度
                    scroll.layout(0, height - scroll.getHeight(), scroll.getWidth(), height);
//                    main.scrollTo(0, 0);
                }
            }
        });
    }

    /**
     * 是否点击键盘以外的位置
     *
     * @param v
     * @param event
     * @return
     */
    public static boolean isShouldHideInput(View v, MotionEvent event) {
//        if (v != null && (v instanceof EditText)) {
        if (v == null) return false;
        int[] leftTop = {0, 0};
        v.getLocationInWindow(leftTop);
        int left = leftTop[0], top = leftTop[1], bottom = top + v.getHeight(), right = left
                + v.getWidth();
        if (event.getX() > left && event.getX() < right
                && event.getY() > top && event.getY() < bottom) {
            // 保留点击EditText的事件
            return false;
        } else {
            return true;
        }
//        }
//        return false;
    }

    /**
     * 隐藏软键盘
     *
     * @param activity
     */
    public static void hideInputMethod(Activity activity) {
        ((InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE))
                .hideSoftInputFromWindow(activity.getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
    }


    /**
     * 隐藏软键盘
     *
     * @param activity
     */
    public static void hideInputMethod2(Activity activity, View view) {
        InputMethodManager imm = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
    }

    /**
     * 显示软键盘
     *
     * @param context
     */
    public static void showSoftInput(Context context, View view) {
        InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
        if (imm != null) {
            view.requestFocus();
            imm.showSoftInput(view, 0);
        }
    }

    public static void toggleSoftInput(View view) {
        InputMethodManager imm = (InputMethodManager) view.getContext()
                .getSystemService(Context.INPUT_METHOD_SERVICE);
        if (imm != null) {
            imm.toggleSoftInput(0, 0);
        }
    }

    /**
     * 计算地球上任意两点(经纬度)距离
     *
     * @param long1 第一点经度
     * @param lat1  第一点纬度
     * @param long2 第二点经度
     * @param lat2  第二点纬度
     * @return 返回距离 单位：米
     */
    public static String Distance(double long1, double lat1, double long2, double lat2) {
        double a, b, R;
        R = 6378137; // 地球半径
        lat1 = lat1 * Math.PI / 180.0;
        lat2 = lat2 * Math.PI / 180.0;
        a = lat1 - lat2;
        b = (long1 - long2) * Math.PI / 180.0;
        double d;
        double sa2, sb2;
        sa2 = Math.sin(a / 2.0);
        sb2 = Math.sin(b / 2.0);
        d = 2 * R * Math.asin(Math.sqrt(sa2 * sa2 + Math.cos(lat1) * Math.cos(lat2) * sb2 * sb2));
        return d + "";
    }

    public static String getNumString(int num) {
        DecimalFormat df = new DecimalFormat("######0.0");
        String numText = String.valueOf(num);
        if (num > 10000) {
            numText = df.format(num / 10000.0f) + "W";
        } else if (num > 1000) {
            numText = df.format(num / 1000.0f) + "K";
        }
        return numText;
    }

    public static String getHourMin(long seconds) {
        //if(seconds>24*60*60) return null;
        long second = seconds % 60;
        long min = ((seconds - second) / 60) % 60;
        long hour = seconds / (60 * 60);
        String time = "";
        if (hour >= 24) {
            time = (hour / 24) + " 天前";
        } else if (hour >= 1 && hour < 24) {
            time = hour + " 小时前";
        } else if (min >= 1 && min < 60) {
            time = min + " 分钟前";
        } else {
            time = "刚刚";
        }
        return time;
    }

    public static String getExactHourMin(long seconds) {
        if (seconds == 0) return "刚刚";

        long second = seconds % 60;
        long min = ((seconds - second) / 60) % 60;
        long totalHour = seconds / (60 * 60);
        long day = totalHour / 24;
        long hour = totalHour % 24;

        StringBuilder builder = new StringBuilder();
        if (day >= 1) {
            builder.append(String.valueOf(day));
            builder.append("天");
        }
        if (hour >= 1) {
            builder.append(String.valueOf(hour));
            builder.append("小时");
        }
        if (min >= 1) {
            builder.append(String.valueOf(min));
            builder.append("分钟");
        }
        if (second >= 1) {
            builder.append(String.valueOf(second));
            builder.append("秒");
        }
        return builder.toString();
    }

    /**
     * 分钱转元
     *
     * @param money
     * @return
     */
    public static String getMoneyString(long money) {
        BigDecimal totalAmount = new BigDecimal(String.valueOf(money));//总金额
        String result = new DecimalFormat("########0.00").format(totalAmount.divide(new BigDecimal(100)));
        if (result.substring(result.indexOf("."), result.length()).equals(".00"))
            return result.substring(0, result.indexOf("."));
        else return result;
    }

    /**
     * 保留两位
     *
     * @param money
     * @return
     */
    public static String getMoneyStringM2(float money) {
        DecimalFormat df = new DecimalFormat("#0.00");
        return df.format(money);
    }

    /**
     * 保留两位
     *
     * @param money
     * @return
     */
    public static String getMoneyStringM2(String money) {
        if (TextUtils.isEmpty(money)) return "0.00";
        DecimalFormat df = new DecimalFormat("#0.00");
        return df.format(Float.parseFloat(money));
    }

    /**
     * 保留两位
     *
     * @param money
     * @return
     */
    public static String getMoneyStringM2(double money) {
        DecimalFormat df = new DecimalFormat("#0.00");
        return df.format(money);
    }


    /**
     * 分钱转元
     *
     * @param money
     * @return
     */
    public static String getMoneyString(float money) {
        BigDecimal totalAmount = new BigDecimal(String.valueOf(money));//总金额
        String result = new DecimalFormat("########0.00").format(totalAmount.divide(new BigDecimal(100)));
        if (result.substring(result.indexOf("."), result.length()).equals(".00"))
            return result.substring(0, result.indexOf("."));
        else return result;
    }

    /**
     * 是否是手机号码
     *
     * @param target 目标字符串
     */
    public static boolean isMobilePhone(String target) {
        return target.matches("1\\d{10}");
    }

    /**
     * 密码
     *
     * @param target 目标字符串
     */
    public static boolean isPasswrodError(String target) {
        return target.matches("\\d{6}");
    }

    /**
     * 密码
     *
     * @param target 目标字符串
     */
    public static boolean isPasswrod(String target) {
        return target.matches("(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{6,20}$");
    }

    /**
     * 密码
     *
     * @param target 目标字符串
     */
    public static boolean isSimplePasswrod(String target) {

        return !TextUtils.isEmpty(target) && target.length() >= 6 && target.length() <= 20;
    }

    public static boolean isEmail(String email) {
    /*String str="^([a-zA-Z0-9]*[-_]?[a-zA-Z0-9]+)*@([a-zA-Z0-9]*[-_]?[a-zA-Z0-9]+)+[\\.][A-Za-z]{2,3}([\\.][A-Za-z]{2})?$";
    Pattern p = Pattern.compile(str);
    Matcher m = p.matcher(email);
    return m.matches();*/
        String str = "([a-z0-9A-Z]+[-|_|\\.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\\.)+[a-zA-Z]{2,}$";
        Pattern regex = Pattern.compile(str);
        Matcher matcher = regex.matcher(email);
        return matcher.matches();
    }

    public static boolean validateIdCard(String idCard) {
        //15位和18位身份证号码的正则表达式
//    String regIdCard="/^(^[1-9]\\d{7}((0\\d)|(1[0-2]))(([0|1|2]\\d)|3[0-1])\\d{3}$)|(^[1-9]\\d{5}[1-9]\\d{3}((0\\d)|(1[0-2]))(([0|1|2]\\d)|3[0-1])((\\d{4})|\\d{3}[Xx])$)$/";
        String regIdCard = "(\\d{14}[0-9a-zA-Z])|(\\d{17}[0-9a-zA-Z])";
        //如果通过该验证，说明身份证格式正确，但准确性还需计算
        if (idCard.matches(regIdCard)) {
            if (idCard.length() == 18) {
                int[] idCardWi = new int[]{7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2}; //将前17位加权因子保存在数组里
                int[] idCardY = new int[]{1, 0, 10, 9, 8, 7, 6, 5, 4, 3, 2}; //这是除以11后，可能产生的11位余数、验证码，也保存成数组
                int idCardWiSum = 0; //用来保存前17位各自乖以加权因子后的总和
                for (int i = 0; i < 17; i++) {
                    idCardWiSum += Integer.valueOf(idCard.substring(i, i + 1)) * idCardWi[i];
                }

                int idCardMod = idCardWiSum % 11;//计算出校验码所在数组的位置
                String idCardLast = idCard.substring(17);//得到最后一位身份证号码

                //如果等于2，则说明校验码是10，身份证号码最后一位应该是X
                if (idCardMod == 2) {
                    if (idCardLast.equalsIgnoreCase("X")) {
//            alert("恭喜通过验证啦！");
                        return true;
                    } else {
//            alert("身份证号码错误！");
                        return false;
                    }
                } else {
                    //用计算出的验证码与最后一位身份证号码匹配，如果一致，说明通过，否则是无效的身份证号码
                    if (Integer.parseInt(idCardLast) == idCardY[idCardMod]) {
//            alert("恭喜通过验证啦！");
                        return true;
                    } else {
//            alert("身份证号码错误！");
                        return false;
                    }
                }
            }
        } else {
//      alert("身份证格式不正确!");
            return false;
        }
        return false;
    }

    // 获取设备唯一码
    public static String geUUID(Context context) {
        TelephonyManager tm = (TelephonyManager) ZhtLibrary.getContext().getSystemService(Context.TELEPHONY_SERVICE);
        String deviceId = tm.getDeviceId();
//        String simSerialNumber = tm.getSimSerialNumber();
        String androidId = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID);
//        UUID  uuid = new UUID((long) androidId.hashCode(), (long) deviceId.hashCode() << 32 | (long) simSerialNumber.hashCode());
        UUID uuid = new UUID((long) androidId.hashCode(), (long) deviceId.hashCode() << 32);
        return uuid.toString();
    }

    public static void callPhone(String phoneNumber, Context context) {
        String number = phoneNumber.replace('-', '\0');
        Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:" + number));
        context.startActivity(intent);
    }

    /**
     * 插入联系人
     *
     * @param phoneNumber
     * @param name
     */
    public static void insertContact(String phoneNumber, String name, Context context) {
        // 创建一个空的ContentValues
        ContentValues values = new ContentValues();

        // 向RawContacts.CONTENT_URI空值插入，
        // 先获取Android系统返回的rawContactId
        // 后面要基于此id插入值
        Uri rawContactUri = context.getContentResolver().insert(ContactsContract.RawContacts.CONTENT_URI, values);
        long rawContactId = ContentUris.parseId(rawContactUri);
        values.clear();

        values.put(ContactsContract.Data.RAW_CONTACT_ID, rawContactId);
        // 内容类型
        values.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE);
        // 联系人名字
        values.put(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME, name);
        // 向联系人URI添加联系人名字
        context.getContentResolver().insert(ContactsContract.Data.CONTENT_URI, values);
        values.clear();

        values.put(ContactsContract.Data.RAW_CONTACT_ID, rawContactId);
        values.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE);
        // 联系人的电话号码
        values.put(ContactsContract.CommonDataKinds.Phone.NUMBER, phoneNumber);
        // 电话类型
        values.put(ContactsContract.CommonDataKinds.Phone.TYPE, ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE);
        // 向联系人电话号码URI添加电话号码
        context.getContentResolver().insert(ContactsContract.Data.CONTENT_URI, values);
    }


    /**
     * 调起系统发短信功能
     *
     * @param phoneNumber
     * @param message
     */
    public static void doSendSMSTo(String phoneNumber, String message, Context context) {
        if (PhoneNumberUtils.isGlobalPhoneNumber(phoneNumber)) {
            Intent intent = new Intent(Intent.ACTION_SENDTO, Uri.parse("smsto:" + phoneNumber));
//            intent.putExtra("address", "哈哈"); //电话号码，这行去掉的话，默认就没有电话
            intent.putExtra("sms_body", message);
            context.startActivity(intent);
        }
    }

    /**
     * @param date1
     * @param date2
     * @return 两个时间之间相差的月份数
     */
    public static int subMonthLength(String date1, String date2) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd", Locale.CHINA);
        int monthLength = 0;//两个日期相差的月分数
        try {
            Calendar calendar1 = Calendar.getInstance();
            calendar1.setTime(format.parse(date1));
            Calendar calendar2 = Calendar.getInstance();
            calendar2.setTime(format.parse(date2));
            int year1 = calendar1.get(Calendar.YEAR);
            int year2 = calendar2.get(Calendar.YEAR);
            int month1 = calendar1.get(Calendar.MONTH);
            int month2 = calendar2.get(Calendar.MONTH);
            if (year1 > year2) {
                monthLength = (year1 - year2) * 12;
                monthLength = monthLength + month1 - month2;
            } else if (year1 == year2) {
                monthLength = Math.abs(month1 - month2);
            } else {
                monthLength = (year2 - year1) * 12;
                monthLength = monthLength + month2 - month1;
            }
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return monthLength;
    }

    /**
     * 是否是闰年
     */
    public static boolean isRunYear(int rp) {
        return rp % 4 == 0 && rp % 100 != 0 || rp % 400 == 0;
    }

    /**
     * md5加密
     */
    public static String md5(Object object) {
        byte[] hash;
        try {
            hash = MessageDigest.getInstance("MD5").digest(toByteArray(object));
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("Huh, MD5 should be supported?", e);
        }

        StringBuilder hex = new StringBuilder(hash.length * 2);
        for (byte b : hash) {
            if ((b & 0xFF) < 0x10) hex.append("0");
            hex.append(Integer.toHexString(b & 0xFF));
        }
        return hex.toString();
    }

    public static byte[] toByteArray(Object obj) {
        byte[] bytes = null;
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        try {
            ObjectOutputStream oos = new ObjectOutputStream(bos);
            oos.writeObject(obj);
            oos.flush();
            bytes = bos.toByteArray();
            oos.close();
            bos.close();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
        return bytes;
    }

    public static String getTwoSizeNum(int num) {
        return num > 9 ? num + "" : "0" + num;
    }

}