package com.cab.service;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
import java.util.Date;
import java.util.List;
import java.util.UUID;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.cab.dao.CabThirdPartyMapper;
import com.cab.dao.UserMapper;
import com.cab.model.CabThirdParty;
import com.cab.model.User;
import com.cku.core.BaseDAOMapper;
import com.cku.core.BaseService;
import com.cku.core.ZAErrorCode;
import com.cku.core.ZAException;
import com.cku.dao.CkuDvUserMapper;
import com.cku.dao.CkuUserMapper;
import com.cku.model.CkuDvUserModel;
import com.cku.model.CkuUser;
import com.cku.upyun.ImageFtp;
import com.cku.util.AESUtils;
import com.cku.util.Debugger;
import com.cku.util.MD5Generator;
import com.sys.dao.AreaMapper;
import com.sys.dao.CityMapper;
import com.sys.dao.ProvinceMapper;
import com.sys.service.TokenService;

@Service("userService")
public class UserServiceImpl extends BaseService<User>{
	@Autowired
	public UserMapper userMapper;
	
	@Autowired
	public ValidationCodeServiceImpl validationCodeService;
	
	@Autowired
	public CabThirdPartyMapper cabThirdPartyMapper;
	
	@Autowired
	public CkuDvUserMapper ckuDvUserMapper;
	
	@Autowired
	public CkuUserMapper ckuUserMapper;
	
	@Autowired
	public ProvinceMapper provinceMapper;
	
	@Autowired
	public CityMapper cityMapper;
	
	@Autowired
	public AreaMapper areaMapper;
	
	@Override
	protected BaseDAOMapper<User> getDAO() {
		return this.userMapper;
	}
	
	public User login(String username, String passwordMD5, String dynamic) throws Exception
	{		
		User user = userMapper.selectByUsername(username);
		
		Debugger.doAssert(user != null, ZAErrorCode.ZA_ERC_KEY_NOT_FOUND, "账户名或密码错误");
		
		String cryptedPassword = user.getPassword();
		byte[] content = Base64.getDecoder().decode(cryptedPassword);
		String realPassword = new String(AESUtils.decrypt(content));
		String md5 = MD5Generator.generate(realPassword + dynamic);

		Debugger.doAssert(passwordMD5.equalsIgnoreCase(md5), ZAErrorCode.ZA_ERC_INVALID_PASSWORD, 
				"账户名或密码错误");

		String token = TokenService.instance().registerToken(user.getId());
		String provinceName = "";
		if(user.getProvinceId()!=null){
			provinceName = provinceMapper.getProvince(user.getProvinceId().toString());
		}
		String cityName = "";
		if(user.getCityId()!=null){
			cityName = cityMapper.getCity(user.getCityId().toString());
		}
		String areaName = "";
		if(user.getAreaId()!=null){
			areaName = areaMapper.getArea(user.getAreaId().toString());
		}
		//控制省市区展示
		if(provinceName==null){
			user.setAddAess("");
		}else if(cityName==null){
			user.setAddAess(provinceName);
		}else if(areaName==null){
			user.setAddAess(provinceName+" "+cityName);
		}else {
			user.setAddAess(provinceName+" "+cityName+" "+areaName);
		}
		if(user.getPayPassWord()!=null &&"".equals(user.getPayPassWord())){
			user.setHasPpsw(true);
		}
		
		/*----------登录成功后查询是否存在cku会员信息---------------*/
		String dvUserId = "-1";
		String ckuUserId ="";
		//根据cab用户id查询出第三方表中对应的CKU账号id
		CabThirdParty cabThirdParty = cabThirdPartyMapper.selectByUserId(user.getId().intValue());
		if(cabThirdParty != null){
			dvUserId = cabThirdParty.getCkuUserId();
		}
		//根据CKU账号id查询出CKU账号信息
		CkuDvUserModel ckuDvUserModel = ckuDvUserMapper.getckuMemberByUserId(dvUserId);
		if(ckuDvUserModel != null){
			ckuUserId = ckuDvUserModel.getCkuId();
		}
		user.setVipNum(ckuUserId);
		//返回是否存在CKU会员的身份
		/*------------------------------------------------*/
		user.setToken(token);
		user.setPassword(null);
		user.setRegistIp(null);
		user.setUsername(null);
		user.setProvinceId(null);
		user.setCityId(null);
		user.setAreaId(null);
		user.setProvinceId(null);
		user.setPayPassWord(null);
		user.setCodeTime(null);
		user.setRandomCode(null);
		user.setCardId(null);
		if(user.getAvatar()==null){
			user.setAvatar("");
		}
		
		return user;
	}

