package com.bizzan.bitrade.controller;


import com.bizzan.bitrade.constant.*;
import com.bizzan.bitrade.entity.*;
import com.bizzan.bitrade.entity.transform.AuthMember;
import com.bizzan.bitrade.pagination.PageResult;
import com.bizzan.bitrade.service.*;
import com.bizzan.bitrade.util.*;
import com.querydsl.core.types.Predicate;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;

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

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import static com.bizzan.bitrade.constant.BooleanEnum.IS_FALSE;
import static com.bizzan.bitrade.constant.BooleanEnum.IS_TRUE;
import static com.bizzan.bitrade.constant.CertifiedBusinessStatus.*;
import static com.bizzan.bitrade.constant.SysConstant.SESSION_MEMBER;
import static org.springframework.util.Assert.*;


/**
 * 用户中心认证
 *
 * @author QQ 2232965526
 * @date 2020年01月09日
 */
@Api(value = "ApproveController" , tags = "用户中心认证接口")
@RestController
@RequestMapping("/approve")
@Slf4j
public class ApproveController {

    private static Logger logger = LoggerFactory.getLogger(ApproveController.class);

    @Autowired
    private MemberService memberService;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private LocaleMessageSourceService msService;
    @Autowired
    private MemberApplicationService memberApplicationService;
    @Autowired
    private BusinessAuthDepositService businessAuthDepositService;
    @Autowired
    private BusinessCancelApplyService businessCancelApplyService ;
    @Autowired
    private MemberWalletService memberWalletService;
    @Autowired
    private BusinessAuthApplyService businessAuthApplyService;
    @Autowired
    private DepositRecordService depositRecordService;
    @Autowired
    private CountryService countryService;
    @Resource
    private LocaleMessageSourceService localeMessageSourceService;
    @Autowired
    private InnerInvokeUtil invokeUtil;

    @Value("${dev.mode.vcode:}")
    private String devModeVcode;

    /**
     * 设置或更改用户头像
     *
     * @param user
     * @param url
     * @return
     */
    @ApiOperation(value="设置或更改用户头像", notes="设置或更改用户头像")
    @ApiImplicitParams(value = {
    		@ApiImplicitParam(name = "url",value = "图像链接",required = true,paramType = "form",dataType = "string")
    })
    @PostMapping("/change/avatar")
    @Transactional(rollbackFor = Exception.class)
    public MessageResult update(@SessionAttribute(SESSION_MEMBER) AuthMember user, String url) {
        Member member = memberService.findOne(user.getId());
        member.setAvatar(url);
        return MessageResult.success();
    }

    /**
     * 安全设置
     *
     * @param user
     * @return
     */
    @ApiOperation(value="安全设置", notes="安全设置")
    @PostMapping("/security/setting")
    public MessageResult securitySetting(@SessionAttribute(SESSION_MEMBER) AuthMember user) {
        Member member = memberService.findOne(user.getId());
        String idNumber = member.getIdNumber();
        //log.info("member={}", member);
        MemberSecurity memberSecurity = MemberSecurity.builder().username(member.getUsername())
                .createTime(member.getRegistrationTime())
                .id(member.getId())
                .emailVerified(StringUtils.isEmpty(member.getEmail()) ? IS_FALSE : IS_TRUE)
                .email(member.getEmail())
                .mobilePhone(member.getMobilePhone())
                .fundsVerified(StringUtils.isEmpty(member.getJyPassword()) ? IS_FALSE : IS_TRUE)
                .loginVerified(IS_TRUE)
                .phoneVerified(StringUtils.isEmpty(member.getMobilePhone()) ? IS_FALSE : IS_TRUE)
                .realName(member.getRealName())
                .idCard(StringUtils.isEmpty(idNumber) ? null : idNumber.substring(0, 2) + "**********" + idNumber.substring(idNumber.length() - 2))
                .realVerified(StringUtils.isEmpty(member.getName()) ? IS_FALSE : IS_TRUE)
                .realAuditing(member.getRealNameStatus().equals(RealNameStatus.AUDITING) ? IS_TRUE : IS_FALSE)
                .avatar(member.getAvatar())
                .accountVerified((member.getBankInfo() == null && member.getAlipay() == null && member.getWechatPay() == null) ? IS_FALSE : IS_TRUE)
                .googleStatus(member.getGoogleState())
                .build();
        //log.info("memberSecurity={}", memberSecurity);
        if (memberSecurity.getRealAuditing().equals(IS_FALSE) && memberSecurity.getRealVerified().equals(IS_FALSE)) {
            List<MemberApplication> memberApplication = memberApplicationService.findLatelyApplication(member);
            memberSecurity.setRealNameRejectReason(memberApplication == null||memberApplication.size()==0 ? null : memberApplication.get(0).getRejectReason());
        }
        MessageResult result = MessageResult.success("success");
        result.setData(memberSecurity);
        return result;
    }

