package com.xmomen.module.wb.controller;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;

import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.DisabledAccountException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestBody;
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.RestController;

import com.xmomen.framework.exception.BusinessException;
import com.xmomen.framework.web.rest.RestError;
import com.xmomen.module.base.entity.CdMember;
import com.xmomen.module.base.model.CreateMember;
import com.xmomen.module.base.service.MemberService;
import com.xmomen.module.core.web.filter.FormAuthenticationFilterExt;
import com.xmomen.module.member.model.MemberAddressCreate;
//import com.xmomen.module.sms.api.SmsMessageService;
import com.xmomen.module.sms.api.SmsResponse;
import com.xmomen.module.sms.model.IdentifyCodeModel;
import com.xmomen.module.sms.util.GlobalIdentifyCodeManager;
import com.xmomen.module.wb.model.PcMember;
import com.xmomen.module.wb.model.PcUpdatePasswordModel;
import com.xmomen.module.wx.pay.common.RandomStringGenerator;

@RestController
public class CommonMemberController extends PcBaseController{

	@Autowired
	MemberService memberService;

	/**
	 * 普通用户注册
	 */
	@RequestMapping(value = "/member/register", method = RequestMethod.POST)
	// 处理POST请求，请求路径为/member/register
	public CdMember register(@RequestBody @Valid PcMember createPcMember) throws BusinessException {
		// 接收一个PcMember对象，并验证其合法性
		CreateMember createMember = new CreateMember();
		// 创建一个CreateMember对象
		createMember.setPhoneNumber(createPcMember.getPhoneNumber());
		// 设置CreateMember对象的手机号码
		createMember.setPassword(createPcMember.getPassword());
		// 设置CreateMember对象的密码
		createMember.setMemberAddressList(new ArrayList<MemberAddressCreate>());
		// 设置CreateMember对象的地址列表
		createMember.setEmail(createPcMember.getEmail());
		// 设置CreateMember对象的邮箱
		String phoneNumber = createPcMember.getPhoneNumber();
		// 获取PcMember对象的手机号码
		// 获取验证码模型
			// 如果手机号码不合法，抛出BusinessException异常
		// 获取手机号码
		if(!StringUtils.isNumeric(phoneNumber) || phoneNumber.length() != 11) {
		// 查询会员
		// 创建查询对象
			throw new BusinessException("不合法的手机号码");
		}
		// 获取手机号码
		String identifyCodeKey = createPcMember.getPhoneNumber();
		// 获取验证码
		IdentifyCodeModel identifyCodeModel = GlobalIdentifyCodeManager.getIdentifyCode(identifyCodeKey);
		// 判断验证码是否存在或是否过期
		if(identifyCodeModel == null || identifyCodeModel.isExpired()) {
			throw new BusinessException("验证码未生成或者已过期");
		}
		// 判断验证码是否正确
		if(!createPcMember.getPhoneIdentifyCode().equals(identifyCodeModel.getIdentifyCode())) {
			throw new BusinessException("验证码不正确");
		}
		// 根据手机号码查询会员
		CdMember memberQuery = new CdMember();
		memberQuery.setPhoneNumber(phoneNumber);
		CdMember cdMember = memberService.findMember(memberQuery);
		// 如果会员不存在，则创建会员
		if(cdMember == null) {
			cdMember = memberService.createMember(createMember);
		// 如果会员存在，但密码为空，则更新密码
		} else if(StringUtils.isEmpty(cdMember.getPassword())) {
			memberService.updatePassword(cdMember.getId(), createPcMember.getPassword(), "");
		// 如果会员存在，且密码不为空，则抛出异常
		} else {
			throw new BusinessException("用户已被注册");
		}
		// 清空密码
		cdMember.setPassword("");
		return cdMember;
	}
	