	public void logout(String token) throws Exception
	{
		TokenService.instance().invalidToken(token);
	}

	public User register(String username, String password, String phone, String code, String remoteAddr,String name,String realname) throws Exception
	{
		User u = userMapper.selectByUsername(username);
		Debugger.doAssert(u == null, ZAErrorCode.ZA_ERC_CAB_REPEAT, "用户已注册");
		byte[] bytes = AESUtils.encrypt(password.getBytes());
		String encryptPassword = Base64.getEncoder().encodeToString(bytes);
		//验证手机验证码
		validationCodeService.verifyCodeAndUse(phone, code);
		//验证密码规则
		Debugger.doAssert(org.apache.commons.lang.StringUtils.isAsciiPrintable(password) && password.length() >= 6 && password.length() <= 20, 
				ZAErrorCode.ZA_ERC_INVALID_PASSWORD, "Invalid password value");
		//验证用户名规则
		Debugger.doAssert(org.apache.commons.lang.StringUtils.isAsciiPrintable(username) && username.length() <= 50, 
				ZAErrorCode.ZA_ERC_KEY_NOT_FOUND, "Invalid username value");
		
		User user = new User();
		user.setUsername(username);
		user.setPassword(encryptPassword);
		user.setPhone(phone);
		user.setRegistIp(remoteAddr);
		user.setName(name);
		user.setRealName("");
		int affected = userMapper.insertSelective(user);
		Debugger.doAssert(affected > 0, ZAErrorCode.ZA_ERC_SQL, "Failed to insert user model");
		//******创建第三方登录对应数据 zhuoHeng
		CabThirdParty cabThirdParty = new CabThirdParty();
		cabThirdParty.setCabUserId(new Long(user.getId()).intValue());
		cabThirdPartyMapper.insertSelective(cabThirdParty);
		//******
		String token = TokenService.instance().registerToken(user.getId());
		user.setToken(token);
		user.setPassword(null);
		user.setRegistIp(null);
		user.setUsername(null);
		user.setAvatar("");
		user.setAge("0");
		user.setFullyRegistered(user.getFullyRegistered());
		user.setThreeLoginType(user.getThreeLoginType());
		user.setName(name);
		
		
		return user;
	}
	
	public void resetPassword(String username, String password, String phone, String code) throws Exception
	{
		User user = userMapper.selectByUsername(username);
		Debugger.doAssert(user != null, ZAErrorCode.ZA_ERC_KEY_NOT_FOUND, "找不到用户");
		
		validationCodeService.verifyCodeAndUse(phone, code);

		byte[] bytes = AESUtils.encrypt(password.getBytes());
		String encryptPassword = Base64.getEncoder().encodeToString(bytes);
		
		User model2 = new User();
		model2.setId(user.getId());
		model2.setPassword(encryptPassword);

		int affected = userMapper.updateByPrimaryKeySelective(model2);
		Debugger.doAssert(affected > 0, ZAErrorCode.ZA_ERC_SQL, "重置密码失败");		
	}

