package com.base.utils.tools.android;

import android.text.TextUtils;
import android.widget.TextView;
import android.widget.Toast;

import com.base.utils.R;
import com.base.utils.base.BaseApp;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 验证工具
 */

public class VerifyUtil {

    public static boolean isIP(String addr) {
        if (addr == null) {
            return false;
        }
        if (addr.length() < 7 || addr.length() > 15 || "".equals(addr)) {
            return false;
        }
        /**
         * 判断IP格式和范围
         */
        String rexp = "([1-9]|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])(\\.(\\d|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])){3}";

        Pattern pat = Pattern.compile(rexp);

        Matcher mat = pat.matcher(addr);

        boolean ipAddress = mat.find();

        return ipAddress;

    }

    /**
     * 手机号正则表达式
     */
    private static final String REGEX_PHONE = "^1[3-9][0-9]\\d{8}$";

    /**
     * 验证手机号码
     *
     * @param mobile 手机号
     * @return true yes ,false no;
     */
    public static boolean isValidMobileNumber(final String mobile) {
        if (!TextUtils.isEmpty(mobile)) {
            final String inputStr = mobile.replace(" ", "").replace("-", "").replace("+", "").trim();
            Pattern pattern = Pattern.compile(REGEX_PHONE);
            Matcher matcher = pattern.matcher(inputStr);
            return matcher.matches();
        }
        return false;
    }

    /**
     * 判断是否是有效的邮箱地址
     */
    public static boolean isValidEmailAddress(String emailAddress) {

        if (!TextUtils.isEmpty(emailAddress)) {
            String regex = "\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*";
            return Pattern.matches(regex, emailAddress);
        }

        return false;
    }

    /**
     * 判断内容是否由字母，数字，下划线组成
     */
    public static boolean isValidContent(String content) {

        if (!TextUtils.isEmpty(content)) {
            String regex = "^[\\w\\u4e00-\\u9fa5]+$";
            return Pattern.matches(regex, content);
        }

        return false;
    }

    /**
     * 判断身份证号码是否有效
     */
    public static boolean isValidIdCard(String idCard) {
        return IdCardValidator.isValidateIdCard(idCard);
    }

    /**
     * 校验身份证的基本组成
     */
    public boolean isIdcard(String idCard) {
        if (!TextUtils.isEmpty(idCard)) {
            String regex = "(^\\d{15}$)|(\\d{17}(?:\\d|x|X)$)";
            return Pattern.matches(regex, idCard);
        }

        return false;
    }

    /**
     * 校验15身份证的基本组成
     */
    public boolean is15Idcard(String idCard) {
        if (!TextUtils.isEmpty(idCard)) {
            String regex = "^[1-9]\\d{7}((0\\d)|(1[0-2]))(([0|1|2]\\d)|3[0-1])\\d{3}$";
            return Pattern.matches(regex, idCard);
        }

        return false;
    }

    /**
     * 校验18身份证的基本组成
     */
    public boolean is18Idcard(String idCard) {
        if (!TextUtils.isEmpty(idCard)) {
            String regex = "^[1-9]\\d{5}[1-9]\\d{3}((0\\d)|(1[0-2]))(([0|1|2]\\d)|3[0-1])\\d{3}([\\d|x|X]{1})$";
            return Pattern.matches(regex, idCard);
        }

        return false;
    }


    /**
     * 根据〖中华人民共和国国家标准GB11643-1999〗中有关公民身份号码的规定，公民身份号码是特征组合码，由十七位数字本体码和一位数字校验码组成。
     * 排列顺序从左至右依次为：六位数字地址码，八位数字出生日期码，三位数字顺序码和一位数字校验码。
     * 顺序码: 表示在同一地址码所标识的区域范围内，对同年、同月、同 日出生的人编定的顺序号，顺序码的奇数分配给男性，偶数分配 给女性。
     * 第十八位数字(校验码)的计算方法为：
     * 1.将前面的身份证号码17位数分别乘以不同的系数。从第一位到第十七位的系数分别为：7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2
     * 2.将这17位数字和系数相乘的结果相加。
     * 3.用加出来和除以11，看余数是多少？
     * 4.余数只可能有0 1 2 3 4 5 6 7 8 9 10这11个数字。其分别对应的最后一位身份证的号码为: 1 0 X 9 8 7 6 5 4 3 2;
     * 5.通过上面得知如果余数是2，就会在身份证的第18位数字上出现罗马数字的Ⅹ。如果余数是10，身份证的最后一位号码就是2。
     */
    private static class IdCardValidator {

