package com.iamberry.app.international.controller;

import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import sun.misc.BASE64Decoder;

import com.iamberry.app.config.Constants;
import com.iamberry.app.config.Response;
import com.iamberry.app.config.ResponseHeader;
import com.iamberry.app.core.dto.RemoteIpInfoDTO;
import com.iamberry.app.core.dto.UserDTO;
import com.iamberry.app.core.entity.User;
import com.iamberry.app.international.util.TokenUtil;
import com.iamberry.app.international.util.Utility;
import com.iamberry.app.tool.util.AES;
import com.iamberry.wechat.file.FileType;

/**
 * UserController
 *
 * @author Moon Cheng
 * @date 2016年1月18日 上午11:53:04
 */
@Controller
@RequestMapping("/secure/user")
public class UserController extends BaseController {

	@Autowired
	HttpServletResponse response;
	
	private Logger logger = LoggerFactory.getLogger(UserController.class);
	
	// 保存用户头像的路径
	private String saveRootPath = "/common/user_head/";
	private String domain = "http://hk.iamberry.com";

	@InitBinder("user")
	public void initBinderUser(WebDataBinder binder) {
		binder.setFieldDefaultPrefix("user.");
	}

	/**
	 * 用户手机注册，成功返回json格式的用户信息
	 * @author Moon Cheng
	 * @param phone 手机号码
	 * @param verificationCode 手机收到的短信验证码
	 * @param password 密码
	 * @param areacode  地区参数 +86 +866港澳台........
	 * @return 2101：验证码错误；2102：验证码超时；1000：请求成功；2000：注册失败；
	 */
	@RequestMapping(value = "/register", method = RequestMethod.POST)
	@ResponseBody
	private Response register(@RequestParam("phone") String phone,
			@RequestParam("verification_code") String verificationCode,
			@RequestParam("password") String password,
			@RequestParam("areacode") String areacode
			) {
		User user = new User();
		int status = checkVerifyCode(phone, verificationCode, 1); //验证手机验证码是否正确
		status = 1;
		if (status == -1) { //验证码错误
			return Response.ERROR_CODE;
		} else if (status == -2) { //验证码超时
			return Response.CODE_TIMEOUT;
		} else
			if (status == 1) { //验证成功
			User users = userService.selectUserByUsername(phone);
				if(users == null){
					String ip = Utility.getIp(request);
					user = userService.register(areacode+","+phone, password, ip); 
					if (user == null) {//注册失败
						return Response.FAILURE;
					}
				}else{
					return Response.ERROR_REGISTER;
				}
		}
		System.out.println(phone+"-注册成功！请求涂鸦");
		//注册成功，返回用户信息
		return Response.SUCCESS.setData(userService.tuyaConnect(user), 1);
	}

	/**
	 * 第三方【微信】用户手机绑定，
	 * @author Moon Cheng
	 * @param phone 手机号
	 * @param openId 微信的open——id
	 * @return 1000：请求成功；2000：注册失败；
	 */
	@RequestMapping(value = "/third_part_binding_phone", method = RequestMethod.POST)
	@ResponseBody
	private Response thirdPartBindingPhone(@RequestParam("phone") String phone,
			@RequestParam("open_id") String openId,@RequestParam("code") String code,
			@RequestParam("areacode") String areacode 
			) {
		User user = new User();
		int status = checkVerifyCode(phone, code, 1); //验证手机验证码是否正确
		if (status == -1) { //验证码错误
			return Response.ERROR_CODE;
		} else if (status == -2) { //验证码超时
			return Response.CODE_TIMEOUT;
		} 
		user = userService.thirdPartBindingPhone(areacode+","+phone, openId);
		if (user == null) {
			return Response.USER_NOT_EXIST;
		}
		
		logger.info(user.getId() + "," + (user.getId().intValue() == 2011));
		
		if (user.getPassword() != null && user.getPassword().equals("EXTIES")) {
			ResponseHeader header = new ResponseHeader(2011, "用户已经存在!", 1);
			UserDTO dto = userService.tuyaConnect(user);
			return new Response(header, dto);
		}
		return Response.SUCCESS.setData(userService.tuyaConnect(user), 1);
	}

	/**
	 * login
	 * 手机号登录，
	 * @param phone 手机号
	 * @param password 密码
	 * @return 2012：身份验证失败；2013：账户冻结；1000：请求成功；
	 */
	@RequestMapping(value = "/login", method = RequestMethod.POST)
	@ResponseBody
	private Response login(@RequestParam(value = "phone", required = true) String phone,
			@RequestParam(value = "password", required = true) String password) {
		Object user = userService.login(phone, password);
		int status = 0;
		if (user instanceof Integer) {
			status = (Integer) user;
			switch (status) { 
			case -1: //账号不存在
				return Response.USER_NOT_EXIST;
			case -2: //密码错误
				return Response.AUTHENTICATION_ERROR;
			case -3: //用户状态不正常
				return Response.USER_FROZEN_ERROR;
			}
		}
		return Response.SUCCESS.setData((UserDTO) user, 1);
	}