	public void modifyPassword(String username, String old_password, String new_password) throws Exception
	{
		User user = userMapper.selectByUsername(username);
		Debugger.doAssert(user != null, ZAErrorCode.ZA_ERC_KEY_NOT_FOUND, "找不到用户");
		
		String cryptedPassword = user.getPassword();
		byte[] content = Base64.getDecoder().decode(cryptedPassword);
		String realPassword = new String(AESUtils.decrypt(content));

		Debugger.doAssert(realPassword.equalsIgnoreCase(old_password), ZAErrorCode.ZA_ERC_INVALID_PASSWORD, 
				"原密码错误");

		byte[] bytes = AESUtils.encrypt(new_password.getBytes());
		String encryptPassword = Base64.getEncoder().encodeToString(bytes);
		
		User model2 = new User();
		model2.setId(user.getId());
		model2.setPassword(encryptPassword);

		int affected = userMapper.updateByPrimaryKeySelective(model2);
		Debugger.doAssert(affected > 0, ZAErrorCode.ZA_ERC_SQL, "修改密码失败");
	}
	
	public int updateInfo(Long id, String name, Integer isFemale, String age,Integer province_id,Integer city_id, Integer area_id, String realName) throws Exception
	{
		User user = new User();
		user.setId(id);
		user.setName(name);
		user.setIsFemale(isFemale);
		user.setAge(age);
		user.setRealName(realName);
		user.setAreaId(area_id);
		user.setProvinceId(province_id);
		user.setCityId(city_id);

		int affected = userMapper.updateByPrimaryKeySelective(user);
		return affected;
	}
	
	public static void main(String[] args) throws Exception {
		
		/*String cryptedPassword = "3s8QwKBQGpu94aMXOBh9Zg==";
		String dynamic = "abcd123";
		byte[] content = Base64.getDecoder().decode(cryptedPassword);
		String realPassword = new String(AESUtils.decrypt(content));
		String md5 = MD5Generator.generate(realPassword + dynamic);
		System.out.println("md5:"+md5);*/
		UUID uuid = UUID.randomUUID(); 
		System.out.println(uuid);
		byte[] bytes = AESUtils.encrypt("123456".getBytes());
		String encryptPassword = Base64.getEncoder().encodeToString(bytes);
		System.out.println(encryptPassword);
		
		byte[] content = Base64.getDecoder().decode(encryptPassword);
		String realPassword = new String(AESUtils.decrypt(content));
		
		System.out.println(realPassword);
		//9bb8b70a322ae4a3
		String md5 = MD5Generator.generate(realPassword + uuid);
		//String md5 = MD5Generator.generate("65539753");
		//String md5 = madeMD5forPW("xinhongwei123!@#");
		System.out.println(md5);

//		Debugger.doAssert(passwordMD5.equalsIgnoreCase(md5), ZAErrorCode.ZA_ERC_INVALID_PASSWORD, 
//				"账户名或密码错误");

	}
	private static String madeMD5forPW(String plainText) {
		String result = null;
		try {
			MessageDigest md = MessageDigest.getInstance("MD5");
			md.update(plainText.getBytes());
			byte b[] = md.digest();
			int i;
			StringBuffer buf = new StringBuffer("");
			for (int offset = 0; offset < b.length; offset++) {
				i = b[offset];
				if (i < 0)
					i += 256;
				if (i < 16)
					buf.append("0");
				buf.append(Integer.toHexString(i));
			}
			result = buf.toString().substring(8, 24);
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		}
		return result;
	}

	public int updateAvatar(Long userId, String resultOra) {
		User user = userMapper.selectByPrimaryId(new Long(userId).intValue());
		String oraAvatar = user.getAvatar();
		user.setAvatar(resultOra);
		int i = userMapper.updateByPrimaryKeySelective(user);
		if(i>0 && oraAvatar!=null && !"".equals(oraAvatar) && 
			oraAvatar.length()>ImageFtp.UPYUNWEBURL.length() && 
			oraAvatar.startsWith(ImageFtp.UPYUNWEBURL)){
			ImageFtp.deleteFile(oraAvatar.replace(ImageFtp.UPYUNWEBURL, ""));
		}
		return i;
	}
	