    /**
     * 设置资金密码
     *
     * @param jyPassword
     * @param user
     * @return
     */
    @ApiOperation(value="设置资金密码", notes="设置资金密码")
    @ApiImplicitParams(value = {
    		@ApiImplicitParam(name = "jyPassword",value = "资金密码",required = true,dataType = "string")
    })
    @PostMapping("/transaction/password")
    @Transactional(rollbackFor = Exception.class)
    public MessageResult approveTransaction(String jyPassword, @SessionAttribute(SESSION_MEMBER) AuthMember user) throws Exception {
        hasText(jyPassword, msService.getMessage("MISSING_JY_PASSWORD"));
        isTrue(jyPassword.length() >= 6 && jyPassword.length() <= 20, msService.getMessage("JY_PASSWORD_LENGTH_ILLEGAL"));
        Member member = memberService.findOne(user.getId());
        Assert.isNull(member.getJyPassword(), msService.getMessage("REPEAT_SETTING"));
        //生成密码
        String jyPass = Md5.md5Digest(jyPassword + member.getSalt()).toLowerCase();
        member.setJyPassword(jyPass);
        return MessageResult.success(msService.getMessage("SETTING_JY_PASSWORD"));
    }

    /**
     * 修改资金密码
     *
     * @param oldPassword
     * @param newPassword
     * @param user
     * @return
     */
    @ApiOperation(value="修改资金密码", notes="修改资金密码")
    @ApiImplicitParams(value = {
    	@ApiImplicitParam(name = "oldPassword",value = "旧密码",required = true,dataType = "string"),
    	@ApiImplicitParam(name = "newPassword",value = "新密码",required = true,dataType = "string")
    })
    @PostMapping("/update/transaction/password")
    @Transactional(rollbackFor = Exception.class)
    public MessageResult updateTransaction(String oldPassword, String newPassword, @SessionAttribute(SESSION_MEMBER) AuthMember user, Integer vtype, String vcode) throws Exception {
        hasText(oldPassword, msService.getMessage("MISSING_OLD_JY_PASSWORD"));
        hasText(newPassword, msService.getMessage("MISSING_NEW_JY_PASSWORD"));
        isTrue(newPassword.length() >= 6 && newPassword.length() <= 20, msService.getMessage("JY_PASSWORD_LENGTH_ILLEGAL"));
        Member member = memberService.findOne(user.getId());
        if(vtype == 1) {
        	ValueOperations valueOperations = redisTemplate.opsForValue();
            Object cache = valueOperations.get(SysConstant.PHONE_RESET_TRANS_CODE_PREFIX + member.getMobilePhone());
            notNull(cache, msService.getMessage("NO_GET_VERIFICATION_CODE"));
            hasText(vcode, msService.getMessage("MISSING_VERIFICATION_CODE"));
            if (!vcode.equals(cache.toString())) {
            	return MessageResult.error(msService.getMessage("VERIFICATION_CODE_INCORRECT"));
            } else {
                valueOperations.getOperations().delete(SysConstant.PHONE_RESET_TRANS_CODE_PREFIX + member.getMobilePhone());
            }
        } else if (vtype == 2) {
        	ValueOperations valueOperations = redisTemplate.opsForValue();
            Object cache = valueOperations.get(SysConstant.EMAIL_RESET_MONEY_CODE_PREFIX + member.getEmail());
            notNull(cache, msService.getMessage("NO_GET_VERIFICATION_CODE"));
            isTrue(vcode.equals(cache.toString()), msService.getMessage("VERIFICATION_CODE_INCORRECT"));
        } else {
        	return MessageResult.error(msService.getMessage("VERIFICATION_CODE_INCORRECT"));
        }
        isTrue(Md5.md5Digest(oldPassword + member.getSalt()).toLowerCase().equals(member.getJyPassword()), msService.getMessage("ERROR_JYPASSWORD"));
        member.setJyPassword(Md5.md5Digest(newPassword + member.getSalt()).toLowerCase());
        return MessageResult.success(msService.getMessage("SETTING_JY_PASSWORD"));
    }