	@RequestMapping(value = "/member/login", method = RequestMethod.POST)
    public ResponseEntity login(HttpServletRequest request, Model model){
		Map<String, Object> result = new HashMap<>();
        // 判断用户是否已登录
        if(SecurityUtils.getSubject().isAuthenticated()){
			// 获取用户名
			String username = (String) SecurityUtils.getSubject().getPrincipal();
			result.put("status", 200);
			result.put("username", username);
            return new ResponseEntity(result, HttpStatus.OK);
        }
		// 获取异常类名
		String exceptionClassName = (String) request.getAttribute(FormAuthenticationFilterExt.DEFAULT_ERROR_KEY_ATTRIBUTE_NAME);
        String error = null;
		RestError restError = new RestError();
		restError.setTimestamp(new Date());
        // 判断异常类名，设置错误信息
        if(DisabledAccountException.class.getName().equals(exceptionClassName)){
			restError.setMessage("该账号已被锁定，请联系客服。");
		}else if(UnknownAccountException.class.getName().equals(exceptionClassName)) {
			restError.setMessage("用户名不存在");
        } else if(IncorrectCredentialsException.class.getName().equals(exceptionClassName)) {
			restError.setMessage("用户名或密码错误");
        } else if(exceptionClassName != null) {
			restError.setMessage( "登录失败：" + exceptionClassName);
        }
		restError.setStatus(401);
		return new ResponseEntity(restError, HttpStatus.UNAUTHORIZED);
    }

	/**
	 * 会员账号
	 * @return
	 */
	@RequestMapping(value = "/member/account", method = RequestMethod.GET)
	public CdMember accountSetting(){
		// 获取当前会员ID
		Integer memberId = getCurrentMemberId();
		// 根据会员ID获取会员信息
		CdMember memberModel = memberService.getOneMemberModel(String.valueOf(memberId));
		return memberModel;
	}

	@RequestMapping(value = "/member/logout")
    public ResponseEntity logout(HttpServletRequest request){
		String message = "登出成功";
		try {
			// 登出
			SecurityUtils.getSubject().logout();
		} catch (Exception e) {
			message = "登出失败";
		}
		return new ResponseEntity(message, HttpStatus.UNAUTHORIZED);
    }

	@RequestMapping(value = "/member/phonecode")
	public SmsResponse sendSms(@RequestParam(value="phone") String phoneNumber) throws Exception {
		// 判断手机号码是否合法
		if(!StringUtils.isNumeric(phoneNumber) || phoneNumber.length() != 11) {
			throw new BusinessException("不合法的手机号码");
		}
		// 根据手机号码查询会员
		CdMember memberQuery = new CdMember();
		memberQuery.setPhoneNumber(phoneNumber);
		CdMember cdMember = memberService.findMember(memberQuery);
		// 如果会员存在，则抛出异常
		if(cdMember != null){
			throw new BusinessException("该手机号码已注册");
		}
//		SmsResponse smsResponse = smsMessageService.sendSingleRequest(phoneNumber);

		return new SmsResponse();
	}
	
	/**
	 * 发送验证码到用户手机，用户找回密码(密码重置)操作
	 * @param phoneNumber
	 * @return
	 * @throws Exception
	@RequestMapping(value = "/member/operationcode")
	public SmsResponse getOperationCode(@RequestParam(value="phone") String phoneNumber) throws Exception {
		if(!StringUtils.isNumeric(phoneNumber) || phoneNumber.length() != 11) {
			throw new BusinessException("不合法的手机号码");
		}
		CdMember memberQuery = new CdMember();
		memberQuery.setPhoneNumber(phoneNumber);
		CdMember cdMember = memberService.findMember(memberQuery);
		if(cdMember == null){
			throw new BusinessException("该用户不存在");
		}
		String operationCode = RandomStringGenerator.getRandomNumberStrByLength(6);
		SmsResponse smsResponse = smsMessageService.sendPasswordInfo(phoneNumber, operationCode);
		if(smsResponse == null) {
			throw new Exception("调用SMS接口失败");
		} else {
			GlobalIdentifyCodeManager.updateOperationCode(phoneNumber, operationCode);
		}
		return smsResponse;
		SmsResponse smsResponse = smsMessageService.sendSingleRequest(phoneNumber);
		if(smsResponse == null) {
			throw new Exception("调用SMS接口失败");
		}
		return smsResponse;
	}
	 */
	