        // 省,直辖市代码表
        private static final String codeAndCity[][] = {{"11", "北京"}, {"12", "天津"},
                {"13", "河北"}, {"14", "山西"}, {"15", "内蒙古"}, {"21", "辽宁"},
                {"22", "吉林"}, {"23", "黑龙江"}, {"31", "上海"}, {"32", "江苏"},
                {"33", "浙江"}, {"34", "安徽"}, {"35", "福建"}, {"36", "江西"},
                {"37", "山东"}, {"41", "河南"}, {"42", "湖北"}, {"43", "湖南"},
                {"44", "广东"}, {"45", "广西"}, {"46", "海南"}, {"50", "重庆"},
                {"51", "四川"}, {"52", "贵州"}, {"53", "云南"}, {"54", "西藏"},
                {"61", "陕西"}, {"62", "甘肃"}, {"63", "青海"}, {"64", "宁夏"},
                {"65", "新疆"}, {"71", "台湾"}, {"81", "香港"}, {"82", "澳门"},
                {"91", "国外"}};

        // 每位加权因子
        private static final int power[] = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};

        // 判断18位身份证号码是否有效
        private static boolean isValidate18IdCard(String idCard) {
            if (idCard.length() != 18) {
                return false;
            }
            String idcard17 = idCard.substring(0, 17);
            String idcard18Code = idCard.substring(17, 18);
            char c[];
            String checkCode;
            if (isDigital(idcard17)) {
                c = idcard17.toCharArray();
            } else {
                return false;
            }

            if (null != c) {
                int bit[] = convertCharToInt(c);
                int sum17 = getPowerSum(bit);

                // 将和值与11取模得到余数进行校验码判断
                checkCode = getCheckCodeBySum(sum17);
                if (null == checkCode) {
                    return false;
                }
                // 将身份证的第18位与算出来的校码进行匹配，不相等就为假
                if (!idcard18Code.equalsIgnoreCase(checkCode)) {
                    return false;
                }
            }

            return true;
        }

        // 将15位的身份证转成18位身份证
        public static String convertIdcarBy15bit(String idcard) {
            String idcard18 = null;
            if (idcard.length() != 15) {
                return null;
            }

            if (isDigital(idcard)) {
                // 获取出生年月日
                String birthday = idcard.substring(6, 12);
                Date birthDate = null;
                try {
                    birthDate = new SimpleDateFormat("yyMMdd").parse(birthday);
                } catch (ParseException e) {
                    e.printStackTrace();
                }
                Calendar cDay = Calendar.getInstance();
                cDay.setTime(birthDate);
                String year = String.valueOf(cDay.get(Calendar.YEAR));

                idcard18 = idcard.substring(0, 6) + year + idcard.substring(8);

                char c[] = idcard18.toCharArray();
                String checkCode;

                if (null != c) {
                    int bit[] = convertCharToInt(c);
                    int sum17;
                    sum17 = getPowerSum(bit);
                    // 获取和值与11取模得到余数进行校验码
                    checkCode = getCheckCodeBySum(sum17);
                    // 获取不到校验位
                    if (null == checkCode) {
                        return null;
                    }

                    // 将前17位与第18位校验码拼接
                    idcard18 += checkCode;
                }
            } else {
                return null;
            }

            return idcard18;
        }

        // 是否全部由数字组成
        public static boolean isDigital(String str) {
            return !(str == null || "".equals(str)) && str.matches("^[0-9]*$");
        }

        // 将身份证的每位和对应位的加权因子相乘之后，再得到和值
        public static int getPowerSum(int[] bit) {
            int sum = 0;
            if (power.length != bit.length) {
                return sum;
            }

            for (int i = 0; i < bit.length; i++) {
                for (int j = 0; j < power.length; j++) {
                    if (i == j) {
                        sum = sum + bit[i] * power[j];
                    }
                }
            }

            return sum;
        }