    /**
     * 重置资金密码
     *
     * @param newPassword
     * @param code
     * @param user
     * @return
     * @throws Exception
     */
    @ApiOperation(value="重置资金密码", notes="重置资金密码")
    @ApiImplicitParams(value = {
    	@ApiImplicitParam(name = "newPassword",value = "新密码",required = true,dataType = "string")
    })
    @PostMapping("/reset/transaction/password")
    @Transactional(rollbackFor = Exception.class)
    public MessageResult resetTransaction(String newPassword, Integer vtype, String vcode, @SessionAttribute(SESSION_MEMBER) AuthMember user) throws Exception {
        hasText(newPassword, msService.getMessage("MISSING_NEW_JY_PASSWORD"));
        isTrue(newPassword.length() >= 6 && newPassword.length() <= 20, msService.getMessage("JY_PASSWORD_LENGTH_ILLEGAL"));
        
        Member member = memberService.findOne(user.getId());
        if(vtype == 1) {
        	ValueOperations valueOperations = redisTemplate.opsForValue();
            Object cache = valueOperations.get(SysConstant.PHONE_RESET_TRANS_CODE_PREFIX + member.getMobilePhone());
            notNull(cache, msService.getMessage("NO_GET_VERIFICATION_CODE"));
            hasText(vcode, msService.getMessage("MISSING_VERIFICATION_CODE"));
            if (!vcode.equals(cache.toString())) {
            	return MessageResult.error(msService.getMessage("VERIFICATION_CODE_INCORRECT"));
            } else {
                valueOperations.getOperations().delete(SysConstant.PHONE_RESET_TRANS_CODE_PREFIX + member.getMobilePhone());
            }
        } else if (vtype == 2) {
        	ValueOperations valueOperations = redisTemplate.opsForValue();
            Object cache = valueOperations.get(SysConstant.EMAIL_RESET_MONEY_CODE_PREFIX + member.getEmail());
            notNull(cache, msService.getMessage("NO_GET_VERIFICATION_CODE"));
            isTrue(vcode.equals(cache.toString()), msService.getMessage("VERIFICATION_CODE_INCORRECT"));
        }
        
        member.setJyPassword(Md5.md5Digest(newPassword + member.getSalt()).toLowerCase());
        return MessageResult.success(msService.getMessage("SETTING_JY_PASSWORD"));
    }