	/**
	 * thirdPartLogin
	 * 第三方登录
	 * @param openId 微信open_id 
	 * @param extType 来源 qq或者微信
	 * @param extName extname
	 * @param extPicture 图片
	 * @return 2012：身份验证失败；2013：账户冻结；1000：请求成功；
	 */
	@RequestMapping(value = "/third_part_login", method = RequestMethod.POST)
	@ResponseBody
	private Response thirdPartLogin(@RequestParam(value = "open_id") String openId,
			@RequestParam(value = "ext_type") String extType, @RequestParam(value = "ext_name") String extName,
			@RequestParam(value = "ext_picture") String extPicture
			) {
		String ip = Utility.getIp(request);
		User user1 = userService.thirdPartLogin(openId, extType, extName, extPicture, ip);

		if (Constants.USER_INACTIVE.equals(user1.getStatus_())) {
			return Response.USER_FROZEN_ERROR;
		}
 // 这里不注册涂鸦，给涂鸦账号，密码
		UserDTO userInfo = new UserDTO(user1.getId(), user1.getUsername(), user1.getPassword(), user1.getToken(), user1.getDisplay_name(),
				user1.getDisplay_picture(), user1.getCreated_on(), user1.getExt_open_id(), user1.getExt_name(), user1.getExt_type(),
				user1.getLocation(), user1.getBaby_nickname() == null? "寶寶" : user1.getBaby_nickname(), user1.getBaby_dob(), user1.getBaby_gender(), user1.getStatus_());
		userInfo.setPassword(null);
		userInfo.setCountry_code(user1.getCountry_code());
		userInfo.setEncryptUsername(AES.encrypt(user1.getUsername()));
		userInfo.setUserCode("iamberry123");
		userInfo.setIs_perfect_user(user1.getIs_perfect_user() == null? 1 : user1.getIs_perfect_user());
		
		return Response.SUCCESS.setData(userInfo);
	}

	/**
	 * getUserInfo
	 * 获取用户基本信息
	 * @param id 用户id
	 * @token  用户token 登录的时候设置的唯一的token
	 * @return Response 2100：无效token；2020：无效用户；1000：请求成功；
	 */
	@RequestMapping(value = "/get_user_info", method = RequestMethod.POST)
	@ResponseBody
	private Response getUserInfo(@RequestParam(value = "user_id", required = true) Long id,
			@RequestParam("token") String token) {
		User userInfo = userService.validateUserToken(token);
		if (userInfo == null) {//token不存在，表示登录的时候没有..
			return Response.INVALID_TOKEN;
		}
		User user = userService.findById(id);
		if (user == null) { //未找到
			return Response.INVALID_PARMS;
		}
		return Response.SUCCESS.setData(user, 1);
	}

	/**
	 * updateProfile
	 * 更新用户基本信息
	 * @param user 用户信息
	 * @param token token
	 * @return Response 2100：无效token；1000：请求成功；
	 */
	@RequestMapping(value = "/update_profile", method = RequestMethod.POST)
	@ResponseBody
	private Response updateProfile(User user, @RequestParam("token") String token) {
		User user1 = userService.updateUserInfo(user, token);
		if (user1 == null) {
			return Response.INVALID_TOKEN;
		}
//		userInfo.setEncryptUsername(AES.encrypt(user.getUsername()));
//		userInfo.setUserCode("iamberry123");
		
		UserDTO userInfo = new UserDTO(user1.getId(), user1.getUsername(), user1.getPassword(), user1.getToken(), user1.getDisplay_name(),
				user1.getDisplay_picture(), user1.getCreated_on(), user1.getExt_open_id(), user1.getExt_name(), user1.getExt_type(),
				user1.getLocation(), user1.getBaby_nickname(), user1.getBaby_dob(), user1.getBaby_gender(), user1.getStatus_());
		userInfo.setPassword(null);
		userInfo.setCountry_code(user1.getCountry_code());
		userInfo.setEncryptUsername(AES.encrypt(user1.getUsername()));
		userInfo.setUserCode("iamberry123");
		return Response.SUCCESS.setData(userInfo, 1);
	}

	private BASE64Decoder decoder = new BASE64Decoder();  
	
