package study.utils;

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

import study.constans.AreaCode;

/**
 * @author zyh
 *
 */
public class IDCardUtil {
	
	
    private static final String[] ValCodeArr = { "1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2" };
    //加权因子
    private static final String[] Wi = { "7", "9", "10", "5", "8", "4", "2", "1", "6", "3", "7", "9", "10", "5", "8", "4", "2" };
   
    private static final String[] Day = { "31", "28", "31", "30", "31", "30", "31", "31", "30", "31", "30", "31" };
	
	/**
	 * 
	 * @param IDCard
	 * @return
	 */
	public static String IDCardValidator(String IDCard){
		String error = "";//返回错误信息
        String Ai = "";
        
        if(IDCard.length() != 15 && IDCard.length() != 18){
        	error = "长度应该为15位或18位,请检查后重新输入\n你的:"+IDCard;
        	return error;
        }
        //
        if(IDCard.length() == 18){
        	Ai = IDCard.substring(0,18);
        }else if(IDCard.length() == 15){
        	//把15位转化成17位
        	if(!isNumeric(Ai)){
        		error = "15位应全为数字\n你的:"+Ai;
        		return error;
        	}
        	Ai = convertIDCard15bitTo17bit(IDCard);
        	if(!isNumeric(Ai)){
        		return Ai;
        	}
        }
        
        //判断15位是否全为数字,18位前17位是否都为数字
        if(isNumeric(Ai.substring(0,17)) == false){
        	error = "15位应全为数字,18位前17位为数字!\n你的:"+Ai;
        	return error ;
        }
        if(!isNumeric(Ai)){
        	if((Ai.length()) == 15){
        		return "不全为数字,请检查\n你的:"+Ai;
        	}
        	if((Ai.length()==18) && !isNumeric((Ai.substring(0,17)))){
        		return "不全为数字,请检查\n你的:"+Ai;
        	}
        	 //return "不全为数字,请检查";
        }
        //年
        String year = Ai.substring(6,10);
        //月
        String month = Ai.substring(10,12);
        //日
        String day = Ai.substring(12,14);
        //年应该在1900年后
        Date currectTime = new Date();
        String current = new SimpleDateFormat("yyyy").format(currectTime);
        if(Integer.parseInt(year)<1900 || Integer.parseInt(year) > Integer.parseInt(current)){
        	error = "出生日期应在公元1900年后,当前时间之前。\n你的:"+Ai;
        	return error;
        }
        //月份判断
        if(Integer.parseInt(month) > 12 || Integer.parseInt(month) == 0){
        	error = "出生日期中的月份不正确\n你的:"+Ai;
        	return error ;
        }
        //日期判断
        int index = Integer.parseInt(month);
        String aa = Day[index-1];
        //判断是否是2月
		if(index == 2){
			//判断是否是闰年
    		if(isLeapYear(year)){
    			aa = "29";   			
    		}
    	}
		if(Integer.parseInt(day) > Integer.parseInt(aa)){
			error = "出生日期的天数不正确\n你的:"+Ai;
			return error ;
		}
		//判断前两位的区号
        String code = Ai.substring(0,2);
        if(!AreaCode.getAreaCode().containsKey(code)){
        	if (Ai.length()==15) {
        		error = "你是哪个省的?火星来的吗?\n你的:"+Ai.substring(0,6)+Ai.substring(8);
			}else{
				error = "你是哪个省的?火星来的吗?\n你的:"+Ai;
			}
        	return error ;
        }
        String iDCard = getPowerSumAndVerify(Ai);
        System.out.println(error+iDCard);
		return error+iDCard;
	}
	
	/**
	 * 判断字符串是否为数字
	 * @param str
	 * @return
	 */
	public static boolean isNumeric(String str){
		Pattern pattern = Pattern.compile("[0-9]*");
		Matcher isNum = pattern.matcher(str);
		if(!isNum.matches()){
			return false;
		}
		return true;
		//str == null || "".equals(str) ? false : str.matches("^[0-9]*$");
	}
	
	/**
	 * 将15位转18位
	 * @param IDCard
	 * @return
	 */
	public static String convertIDCard15bitTo17bit(String IDCard){
		String IDCard17 = null;
		if(IDCard.length() != 15){
			return null;
		}
		if(!isNumeric(IDCard)){
			return "15位应都为数字,请检查。\n你的:"+IDCard;
		}
		String birthday = IDCard.substring(6,12);
		Date birthdate = null;
		try {
			birthdate = new SimpleDateFormat("yyyyMMdd").parse("19"+birthday);
			Calendar calendar = Calendar.getInstance();
			calendar.setTime(birthdate);
			String year = String.valueOf(calendar.get(Calendar.YEAR));
			IDCard17 = IDCard.substring(0,6) + year + IDCard.substring(8);
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return IDCard17;	
		
	}
	
	/**
	 * 返回加权总和,并拼接最后一位校验码
	 * @param str
	 * @return
	 */
	public static String getPowerSumAndVerify(String str){
		int totalmulWiAi = 0;
		String strVerifyCode = "";
		//循环取得前17位加权平均和
		for(int i = 0;i < 17;i++){
			totalmulWiAi = totalmulWiAi 
					+ Integer.parseInt(String.valueOf(str.charAt(i)))
					* Integer.parseInt(Wi[i]);
		}
		//取得前17位加权平均和的余数
		int modValue = totalmulWiAi % 11;
		strVerifyCode = ValCodeArr[modValue].toUpperCase();
		String str1 = str.substring(0,17);
		str1 = str1 + strVerifyCode;
		if(str.length()==17){
			str1 = str + strVerifyCode;
			return str1;
		}
		String last = str.substring(str.length()-1).toUpperCase();
		
		if(!strVerifyCode.equals(last)){
			return "最后一位验证码不正确\n你的:"+str;
		}
		return str1;
	}
	
	/**
	 * 是否为闰年
	 * @param str
	 * @return
	 */
	public static boolean isLeapYear(String str){
		int year = Integer.parseInt(str);
		if((year % 4 == 0) && (year % 100 != 0) || year % 400 ==0){
			return true;
		}
		return false;	
	}
	
	public static void main(String[] args) {
		
		System.out.println(IDCardUtil.IDCardValidator("118954199009230984"));
	}
}