    /**
     * 绑定手机号
     *
     * @param password
     * @param phone
     * @param code
     * @param user
     * @return
     */
    @ApiOperation(value="绑定手机号", notes="绑定手机号")
    @ApiImplicitParams(value = {
    	@ApiImplicitParam(name = "country",value = "国家",required = true,dataType = "string"),
    	@ApiImplicitParam(name = "phone",value = "手机号",required = true,dataType = "string"),
    	@ApiImplicitParam(name = "code",value = "验证码",required = true,dataType = "string")
    })
    @PostMapping("/bind/phone")
    @Transactional(rollbackFor = Exception.class)
    public MessageResult bindPhone(HttpServletRequest request, String country, String phone, String code, @SessionAttribute(SESSION_MEMBER) AuthMember user) throws Exception {
        //hasText(password, msService.getMessage("MISSING_LOGIN_PASSWORD"));
        hasText(phone, msService.getMessage("MISSING_PHONE"));
        hasText(code, msService.getMessage("MISSING_VERIFICATION_CODE"));
        Country country1 = countryService.findOne(country);
        if (null == country1) {
            return MessageResult.error(localeMessageSourceService.getMessage("REQUEST_ILLEGAL"));
        }
        if ("中国".equals(country)) {
            if (!ValidateUtil.isMobilePhone(phone.trim())) {
                return MessageResult.error(msService.getMessage("PHONE_FORMAT_ERROR"));
            }
        }
        Member member = memberService.findOne(user.getId());

        ValueOperations valueOperations = redisTemplate.opsForValue();
        Object cache = valueOperations.get(SysConstant.PHONE_BIND_CODE_PREFIX + phone);
        notNull(cache, msService.getMessage("NO_GET_VERIFICATION_CODE"));
        Member member1 = memberService.findByPhone(phone);
        isTrue(member1 == null, msService.getMessage("PHONE_ALREADY_BOUND"));
        if (!code.equals(cache.toString())) {
            return MessageResult.error(msService.getMessage("VERIFICATION_CODE_INCORRECT"));
        } else {
            valueOperations.getOperations().delete(SysConstant.PHONE_BIND_CODE_PREFIX + phone);
        }
        isTrue(member.getMobilePhone() == null, msService.getMessage("REPEAT_PHONE_REQUEST"));
        //if (member.getPassword().equals(Md5.md5Digest(password + member.getSalt()).toLowerCase())) {
            member.setMobilePhone(phone);
            return MessageResult.success(msService.getMessage("SETTING_SUCCESS"));
        //} else {
        //    request.removeAttribute(SysConstant.SESSION_MEMBER);
        //    return MessageResult.error(msService.getMessage("PASSWORD_ERROR"));
        //}
    }