	/**
	 * updateDisplayPicture
	 * 更改用户头像
	 * @param user 用户信息
	 * @param token 唯一标识符
	 * @return Response
	 * @throws IOException 
	 */
	@RequestMapping(value = "/update_display_picture", method = RequestMethod.POST)
	@ResponseBody
	private Response updateDisplayPicture(@RequestParam("picture_base64") String pictureBase64,
			@RequestParam("token") String token, HttpServletRequest request) throws IOException {
		// 判断文件类型
		byte [] b = new byte[28];
		pictureBase64.getBytes(0, 27, b, 0);
		String temp = new String(b);
		try {
			b = decoder.decodeBuffer(temp);
		} catch (IOException e) {
			logger.error("updateDisplayPicture:" + e.getMessage());
			return Response.FAILURE;
		}
		String type = null;					// 文件类型
		String fileHead = byte2hex(b);		// 文件头
		fileHead = fileHead.toUpperCase();
		type = getType(fileHead);
		if (type == null) {
			return Response.FAILURE;
		}
		// 获取保存地址
		String savePath = request.getServletContext().getRealPath(saveRootPath);
		StringBuilder tempDir = new StringBuilder(savePath);
		Long ran = new Date().getTime();
		tempDir.append(File.separator);
		tempDir.append(ran);
		tempDir.append(File.separator);
		// 判断保存路径是否存在，如果不存在，那么创建
		File file=new File(savePath);
		if (!file.exists()) {
			logger.info("updateDisplayPicture-exists");
			file.mkdirs();
		}
		// 获取保存文件名称
		StringBuilder saveName = new StringBuilder(TokenUtil.getToken());
		saveName.append(".").append(type);
		tempDir.append(saveName);
		// 保存磁盘
		String userHeadURL = null;
		if (!generateImage(pictureBase64, tempDir.toString())) {
			logger.error("updateDisplayPicture-generateImage saveFile Error");
			return Response.FAILURE;
		} else {
			userHeadURL = domain + request.getContextPath() + saveRootPath + ran + "/" + saveName.toString();
		}
		// 保存
		String path = userService.updateDisplayPicture(userHeadURL, token);
		return Response.SUCCESS.setData(path, 1);
	}
	
	private String getType(String fileHead) {
		FileType [] fileTypes = FileType.values();
		for (FileType fileType : fileTypes) {
			if (fileHead.startsWith(fileType.getValue())) {
				return fileType.getSuffix();
			}
		}
		return null;
	}
	
	private boolean generateImage(String imgStr, String imgFilePath) throws IOException {  
		// Base64解码  
		byte[] bytes = decoder.decodeBuffer(imgStr);
		for (int i = 0; i < bytes.length; ++i) {  
			if (bytes[i] < 0) {
				// 调整异常数据  
				bytes[i] += 256;  
			}  
		}  
		// 生成图片 
		File file = new File(imgFilePath);
		FileUtils.writeByteArrayToFile(file, bytes);
		return true;  
	}

	private String byte2hex(byte[] b) {
       // 转成16进制字符串
       String hs = "";
       String tmp = "";
       for (int n = 0; n < b.length; n++) {
           //整数转成十六进制表示
           tmp = (java.lang.Integer.toHexString(b[n] & 0XFF));
           if (tmp.length() == 1) {
               hs = hs + "0" + tmp;
           } else {
               hs = hs + tmp;
           }
       }
       tmp = null;
       return hs;
   }

	/**
	 * 此方法可以不再使用
	 */
	@RequestMapping(value = "/avator/{id}/{rand}", method = RequestMethod.GET)
	@ResponseBody
	@Deprecated
	private void getDisplayPicture() {
		String url = request.getRequestURI();
		url = url.substring(0, url.lastIndexOf('/'));
		String userID = url.substring(url.lastIndexOf('/') + 1);
		String avator = userService.selectUserAvator(Long.valueOf(userID));
		response.setContentType("image/jpg");
		try {
			OutputStream os = response.getOutputStream();
			BASE64Decoder decoder = new BASE64Decoder();
			byte[] decoderBytes = decoder.decodeBuffer(avator);
			os.write(decoderBytes);
			os.flush();
			os.close();
		} catch (Exception e) {
			// TODO: handle exception
		}
	}

	/**
	 * changePassword
	 * 修改手机密码
	 * @param oldPassword 新密码
	 * @param newPassword 旧密码
	 * @param token token
	 * @return Response 2101：验证码错误；2102：验证码超时；2100：无效token；1000：请求成功；
	 */
	@RequestMapping(value = "/change_password", method = RequestMethod.POST)
	@ResponseBody
	private Response changePassword(@RequestParam("old_password") String oldPassword,
			@RequestParam("new_password") String newPassword, @RequestParam("token") String token) {
		int status = userService.changePassword(oldPassword, newPassword, token);
		if (status == -1) { //token错误
			return Response.INVALID_TOKEN;
		} else if (status == 0) { //密码错误
			return Response.ERROR_OLDPASSWORD;
		} else { 
			return Response.SUCCESS.setData(null);
		}
	}