	/**
	 * 
	 * @Description：验证验证码并生成随机码（设置支付密码）
	 * @author: zhuoHeng
	 * @version: 2016年4月27日 上午9:39:59
	 * @throws ZAException 
	 */
	public String validateIdentities(Long userId,String code) throws ZAException{
		
		User user = userMapper.selectByPrimaryId(new Long(userId).intValue());
		validationCodeService.verifyCodeAndUse(user.getPhone(), code);
		UUID uuid = UUID.randomUUID();
		Date date = new Date();
		user.setRandomCode(uuid.toString());
		user.setCodeTime(date);
		userMapper.updateByPrimaryKeySelective(user);
		
		return uuid.toString();
	}
	
	/**
	 * 
	 * @Description：验证身份证号并设置支付密码（设置支付密码）
	 * @author: zhuoHeng
	 * @version: 2016年4月28日 上午11:54:06
	 * @throws Exception 
	 */
	public void setPayPassWord(Long userId,String cardId,String uuid,String payPsw) throws Exception{
		
		User user = userMapper.selectByPrimaryId(new Long(userId).intValue());
		Date now = new Date();
		Debugger.doAssert(now.getTime()-user.getCodeTime().getTime()<10 * 60 * 1000, ZAErrorCode.ZA_ERC_UUID, "验证超时");
		if(user.getRandomCode().equals(uuid)){
			CabThirdParty obj = cabThirdPartyMapper.selectByUserId(new Long(userId).intValue());
			if(obj!=null){
				CkuDvUserModel ckuDvUserModel = ckuDvUserMapper.getckuMemberByUserId(obj.getCkuUserId());
				List<CkuUser> list = ckuUserMapper.getUserMessage(ckuDvUserModel.getCkuId());
				Debugger.doAssert(cardId.equals(list.get(0).getIdNum()), ZAErrorCode.ZA_ERC_IDNUM, "身份证号不正确");
				byte[] bytes = AESUtils.encrypt(payPsw.getBytes());
				String encryptPassword = Base64.getEncoder().encodeToString(bytes);
				user.setPayPassWord(encryptPassword);
				user.setCardId(cardId);
				userMapper.updateByPrimaryKeySelective(user);
			}
		}
	}
	
	/**
	 * 
	 * @Description：修改支付密码
	 * @author: zhuoHeng
	 * @version: 2016年4月28日 下午3:00:29
	 * @throws Exception 
	 */
	public void updatePayPassWord(Long userId,String old_password,String new_password,String validation_code) throws Exception{
		
		User user = userMapper.selectByPrimaryId(new Long(userId).intValue());
		Date now = new Date();
		Debugger.doAssert(now.getTime()-user.getCodeTime().getTime()<10 * 60 * 1000, ZAErrorCode.ZA_ERC_UUID, "验证超时");
		byte[] content = Base64.getDecoder().decode(user.getPayPassWord());
		String realPassword = new String(AESUtils.decrypt(content));
		Debugger.doAssert(realPassword.equalsIgnoreCase(old_password), ZAErrorCode.ZA_ERC_INVALID_PASSWORD, "原密码错误");
		byte[] bytes = AESUtils.encrypt(new_password.getBytes());
		String encryptPassword = Base64.getEncoder().encodeToString(bytes);
		User newUser = new User();
		newUser.setId(userId);
		newUser.setPayPassWord(encryptPassword);
		userMapper.updateByPrimaryKeySelective(newUser);
		
	}
	
	/**
	 * 
	 * @Description：验证支付密码
	 * @author: zhuoHeng
	 * @version: 2016年4月28日 下午3:30:21
	 */
	public void validatePayPassWord(Long userId,String payPsw,String dynamic) throws Exception{
		
		User user = userMapper.selectByPrimaryId(new Long(userId).intValue());
		byte[] content = Base64.getDecoder().decode(user.getPayPassWord());
		String realPassword = new String(AESUtils.decrypt(content));
		String md5 = MD5Generator.generate(realPassword + dynamic);
		Debugger.doAssert(payPsw.equalsIgnoreCase(md5), ZAErrorCode.ZA_ERC_INVALID_PAYPASSWORD, "支付密码错误");
		
	}

}