        // 将和值与11取模得到余数进行校验码判断
        private static String getCheckCodeBySum(int sum17) {
            String checkCode = null;
            switch (sum17 % 11) {
                case 10:
                    checkCode = "2";
                    break;
                case 9:
                    checkCode = "3";
                    break;
                case 8:
                    checkCode = "4";
                    break;
                case 7:
                    checkCode = "5";
                    break;
                case 6:
                    checkCode = "6";
                    break;
                case 5:
                    checkCode = "7";
                    break;
                case 4:
                    checkCode = "8";
                    break;
                case 3:
                    checkCode = "9";
                    break;
                case 2:
                    checkCode = "x";
                    break;
                case 1:
                    checkCode = "0";
                    break;
                case 0:
                    checkCode = "1";
                    break;
            }

            return checkCode;
        }

        // 将字符数组转为整型数组
        private static int[] convertCharToInt(char[] c) throws NumberFormatException {
            int[] a = new int[c.length];
            int k = 0;
            for (char temp : c) {
                a[k++] = Integer.parseInt(String.valueOf(temp));
            }

            return a;
        }

        // 验证身份证号码是否有效
        public static boolean isValidateIdCard(String idCard) {
            if (!TextUtils.isEmpty(idCard)) {
                if (idCard.length() == 15) {
                    return isValidate18IdCard(convertIdcarBy15bit(idCard));
                } else if (idCard.length() == 18) {
                    return isValidate18IdCard(idCard);
                }
            }

            return false;
        }
    }

    public static int verifyCodeTime1 = 60;//剩下时间
    public static int verifyCodeTime2 = 60;//剩下时间
    private static TextView smsCodeTextView1 = null;
    private static TextView smsCodeTextView2 = null;

    public static void destroyVerify() {
        smsCodeTextView1 = null;
        smsCodeTextView2 = null;
    }

    public static void refreshVerifyCodeButton(final TextView textView) {
        smsCodeTextView1 = textView;
        if (verifyCodeTime1 > 0 && verifyCodeTime1 < 60) {
            //表示如果上次发送验证码的60秒还没有消失
            if (smsCodeTextView1 != null)
                Toast.makeText(textView.getContext(), textView.getContext().getString(R.string.prompt_verify_wait_for) + verifyCodeTime1 + textView.getContext().getString(R.string.prompt_verify_wait_for_unit), Toast.LENGTH_SHORT).show();
            return;
        }
        verifyCodeTime1 = 60;
        smsCodeTextView1.setEnabled(false);
        final Timer timer = new Timer();
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                BaseApp.getMainHandler().post(new Runnable() {
                    @Override
                    public void run() {
                        verifyCodeTime1 -= 1;
                        if (smsCodeTextView1 != null) {
                            smsCodeTextView1.setText(String.valueOf(verifyCodeTime1));
                        }
                        if (verifyCodeTime1 == 0) {
                            if (smsCodeTextView1 != null) {
                                smsCodeTextView1.setEnabled(true);
                                smsCodeTextView1.setText(smsCodeTextView1.getContext().getString(R.string.prompt_verify_default_text));
                            }
                            timer.cancel();
                        }
                    }
                });
            }
        }, 1000, 1000);

    }

    public static void refreshVerifyCodeButton2(final TextView textView) {
        smsCodeTextView2 = textView;
        if (verifyCodeTime2 > 0 && verifyCodeTime2 < 60) {
            //表示如果上次发送验证码的60秒还没有消失
            if (smsCodeTextView2 != null)
                Toast.makeText(textView.getContext(), textView.getContext().getString(R.string.prompt_verify_wait_for) + verifyCodeTime2 + textView.getContext().getString(R.string.prompt_verify_wait_for_unit), Toast.LENGTH_SHORT).show();
            return;
        }
        verifyCodeTime2 = 60;
        smsCodeTextView2.setEnabled(false);
        final Timer timer = new Timer();
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                BaseApp.getMainHandler().post(new Runnable() {
                    @Override
                    public void run() {
                        verifyCodeTime2 -= 1;
                        if (smsCodeTextView2 != null) {
                            smsCodeTextView2.setText(String.valueOf(verifyCodeTime2));
                        }
                        if (verifyCodeTime2 == 0) {
                            if (smsCodeTextView2 != null) {
                                smsCodeTextView2.setEnabled(true);
                                smsCodeTextView2.setText(smsCodeTextView2.getContext().getString(R.string.prompt_verify_default_text));
                            }
                            timer.cancel();
                        }
                    }
                });
            }
        }, 1000, 1000);

    }
}