	/**
	 * changePhone
	 * 修改手机号码
	 * @author Moon Cheng, Yin
	 * @param newPhone 新手机号
	 * @param token token
	 * @param verificationCode 手机验证码
	 * @return2101：验证码错误；2102：验证码超时；2100：无效token；1000：请求成功；
	 */
	@RequestMapping(value = "/change_phone", method = RequestMethod.POST)
	@ResponseBody
	private Response changePhone(@RequestParam("new_phone") String newPhone,
			@RequestParam("verification_code") String verificationCode, @RequestParam("token") String token) {
		int status = checkVerifyCode(newPhone, verificationCode, 2);
		User user = null;
		if (status == -1) { //验证码错误
			return Response.ERROR_CODE;
		} else if (status == -2) { //验证码超时
			return Response.CODE_TIMEOUT;
		} else if (status == 1) { 
			user = userService.changePhone(newPhone, token);
			if (user == null) {
				return Response.INVALID_TOKEN;
			}
		}
		return Response.SUCCESS.setData(userService.tuyaConnect(user), 1);
	}

	/**
	 * resetPassword
	 * 重置手机密码
	 * @param username 用户米
	 * @param newPassword 新密码
	 * @param verificationCode 验证码
	 * @return2101：验证码错误；2102：验证码超时；2001：无效用户；2000：重置密码失败； 1000：请求成功；
	 */
	@RequestMapping(value = "/reset_password", method = RequestMethod.POST)
	@ResponseBody
	private Response resetPassword(@RequestParam(value = "username") String username,
			@RequestParam("new_password") String newPassword,
			@RequestParam("verification_code") String verificationCode) {
		int status = checkVerifyCode(username, verificationCode, 3);
		if (status == -1) {//验证码错误
			return Response.ERROR_CODE;
		} else if (status == -2) { //验证码超时
			return Response.CODE_TIMEOUT;
		} else if (status == 1) { 
			status = userService.resetPassWord(username, newPassword);
			if (status == -3) {//账号不存在
				return Response.USER_NOT_EXIST; 
			} else if (status == 0) {
				return Response.FAILURE;
			}
		}

		return Response.SUCCESS.setData(null);
	}

	/**
	 * 发送手机验证码
	 * @param phone 手机号 
	 * @param statusCode  1代表注册，2代表更换手机号，3代表忘记密码
	 * @return
	 */
	@RequestMapping(value = "/send_code", method = RequestMethod.GET)
	@ResponseBody
	private Response sendCode(@RequestParam("phone") String phone, @RequestParam("status_code") int statusCode,@RequestParam("areacode") String areacode) {
		String code = null;
		Map<String, Integer> status = new HashMap<>();
		User user = new User();
		try {
			switch (statusCode) {
			case 1:// register
				user = userService.selectUserByUsername(phone);
				if (user != null) {
					return Response.ERROR_REGISTER;
				}
				
				break;
			case 2:// change phone
				user = userService.selectUserByUsername(phone);
				if (user != null) {
					return Response.ERROR_REGISTER;
				}

				break;
			case 3:// reset password
				user = userService.selectUserByUsername(phone);
				if (user == null) {
					return Response.USER_NOT_EXIST;
				}

				break;
			default:
				break;
			}
			codeService.sendCode(areacode+","+phone, statusCode);
			status.put("code", 0);
		} catch (Exception e) {
			System.out.println(e);
			return Response.SERVER_INTERNAL_ERROR;
		}
		if (0 == status.get(Constants.SMS_RETURNCODE)) {
			return Response.SUCCESS.setData(code, 0);
		} else {
			return Response.FAILURE.setHeader(new ResponseHeader(status.get(Constants.SMS_RETURNCODE), "", 0));
		}
	}

	/**
	 * 获取封面图片
	 * @return json
	 */
	@RequestMapping(value = "/start_page", method = RequestMethod.GET)
	@ResponseBody
	private Response getStartPage() {
		String pageUrl = userService.getStartPage();
		return Response.SUCCESS.setData(pageUrl, 1);
	}

	/**
	 * 获取地址url
	 * @return
	 */
	@RequestMapping(value = "/get_location", method = RequestMethod.GET)
	@ResponseBody
	private Response getLocation() {
		String IP = Utility.getIp(request);
		 //String IP = "183.14.17.153";
		RemoteIpInfoDTO remoteIpInfoDTO = userService.getLocation(IP);
		return Response.SUCCESS.setData(remoteIpInfoDTO, 1);
	}
	
	/**
	 * 获取app版本号
	 * @return
	 */
	@RequestMapping(value = "/get_version", method = RequestMethod.GET)
	@ResponseBody
	private Response getApkVersion() {
		return Response.SUCCESS.setData(userService.getApkVersion());
	}
}
