package com.cab.service;

import java.io.IOException;
import java.util.Date;
import java.util.Random;

import org.apache.commons.httpclient.HttpException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.cab.dao.UserMapper;
import com.cab.dao.ValidationCodeMapper;
import com.cab.model.User;
import com.cab.model.ValidationCode;
import com.cku.core.ZAErrorCode;
import com.cku.core.ZAException;
import com.cku.sms.SmsCode;
import com.cku.util.Debugger;
import com.cku.util.StringUtils;

@Service("validationCodeService")
public class ValidationCodeServiceImpl {
	@Autowired
	public ValidationCodeMapper validationCodeMapper;
	@Autowired
	public UserMapper userMapper;
	
	public static int CODE_ALIVE_TIME_MINUTE = 10; // 10 minutes actived for phone code.
	public static int CODE_APPLY_INTERVAL = 1 * 60 * 1000; // 1 minute for apply interval.
	
	public void verifyCodeAndUse(String phone, String code) throws ZAException
	{
		ValidationCode vc = validationCodeMapper.selectByPrimaryKey(phone);
		
		Debugger.doAssert(vc != null, ZAErrorCode.ZA_ERC_VALIDATION_CODE_FAILED, "Code not exists");

		Debugger.doAssert(vc.getValidationCode().equals(code), ZAErrorCode.ZA_ERC_VALIDATION_CODE_FAILED, 
				"Error code number");
		Date now = new Date(), codeTime = vc.getCodeTime();
		Debugger.doAssert(now.getTime() - codeTime.getTime() < CODE_ALIVE_TIME_MINUTE * 60 * 1000, 
				ZAErrorCode.ZA_ERC_VALIDATION_CODE_FAILED, "Code time is invalid");
		
		ValidationCode vc2 = new ValidationCode();
		vc2.setCodeTime(new Date(0));
		vc2.setPhone(phone);
		
		validationCodeMapper.updateByPrimaryKeySelective(vc2);
	}
	
	public String applyNewCode(String phone) throws ZAException, HttpException, IOException
	{
		Debugger.doAssert(StringUtils.isMobile(phone), ZAErrorCode.ZA_ERC_INVALID_PARAMETER, "非法手机号码");
		ValidationCode vc = validationCodeMapper.selectByPrimaryKey(phone);
		User user = userMapper.selectByUsername(phone);
		boolean insert = true;
		Date now = new Date();
		if (vc != null)
		{
			insert = false;
			Date lastApply = vc.getApplyTime();
			
			Debugger.doAssert(now.getTime() - lastApply.getTime() > CODE_APPLY_INTERVAL, ZAErrorCode.ZA_ERC_VALIDATION_CODE_FAILED, 
					"验证码每隔1分钟才能请求一次");
		}
		else
		{
			vc = new ValidationCode();
			vc.setPhone(phone);
		}
		
		String code = _createRandomString(4, s_codeCharList);
		
		String[] params = new String[] { code, String.valueOf(CODE_ALIVE_TIME_MINUTE) };
		
		SmsCode.publishToUCPASS(phone, params);

		vc.setApplyTime(now);
		vc.setCodeTime(now);
		vc.setValidationCode(code);
		//判断手机号是否被注册 001372 762
		boolean flag = false;
		if(user != null){
			flag = true;
		}
		if (insert)
		{
			validationCodeMapper.insert(vc);
			return "{\"yzm\":"+code+",\"flag\":"+flag+"}";
		}
		else
		{
			validationCodeMapper.updateByPrimaryKey(vc);
			return "{\"yzm\":"+code+",\"flag\":"+flag+"}";
		}
	}

	private static String _createRandomString(int number, char[] charList) {
		Random rand = new Random();
		char[] charArr = new char[number];
		for (int i = 0; i < number; ++i) {
			int x = rand.nextInt(charList.length);
			charArr[i] = charList[x];
		}

		return new String(charArr);
	}

	private static char[] s_codeCharList = new char[] { '0', '1', '2', '3',
			'4', '5', '6', '7', '8', '9' };
}