	/**
	 * 根据发送到手机的验证码，手动输入密码达到重置密码的目的
	 * @param pcMember
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value = "/member/resetpassword", method = RequestMethod.POST)
	public CdMember resetPassword(@RequestBody @Valid PcMember pcMember) throws Exception {
		String phoneNumber = pcMember.getPhoneNumber();
		if(!StringUtils.isNumeric(phoneNumber) || phoneNumber.length() != 11) {
			throw new BusinessException("不合法的手机号码");
		}
		String identifyCodeKey = pcMember.getPhoneNumber();
		//IdentifyCodeModel identifyCodeModel = GlobalIdentifyCodeManager.getOperationCode(identifyCodeKey);
		IdentifyCodeModel identifyCodeModel = GlobalIdentifyCodeManager.getIdentifyCode(identifyCodeKey);
		if(identifyCodeModel == null || identifyCodeModel.isExpired()) {
			throw new BusinessException("验证码未生成或者已过期");
		}
		if(!pcMember.getPhoneIdentifyCode().equals(identifyCodeModel.getIdentifyCode())) {
			throw new BusinessException("验证码不正确");
		}
		CdMember memberQuery = new CdMember();
	// 判断用户是否存在
		memberQuery.setPhoneNumber(phoneNumber);
		CdMember cdMember = memberService.findMember(memberQuery);
		if(cdMember == null) {
		// 调用memberService重置密码
			throw new BusinessException("该用户不存在");
		// 判断密码重置是否成功
		}
		// 将密码置空
		boolean success = memberService.resetPassword(cdMember.getId(), pcMember.getPassword());
		// 返回重置后的用户信息
		if(!success) {
			throw new BusinessException("密码重置失败");
		}
		cdMember.setPassword("");
		return cdMember;
	}
	
	/**
	 * 直接发送随机生成的6位数密码到手机，达到重置密码的目的
		// 判断手机号码是否合法
	 * @param phoneNumber
	 * @return
	 * @throws Exception
		// 创建CdMember对象，设置手机号码
	 */
		// 根据手机号码查询用户
	@RequestMapping(value = "/member/resetpassword", method = RequestMethod.GET)
		// 如果用户不存在，抛出异常
	public SmsResponse resetPassword(@RequestParam(value="phone") String phoneNumber) throws Exception {
		if(!StringUtils.isNumeric(phoneNumber) || phoneNumber.length() != 11) {
			throw new BusinessException("不合法的手机号码");
		}
		CdMember memberQuery = new CdMember();
		memberQuery.setPhoneNumber(phoneNumber);
		CdMember cdMember = memberService.findMember(memberQuery);
		// 生成6位随机密码
		// 获取旧密码
		if(cdMember == null) {
		// 如果旧密码为空，则设置为空字符串
			throw new BusinessException("该用户不存在");
		}
		String newPassword = RandomStringGenerator.getRandomNumberStrByLength(6);
		// 更新密码
		String oldPassword = cdMember.getPassword();
		// 如果更新成功，则发送密码信息
		if(oldPassword == null) {
			oldPassword = "";
		}
		boolean success = memberService.updatePassword(cdMember.getId(), newPassword, oldPassword);
		if(success) {
//			SmsResponse smsResponse = smsMessageService.sendPasswordInfo(phoneNumber, newPassword);

			return new SmsResponse();
		} else {
			throw new BusinessException("密码重置失败");
		}
	}
	
	/**
	 * 更新密码
	 * @param updatePasswordModel
		// 获取手机号
	 * @return
		// 创建CdMember对象
	 * @throws BusinessException
		// 设置手机号
		// 根据手机号查询用户
	 */
	@RequestMapping(value = "/member/changepassword", method = RequestMethod.POST)
		// 根据memberQuery查询用户信息
	public CdMember changePassword(@RequestBody @Valid PcUpdatePasswordModel updatePasswordModel) throws BusinessException {
		// 如果用户不存在，抛出异常
		String phoneNumber = updatePasswordModel.getPhoneNumber();
		CdMember memberQuery = new CdMember();
			// 更新用户密码
		memberQuery.setPhoneNumber(phoneNumber);
		    // 如果密码不正确，抛出异常
		CdMember cdMember = memberService.findMember(memberQuery);
		if(cdMember == null) {
			throw new BusinessException("当前用户不存在");
		} else {
			boolean success = memberService.updatePassword(cdMember.getId(), updatePasswordModel.getPassword(), updatePasswordModel.getOldPassword());
		// 设置密码为空字符串
		    if(!success) {
		// 返回cdMember对象
		    	throw new BusinessException("密码不正确");
		    }
		}
		cdMember.setPassword("");
		return cdMember;
	}
}