    /**
     *
     * 更改登录密码
     *
     * @param request
     * @param oldPassword
     * @param newPassword
     * @param code
     * @param user
     * @return
     * @throws Exception
     */
    @ApiOperation(value="更改登录密码", notes="更改登录密码")
    @ApiImplicitParams(value = {
    	@ApiImplicitParam(name = "oldPassword",value = "旧密码",required = true,dataType = "string"),
    	@ApiImplicitParam(name = "newPassword",value = "新密码",required = true,dataType = "string")
    })
    @PostMapping("/update/password")
    @Transactional(rollbackFor = Exception.class)
    public MessageResult updateLoginPassword(HttpServletRequest request, String oldPassword, String newPassword, Integer vtype, String vcode, @SessionAttribute(SESSION_MEMBER) AuthMember user) throws Exception {
//        hasText(oldPassword, msService.getMessage("MISSING_OLD_PASSWORD"));
        if (!StringUtils.hasText(oldPassword)) {
            return MessageResult.error(msService.getMessage("MISSING_OLD_PASSWORD"));
        }
//        hasText(newPassword, msService.getMessage("MISSING_NEW_PASSWORD"));
        if (!StringUtils.hasText(newPassword)) {
            return MessageResult.error(msService.getMessage("MISSING_NEW_PASSWORD"));
        }
//        isTrue(newPassword.length() >= 6 && newPassword.length() <= 20, msService.getMessage("PASSWORD_LENGTH_ILLEGAL"));
        if(newPassword.length() < 6 || newPassword.length() > 20){
            return MessageResult.error(msService.getMessage("PASSWORD_LENGTH_ILLEGAL"));
        }
        Member member = memberService.findOne(user.getId());
        boolean isDevBypass = !devModeVcode.isEmpty() && devModeVcode.equals(vcode);
        if(vtype == 1) {
        	if (!isDevBypass) {
	        	ValueOperations valueOperations = redisTemplate.opsForValue();
		        Object cache = valueOperations.get(SysConstant.PHONE_UPDATE_PASSWORD_PREFIX + user.getMobilePhone());
//		        notNull(cache, msService.getMessage("NO_GET_VERIFICATION_CODE"));
                if(null == cache){
                    return MessageResult.error(msService.getMessage("NO_GET_VERIFICATION_CODE"));
                }
//		        hasText(vcode, msService.getMessage("MISSING_VERIFICATION_CODE"));
                if (!StringUtils.hasText(vcode)) {
                    return MessageResult.error(msService.getMessage("MISSING_VERIFICATION_CODE"));
                }
		        if (!vcode.equals(cache.toString())) {
		            return MessageResult.error(msService.getMessage("VERIFICATION_CODE_INCORRECT"));
		        } else {
		            valueOperations.getOperations().delete(SysConstant.PHONE_UPDATE_PASSWORD_PREFIX + user.getMobilePhone());
		        }
        	}
        } else if (vtype == 2) {
        	if (!isDevBypass) {
	        	ValueOperations valueOperations = redisTemplate.opsForValue();
	            Object cache = valueOperations.get(SysConstant.EMAIL_UPDATE_PASSWORD_PREFIX + member.getEmail());
//	            notNull(cache, msService.getMessage("NO_GET_VERIFICATION_CODE"));
                if(null == cache){
                    return MessageResult.error(msService.getMessage("NO_GET_VERIFICATION_CODE"));
                }
//	            isTrue(vcode.equals(cache.toString()), msService.getMessage("VERIFICATION_CODE_INCORRECT"));
                if (!vcode.equals(cache.toString())) {
                    return MessageResult.error(msService.getMessage("VERIFICATION_CODE_INCORRECT"));
                } else {
                    valueOperations.getOperations().delete(SysConstant.EMAIL_UPDATE_PASSWORD_PREFIX + member.getEmail());
                }
        	}
        } else {
            return MessageResult.error(msService.getMessage("VERIFICATION_CODE_INCORRECT"));
        }
        //if(!invokeUtil.modifyPassword(member.getUsername(), oldPassword, newPassword))
        //	return MessageResult.error(msService.getMessage("PASSWORD_ERROR"));
        request.removeAttribute(SysConstant.SESSION_MEMBER);
        //redismanager.removeTokenMember(member.getToken());
//        isTrue(Md5.md5Digest(oldPassword + member.getSalt()).toLowerCase().equals(member.getPassword()), msService.getMessage("PASSWORD_ERROR"));
        if(!Md5.md5Digest(oldPassword + member.getSalt()).toLowerCase().equals(member.getPassword())){
            return MessageResult.error(msService.getMessage("PASSWORD_ERROR"));
        }
        member.setPassword(Md5.md5Digest(newPassword + member.getSalt()).toLowerCase());
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DATE, 2);
        member.setMoneyLockTime(calendar.getTime());
        return MessageResult.success(msService.getMessage("SETTING_SUCCESS"));
    }

    /**
     * 绑定邮箱
     *
     * @param request
     * @param password
     * @param code
     * @param email
     * @param user
     * @return
     */
    @ApiOperation(value="绑定邮箱", notes="绑定邮箱")
    @ApiImplicitParams(value = {
    	@ApiImplicitParam(name = "code",value = "验证码",required = true,dataType = "string"),
    	@ApiImplicitParam(name = "email",value = "邮箱",required = true,dataType = "string")
    })
    @PostMapping("/bind/email")
    @Transactional(rollbackFor = Exception.class)
    public MessageResult bindEmail(HttpServletRequest request, String code, String email, @SessionAttribute(SESSION_MEMBER) AuthMember user) throws Exception {
        //hasText(password, msService.getMessage("MISSING_LOGIN_PASSWORD"));
        hasText(code, msService.getMessage("MISSING_VERIFICATION_CODE"));
        hasText(email, msService.getMessage("MISSING_EMAIL"));
        isTrue(ValidateUtil.isEmail(email), msService.getMessage("EMAIL_FORMAT_ERROR"));
        ValueOperations valueOperations = redisTemplate.opsForValue();
        Object cache = valueOperations.get(SysConstant.EMAIL_BIND_CODE_PREFIX + email);
        notNull(cache, msService.getMessage("NO_GET_VERIFICATION_CODE"));
        isTrue(code.equals(cache.toString()), msService.getMessage("VERIFICATION_CODE_INCORRECT"));
        Member member = memberService.findOne(user.getId());
        isTrue(member.getEmail() == null, msService.getMessage("REPEAT_EMAIL_REQUEST"));
        //if (!Md5.md5Digest(password + member.getSalt()).toLowerCase().equals(member.getPassword())) {
        //    request.removeAttribute(SysConstant.SESSION_MEMBER);
        //    return MessageResult.error(msService.getMessage("PASSWORD_ERROR"));
        //} else {
        member.setEmail(email);
        return MessageResult.success(msService.getMessage("SETTING_SUCCESS"));
        //}
    }
    
    @ApiOperation(value="变更邮箱", notes="变更邮箱")
    @ApiImplicitParams(value = {
    	@ApiImplicitParam(name = "code",value = "验证码",required = true,dataType = "string"),
    	@ApiImplicitParam(name = "email",value = "邮箱",required = true,dataType = "string")
    })
    @PostMapping("/change/email")
    @Transactional(rollbackFor = Exception.class)
    public MessageResult changeEmail(HttpServletRequest request, String code, String email, @SessionAttribute(SESSION_MEMBER) AuthMember user) throws Exception {
        //hasText(password, msService.getMessage("MISSING_LOGIN_PASSWORD"));
        hasText(code, msService.getMessage("MISSING_VERIFICATION_CODE"));
        hasText(email, msService.getMessage("MISSING_EMAIL"));
        isTrue(ValidateUtil.isEmail(email), msService.getMessage("EMAIL_FORMAT_ERROR"));
        Member member = memberService.findOne(user.getId());
        ValueOperations valueOperations = redisTemplate.opsForValue();
        Object cache = valueOperations.get(SysConstant.EMAIL_CHANGE_CODE_PREFIX + member.getEmail());
        notNull(cache, msService.getMessage("NO_GET_VERIFICATION_CODE"));
        isTrue(code.equals(cache.toString()), msService.getMessage("VERIFICATION_CODE_INCORRECT"));
        
        //isTrue(member.getEmail() == null, msService.getMessage("REPEAT_EMAIL_REQUEST"));
        //if (!Md5.md5Digest(password + member.getSalt()).toLowerCase().equals(member.getPassword())) {
        //    request.removeAttribute(SysConstant.SESSION_MEMBER);
        //    return MessageResult.error(msService.getMessage("PASSWORD_ERROR"));
        //} else {
        if(member.getEmail()!=null && member.getUsername().equals(member.getEmail()))
        	member.setUsername(email);
        member.setEmail(email);
        return MessageResult.success(msService.getMessage("SETTING_SUCCESS"));
        //}
    }

    /**
     * 实名认证
     *
     * @param realName
     * @param idCard
     * @param user
     * @return
     */
    @ApiOperation(value="实名认证", notes="实名认证")
    @ApiImplicitParams(value = {
    	@ApiImplicitParam(name = "familyName",value = "姓",required = true,dataType = "string"),
    	@ApiImplicitParam(name = "middleName",value = "中间名",required = true,dataType = "string"),
    	@ApiImplicitParam(name = "name",value = "名",required = true,dataType = "string"),
    	@ApiImplicitParam(name = "birthdate",value = "生日",required = true,dataType = "string"),
    	@ApiImplicitParam(name = "idType",value = "证件类型",required = true,dataType = "string"),
    	@ApiImplicitParam(name = "idCard",value = "证件号",required = true,dataType = "string"),
    	@ApiImplicitParam(name = "idCardFront",value = "证件正面照片",required = true,dataType = "string"),
    	@ApiImplicitParam(name = "idCardBack",value = "证件背面照片",required = true,dataType = "string"),
    	@ApiImplicitParam(name = "handHeldIdCard",value = "手持证件照片",required = true,dataType = "string"),
    	@ApiImplicitParam(name = "nationality",value = "国籍",required = true,dataType = "string")
    })
    @PostMapping("/real/name")
    @Transactional(rollbackFor = Exception.class)
    public MessageResult realApprove(String familyName, String middleName, String name, String birthdate, String idType, String idCard, String idCardFront,
                                     String idCardBack, String handHeldIdCard, String nationality,
                                     @SessionAttribute(SESSION_MEMBER) AuthMember user) {
        //hasText(realName, msService.getMessage("MISSING_REAL_NAME"));
        //hasText(idCard, msService.getMessage("MISSING_ID_CARD"));
        hasText(idCardFront, msService.getMessage("MISSING_ID_CARD_FRONT"));
        hasText(idCardBack, msService.getMessage("MISSING_ID_CARD_BACK"));
        hasText(handHeldIdCard, msService.getMessage("MISSING_ID_CARD_HAND"));
        Member member = memberService.findOne(user.getId());
      //  if ("China".equals(member.getCountry().getEnName())) {
     //       isTrue(ValidateUtil.isChineseName(realName), msService.getMessage("REAL_NAME_ILLEGAL"));
     //       isTrue(IdcardValidator.isValidate18Idcard(idCard), msService.getMessage("ID_CARD_ILLEGAL"));
    //    }
        isTrue(member.getRealNameStatus() == RealNameStatus.NOT_CERTIFIED, msService.getMessage("REPEAT_REAL_NAME_REQUEST"));
        int count = memberApplicationService.queryByIdCard(idCard);
        if(count>0){
            return MessageResult.error(msService.getMessage("ONLY_AUTHENTICATE_ONCE"));
        }
        MemberApplication memberApplication = new MemberApplication();
        memberApplication.setAuditStatus(AuditStatus.AUDIT_ING);
        //memberApplication.setRealName(realName);
        memberApplication.setName(name);
        memberApplication.setFamilyName(familyName);
        memberApplication.setMiddleName(middleName);
        memberApplication.setBirthdate(birthdate);
        memberApplication.setIdType(idType);
        memberApplication.setIdCard(idCard);
        memberApplication.setMember(member);
        memberApplication.setIdentityCardImgFront(idCardFront);
        memberApplication.setIdentityCardImgInHand(handHeldIdCard);
        memberApplication.setIdentityCardImgReverse(idCardBack);
        memberApplication.setNationality(nationality);
        memberApplication.setCreateTime(new Date());
        memberApplicationService.save(memberApplication);
        member.setRealNameStatus(RealNameStatus.AUDITING);
        return MessageResult.success(msService.getMessage("REAL_APPLY_SUCCESS"));
    }


    /**
     * 查询实名认证情况
     *
     * @param user
     * @return
     */
    @ApiOperation(value="查询实名认证信息", notes="查询实名认证信息")
    @PostMapping("/real/detail")
    @Transactional(rollbackFor = Exception.class)
    public MessageResult realNameApproveDetail(@SessionAttribute(SESSION_MEMBER) AuthMember user) {
        Member member = memberService.findOne(user.getId());
        List<Predicate> predicateList = new ArrayList<>();
        predicateList.add(QMemberApplication.memberApplication.member.eq(member));
        PageResult<MemberApplication> memberApplicationPageResult = memberApplicationService.query(predicateList, null, null);
        MemberApplication memberApplication = new MemberApplication();
        if (memberApplicationPageResult != null && memberApplicationPageResult.getContent() != null
                && memberApplicationPageResult.getContent().size() > 0) {
            memberApplication = memberApplicationPageResult.getContent().get(0);
        }
        MessageResult result = MessageResult.success();
        result.setData(memberApplication);
        return result;
    }

    /**
     * 账户设置
     *
     * @param user
     * @return
     */
    @ApiOperation(value="获取账户设置", notes="获取账户设置")
    @PostMapping("/account/setting")
    @Transactional(rollbackFor = Exception.class)
    public MessageResult accountSetting(@SessionAttribute(SESSION_MEMBER) AuthMember user) {
        Member member = memberService.findOne(user.getId());
        hasText(member.getIdNumber(), msService.getMessage("NO_REAL_NAME"));
        hasText(member.getJyPassword(), msService.getMessage("NO_JY_PASSWORD"));
        MemberAccount memberAccount = MemberAccount.builder().alipay(member.getAlipay())
                .aliVerified(member.getAlipay() == null ? IS_FALSE : IS_TRUE)
                .bankInfo(member.getBankInfo())
                .bankVerified(member.getBankInfo() == null ? IS_FALSE : IS_TRUE)
                .wechatPay(member.getWechatPay())
                .wechatVerified(member.getWechatPay() == null ? IS_FALSE : IS_TRUE)
                .realName(member.getRealName())
                .build();
        MessageResult result = MessageResult.success();
        result.setData(memberAccount);
        return result;
    }

    /**
     * 原来的手机还能用的情况下更换手机
     *
     * @param request
     * @param password
     * @param phone
     * @param code
     * @param user
     * @return
     * @throws Exception
     */
    @ApiOperation(value="更换手机号", notes="更换手机号")
    @ApiImplicitParams(value = {
        @ApiImplicitParam(name = "country",value = "国家",required = true,dataType = "string"),
        @ApiImplicitParam(name = "phone",value = "手机号",required = true,dataType = "string"),
    	@ApiImplicitParam(name = "code",value = "验证码",required = true,dataType = "string")
    })
    @PostMapping("/change/phone")
    @Transactional(rollbackFor = Exception.class)
    public MessageResult changePhone(HttpServletRequest request, String country, String phone, String code, @SessionAttribute(SESSION_MEMBER) AuthMember user) throws Exception {
        Member member = memberService.findOne(user.getId());
        //hasText(password, msService.getMessage("MISSING_LOGIN_PASSWORD"));
        hasText(phone, msService.getMessage("MISSING_PHONE"));
        hasText(code, msService.getMessage("MISSING_VERIFICATION_CODE"));
        Member member1 = memberService.findByPhone(phone);
        isTrue(member1 == null, msService.getMessage("PHONE_ALREADY_BOUND"));
        ValueOperations valueOperations = redisTemplate.opsForValue();
        Object cache = valueOperations.get(SysConstant.PHONE_CHANGE_CODE_PREFIX + member.getMobilePhone());
        notNull(cache, msService.getMessage("NO_GET_VERIFICATION_CODE"));
        
        Country country1 = countryService.findOne(country);
        if (null == country1) {
            return MessageResult.error(localeMessageSourceService.getMessage("REQUEST_ILLEGAL"));
        }

        if ("86".equals(country1.getAreaCode())) {
            if (!ValidateUtil.isMobilePhone(phone.trim())) {
                return MessageResult.error(msService.getMessage("PHONE_FORMAT_ERROR"));
            }
        }
        //if (member.getPassword().equals(Md5.md5Digest(password + member.getSalt()).toLowerCase())) {
        if (!code.equals(cache.toString())) {
            return MessageResult.error(msService.getMessage("VERIFICATION_CODE_INCORRECT"));
        } else {
            valueOperations.getOperations().delete(SysConstant.PHONE_CHANGE_CODE_PREFIX + member.getMobilePhone());
        }
        if(member.getMobilePhone()!=null && member.getUsername().equals(member.getMobilePhone()))
        	member.setUsername(phone);
        member.setCountry(country1);
        member.setMobilePhone(phone);
        return MessageResult.success(msService.getMessage("SETTING_SUCCESS"));
        //} else {
        //    request.removeAttribute(SysConstant.SESSION_MEMBER);
        //    return MessageResult.error(msService.getMessage("PASSWORD_ERROR"));
        //}
    }
}
