package cn.iselab.mooctest.user.web.logic.impl;

import cn.iselab.mooctest.rpc.user.data.UserDTO;
import cn.iselab.mooctest.user.configure.MailProperties;
import cn.iselab.mooctest.user.constants.VerifyConstants;
import cn.iselab.mooctest.user.constants.ResponseStatus;
import cn.iselab.mooctest.user.data.ResponseResult;
import cn.iselab.mooctest.user.model.*;
import cn.iselab.mooctest.user.service.*;
import cn.iselab.mooctest.user.util.EncryptionUtil;
import cn.iselab.mooctest.user.util.MSUtil;
import cn.iselab.mooctest.user.util.OSSUtil;
import cn.iselab.mooctest.user.web.data.BankAccountInfoVO;
import cn.iselab.mooctest.user.web.data.UserVO;
import cn.iselab.mooctest.user.web.data.wrapper.BankAccountInfoVOWrapper;
import cn.iselab.mooctest.user.web.data.wrapper.UserVOWrapper;
import cn.iselab.mooctest.user.web.exception.ConfigurationNotExistException;
import cn.iselab.mooctest.user.web.exception.HttpBadRequestException;
import cn.iselab.mooctest.user.web.logic.BaseLogic;
import cn.iselab.mooctest.user.web.logic.UserLogic;
import cn.iselab.mooctest.user.web.wrapper.UserWrapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.validator.routines.EmailValidator;
import org.apache.zookeeper.Op;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.mail.MessagingException;
import javax.naming.Name;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.sql.Timestamp;
import java.util.List;
import java.util.Map;

/**
 * @author sean
 * @date 2018-03-04.
 */
@Slf4j
@Service
public class UserLogicImpl extends BaseLogic implements UserLogic {

    @Autowired
    private UserService userService;

    @Autowired
    private UserWrapper userWrapper;

    @Autowired
    private IntegralService integralService;

    @Autowired
    private MailService mailService;

    @Autowired
    private VerifyCodeService verifyCodeService;

    @Autowired
    private MailProperties mailProperties;

    @Autowired
    private UserVOWrapper userVOWrapper;

    @Autowired
    private BankAccountInfoVOWrapper bankAccountInfoVOWrapper;

    @Autowired
    private OSSUtil ossUtil;

    @Autowired
    private BankAccountInfoService bankAccountInfoService;

    @Autowired
    private ConfigurationService configurationService;

    private String userId;

    @Value("${feature.email}")
    private Boolean emailService;

    @Override
    public UserDTO getUserByEmail(String s) {
        User user = userService.findByEmail(s);
        if (user == null) {
            log.error("There is not this email");
            return null;
        }
        UserDTO dto = userWrapper.wrap(user);
        setIntegral(dto, user);
        return dto;
    }

    @Override
    public UserDTO getUserByMobile(String s) {
        User user = userService.findByMobile(s);
        if (user == null) {
            return null;
        }
        UserDTO dto = userWrapper.wrap(user);
        setIntegral(dto, user);
        return dto;
    }

    @Override
    public UserDTO getUserById(Long userId) {
        User user = userService.findById(userId);
        if (user == null) {
            return null;
        }
        UserDTO dto = userWrapper.wrap(user);
        setIntegral(dto, user);
        return dto;
    }

    @Override
    public Boolean checkPassword(UserDTO userDTO) {
        String password = userDTO.getPassword();
        User user;
        if (userDTO.getEmail().isEmpty() && userDTO.getMobile().isEmpty()) {
            throw new HttpBadRequestException("empty username");
        }
        if (!userDTO.getEmail().isEmpty()) {
            user = userService.findByEmail(userDTO.getEmail());
            if (user.getPassword().equals(password)) {
                return true;
            } else
                return false;
        } else {
            user = userService.findByMobile(userDTO.getMobile());
            if (user.getPassword().equals(password)) {
                return true;
            } else
                return false;
        }
    }

    @Override
    public ResponseResult<UserDTO> checkPWD(UserDTO userDTO) {
        ResponseResult<UserDTO> result = new ResponseResult<UserDTO>();
        String msg = "";
        if((userDTO.getEmail()==null||userDTO.getEmail().isEmpty())
                && (userDTO.getMobile()==null||userDTO.getMobile().isEmpty())){
            result.init(ResponseStatus.FAILED, "账号和密码不可为空", null);
            LOG.error("账号和密码不可为空");
            return result;
        }

        User user;
        try {
            user = (!userDTO.getEmail().isEmpty())?
                    userService.findByEmail(userDTO.getEmail())
                    :userService.findByMobile(userDTO.getMobile());

            if(user.getAvailability()!=1){
                msg = user.getAvailability()==0?"该帐号未激活":"该帐号被删除";
                result.init(ResponseStatus.FAILED, msg, userDTO);
                LOG.error(msg+"-email:"+user.getEmail());
                return result;
            }
            if (user.getPassword().equals(userDTO.getPassword())) {
                msg = "登录成功--登录id--" + user.getId();
                result.init(ResponseStatus.SUCCESS, msg, userWrapper.wrap(user));
                LOG.info(msg+"-email:"+user.getEmail());
            } else {
                msg = "登录失败--密码错误";
                result.init(ResponseStatus.FAILED, msg, userDTO);
                LOG.error(msg+"-email:"+user.getEmail());
            }
//
//            if (!userDTO.getEmail().isEmpty()) {
//                user = userService.findByEmail(userDTO.getEmail());
//                if (user.getPassword().equals(userDTO.getPassword())) {
//                    msg = "邮箱登录成功--邮箱--" + user.getEmail();
//                    result.init(ResponseStatus.SUCCESS, msg, userWrapper.wrap(user));
//                    LOG.info(msg);
//                } else {
//                    msg = "邮箱登录失败--密码错误";
//                    result.init(ResponseStatus.FAILED, msg, userDTO);
//                    LOG.error(msg);
//                }
//            } else {
//                user = userService.findByMobile(userDTO.getMobile());
//                if (user.getPassword().equals(userDTO.getPassword())) {
//                    msg = "手机登录成功--手机号";
//                    result.init(ResponseStatus.SUCCESS, msg, userWrapper.wrap(user));
//                    LOG.info(msg);
//                } else {
//                    msg = "手机登录失败--密码错误";
//                    result.init(ResponseStatus.FAILED, msg, userDTO);
//                    LOG.error(msg);
//                }
//            }
        }catch (NullPointerException e){
            result.init(ResponseStatus.FAILED, "用户不存在", userDTO);
            LOG.error(result.getMsg(),e);
        }finally {
            return result;
        }
    }

    @Override
    public UserDTO save(UserDTO userDTO) {
        User user = userWrapper.unwrap(userDTO);
        return userWrapper.wrap(userService.register(user));
    }

    @Override
    public UserDTO updateUser(UserDTO userDTO) {
        User user = userWrapper.unwrap(userDTO);
        user = userService.update(user);
        return userWrapper.wrap(user);
    }

    private void setIntegral(UserDTO dto, User user) {
        UserIntegral integral = integralService.findByUserId(user.getId());
        if (integral == null) {
            UserIntegral integral1 = new UserIntegral();
            integral1.setEnabled(true);
            integral1.setTotal(0);
            integral1.setUserId(user.getId());
            integral1.setCreateTime(new Timestamp(System.currentTimeMillis()));
            integralService.saveIntegral(integral1);
            dto.setIntegral(integral1.getTotal());
        } else {
            dto.setIntegral(integral.getTotal());
        }
    }

    @Override
    public List<UserDTO> getUserByFuzzyName(UserDTO userDTO) {
        List<User> users = userService.findByFuzzyName(userDTO.getName());
        return userWrapper.wrap(users);
    }

    @Override
    public List<UserDTO> getUserByFuzzyEmail(UserDTO userDTO) {
        List<User> users = userService.findByFuzzyEmail(userDTO.getEmail());
        return userWrapper.wrap(users);
    }

    @Override
    public List<UserDTO> getUserByFuzzyNameOrEmail(UserDTO userDTO) {
        String keyword = null;
        if (userDTO.getName() != null) {
            keyword = userDTO.getName();
        } else if (userDTO.getEmail() != null) {
            keyword = userDTO.getEmail();
        }
        List<User> userList = userService.findByFuzzyNameOrEmail(keyword);
        return userWrapper.wrap(userList);
    }

    @Override
    public List<UserDTO> findAll(List<Long> userIds) {
        if (userIds.size() < 1) {
            throw new HttpBadRequestException("userId length <1");
        }
        return userWrapper.wrap(userService.findAll(userIds));
    }

    @Override
    public List<UserDTO> findByEmails(List<String> emails) {
        if (emails.size() < 1) {
            throw new HttpBadRequestException("emails length <1");
        }
        return userWrapper.wrap(userService.findAllByEmails(emails));
    }

    @Override
    public ResponseResult<UserDTO> registerAccount(UserVO userVO) {
        ResponseResult<UserDTO> result = new ResponseResult<>();
        if(!userVO.getEmail().trim().isEmpty() && !userVO.getPassword().trim().isEmpty()) {
            if(userService.findByEmail(userVO.getEmail()) != null){
                result.init(ResponseStatus.FAILED, "该邮箱已被注册", userVO);
                LOG.error(result.getMsg());
                return result;
            }
            if (!EmailValidator.getInstance().isValid(userVO.getEmail())){
                result.init(ResponseStatus.FAILED, "注册邮箱非法", userVO);
                LOG.error(result.getMsg());
                return result;
            }
            if (userVO.getName().length()>50 || userVO.getName().length()<2){
                result.init(ResponseStatus.FAILED, "姓名长度非法,应在2~50位", userVO);
                LOG.error(result.getMsg());
                return result;
            }
            if (userVO.getPassword().length() > 16 || userVO.getPassword().length() < 6){
                result.init(ResponseStatus.FAILED, "密码长度非法,应在6~16位", userVO);
                LOG.error(result.getMsg());
                return result;
            }
            if (! userVO.getPassword2().trim().equals(userVO.getPassword())){
                result.init(ResponseStatus.FAILED, "两次密码不一致，请重新输入", userVO);
                LOG.error(result.getMsg());
                return result;
            }

            if(emailService){
                // 具有邮箱服务
                if(! verifyCodeService.validateVerifyCode("email", userVO.getEmail(), userVO.getVerifyCode())){
                    result.init(ResponseStatus.FAILED, "请确认验证码输入正确", userVO);
                    LOG.error(result.getMsg());
                    return result;
                }
            }



            try{
                userVO.setPassword(EncryptionUtil.encryptMD5(userVO.getPassword()));
                userVO.setAvailability(1);
                userVO.setCreateTime(new Timestamp(System.currentTimeMillis()).getTime());
                userVO.setManualCheckValid(true);
                User user = userWrapper.unwrap(userVO);

                userService.register(user);
                result.init(ResponseStatus.SUCCESS, "注册成功!请前往登录!", userWrapper.wrap(user));
            }catch (Exception e){
                result.init(ResponseStatus.FAILED, "系统错误:注册失败", null);
                LOG.error(result.getMsg(),e);
                return result;
            }

        }else{
            result.init(ResponseStatus.FAILED, "帐号和密码不可为空", userVO);
            LOG.error(result.getMsg());
            return result;
        }
        return result;
    }

    @Override
    public ResponseResult<String> sendVerifyEmail(UserDTO userDTO) {
        String receiver = userDTO.getEmail();
        ResponseResult<String> result = new ResponseResult<>();
//        if(userService.findByEmail(userDTO.getEmail()) != null){
//            result.init(ResponseStatus.FAILED, "该邮箱已被注册", receiver);
//            LOG.error(result.getMsg());
//            return result;
//        }
        System.out.println(userDTO.getEmail());
        if (!EmailValidator.getInstance().isValid(userDTO.getEmail())){
            result.init(ResponseStatus.FAILED, "邮箱输入非法", receiver);
            LOG.error(result.getMsg());
            return result;
        }

        VerifyCode verifyCode = new VerifyCode();
        verifyCode.setType("email");
        verifyCode.setReceiver(receiver);
        verifyCode.setCode(MSUtil.generateRandomVeriCode());
        verifyCode.setCreateTime(new Timestamp(System.currentTimeMillis()));
        verifyCode.setExpiredTime(new Timestamp(System.currentTimeMillis()+ VerifyConstants.TIME_OUT));

        try {
            mailService.sendVerifyEmail(mailProperties.getUsername(),
                    verifyCode.getReceiver(),
                    verifyCode.getCode());
        } catch (MessagingException e) {
            result.init(ResponseStatus.FAILED, "邮件发送出错，请检查邮箱是否正确", receiver);
            LOG.error(result.getMsg(),e);
            return result;
        }
        verifyCodeService.saveVerifyCode(verifyCode);
        result.init(ResponseStatus.SUCCESS, "邮件发送成功！", receiver);
        LOG.info(result.getMsg()+"-Email: " + receiver + "-code: "+ verifyCode.getCode());
        return result;
    }

    @Override
    public ResponseResult<String> sendMobileVerfication(UserDTO userDTO) {
        String receiver = userDTO.getMobile();
        ResponseResult<String> result = new ResponseResult<>();
        if (receiver == null || !MSUtil.isMobileNO(receiver)){
            result.init(ResponseStatus.FAILED, "手机号不合法！", receiver);
            LOG.error(result.getMsg() + " mobile: " + receiver);
            return result;
        }
        VerifyCode latestVerifyCode = verifyCodeService.getLatestVerifyCode("mobile", receiver);
        if (latestVerifyCode != null ) {
            long waitTime = (latestVerifyCode.getCreateTime().getTime()
                    + VerifyConstants.MOBILE_VERIFICATION_INTERVAL)
                    - System.currentTimeMillis();
            if(waitTime > 0){
                result.init(ResponseStatus.FAILED, "发送过于频繁," + waitTime/1000 + "秒后重试", receiver);
                LOG.error(result.getMsg() + "-receiver: " + receiver);
                return result;
            }
        }

        String code = MSUtil.generateRandomVeriCode();
        String successCode = "000000";
        String arrearsCode = "121002";
        String sendResult = MSUtil.sendSmsVerification(receiver, code);
        if(sendResult.equals(successCode)){
            VerifyCode verifyCode = new VerifyCode();
            verifyCode.setType("mobile");
            verifyCode.setReceiver(receiver);
            verifyCode.setCode(code);
            verifyCode.setCreateTime(new Timestamp(System.currentTimeMillis()));
            verifyCode.setExpiredTime(new Timestamp(System.currentTimeMillis()
                    + VerifyConstants.TIME_OUT));
            verifyCodeService.saveVerifyCode(verifyCode);
            result.init(ResponseStatus.SUCCESS, "短信发送成功", receiver);
            LOG.info(result.getMsg() + ", mobile: " + receiver + " code: " +code);
        }else{
            if (sendResult.equals(arrearsCode)){
                mailService.sendArrearsEmail();
            }
            result.init(ResponseStatus.FAILED, "短信服务异常", receiver);
            LOG.error(result.getMsg(), "- mobile: " + receiver);
        }

        return result;

    }

    @Override
    public ResponseResult<UserDTO> loginByMobile(UserVO userVO) {
        ResponseResult<UserDTO> result = new ResponseResult<>();
        String mobile = userVO.getMobile();
        String code = userVO.getVerifyCode();
        if (mobile == null || !MSUtil.isMobileNO(mobile)){
            result.init(ResponseStatus.FAILED, "手机号不正确", userVO);
            LOG.error(result.getMsg() + userVO.getMobile());
            return result;
        }
        if(!verifyCodeService.validateVerifyCode("mobile", mobile, code)){
            result.init(ResponseStatus.FAILED, "手机号或验证码不正确", userVO);
            LOG.error(result.getMsg() + " - mobile: "+mobile + " - code: " + code);
            return result;
        }
        User user = userService.findByMobile(mobile);
        if (user == null){
            result.init(ResponseStatus.FAILED, "该手机号未绑定平台账号", userVO);
            LOG.error(result.getMsg() + userVO.getMobile());
            return result;
        }
        UserDTO userDTO = userWrapper.wrap(user);
        result.init(ResponseStatus.SUCCESS, "手机登录成功", userDTO);
        LOG.error(result.getMsg() + " - mobile: " + userVO.getMobile());
        return result;
    }

    @Override
    public ResponseResult<UserVO> checkVerifyCode(UserVO userVO, String type){
        ResponseResult<UserVO> result = new ResponseResult<>();
        if (type.equals("email")){
            if (!EmailValidator.getInstance().isValid(userVO.getEmail())){
                result.init(ResponseStatus.FAILED, "邮箱输入非法", userVO);
                LOG.error(result.getMsg() + " email: " + userVO.getEmail());
                return result;
            }
            if(! verifyCodeService.validateVerifyCode("email", userVO.getEmail(), userVO.getVerifyCode())){
                result.init(ResponseStatus.FAILED, "请确认邮箱及验证码输入正确", userVO);
                LOG.error(result.getMsg());
                return result;
            }

            User user = userService.findByEmail(userVO.getEmail());
            if (user == null){
                result.init(ResponseStatus.FAILED, "用户不存在", userVO);
                LOG.error(result.getMsg());
                return result;
            }
            try{
                userVO = resetCodeStr(user);
                result.init(ResponseStatus.SUCCESS, "验证码输入正确", userVO);
                LOG.info(result.getMsg() + " email: " + userVO.getEmail()+ " code: " + userVO.getVerifyCode());
                return result;
            }catch (Exception e){
                LOG.error("重置密码加密口令出错", e);
                result.init(ResponseStatus.FAILED, "系统繁忙", null);
                return result;
            }

        }

        if (type.equals("mobile")){
            if (userVO.getMobile() == null || !MSUtil.isMobileNO(userVO.getMobile())){
                result.init(ResponseStatus.FAILED, "手机号不正确", userVO);
                LOG.error(result.getMsg() + userVO.getMobile());
                return result;
            }
            if(!verifyCodeService.validateVerifyCode("mobile", userVO.getMobile(), userVO.getVerifyCode())){
                result.init(ResponseStatus.FAILED, "手机号或验证码不正确", userVO);
                LOG.error(result.getMsg());
                return result;
            }
            User user = userService.findByMobile(userVO.getMobile());
            if (user == null){
                result.init(ResponseStatus.FAILED, "该手机号未绑定平台账号", userVO);
                LOG.error(result.getMsg() + userVO.getMobile());
                return result;
            }
            try{
                userVO = resetCodeStr(user);
                result.init(ResponseStatus.SUCCESS, "验证码输入正确", userVO);
                LOG.info(result.getMsg() + " email: " + userVO.getMobile()+ " code: " + userVO.getVerifyCode());
                return result;
            } catch (Exception e){
                LOG.error("重置密码加密口令出错", e);
                result.init(ResponseStatus.FAILED, "系统繁忙", null);
                return result;
            }


        }

        result.init(ResponseStatus.FAILED, "验证出错", userVO);
        LOG.error(result.getMsg());
        return result;
    }


    @Override
    public ResponseResult<UserVO> resetPassword(UserVO userVO){
        ResponseResult<UserVO> result = new ResponseResult<>();
        String encrypt = userVO.getVerifyCode();
        try{
            String base64DecodeStr = new String(Base64.decodeBase64(encrypt.getBytes("UTF-8")));
            String decrypt = EncryptionUtil.decryptDES(base64DecodeStr);
            String[] items = decrypt.split("_");
            long userId = Long.valueOf(items[1]);
            long expireTime = Long.valueOf(items[2]);
            if (expireTime < System.currentTimeMillis()){
                throw new Exception("验证已过期");
            }
            User user = userService.findById(userId);
            if (user == null){
                throw new Exception("用户不存在");
            }
            if (userVO.getPassword().length() > 16 || userVO.getPassword().length() < 6){
                throw new Exception("密码长度应在6-16位");
            }
            user.setPassword(EncryptionUtil.encryptMD5(userVO.getPassword()));
            user = userService.update(user);
            userVO = userVOWrapper.wrap(user);
            result.init(ResponseStatus.SUCCESS, "密码重置成功", userVO);
            LOG.info(result.getMsg() + "userId: " + userVO.getId());
        } catch (Exception e){
            result.init(ResponseStatus.FAILED, e.getMessage(), userVO);
            LOG.error(result.getMsg(), e);
            return result;
        }
        return result;
    }

    private UserVO resetCodeStr(User user) throws Exception {
        UserVO userVO = userVOWrapper.wrap(user);
        String passStr = "user_" + user.getId() + "_" +
                String.valueOf(System.currentTimeMillis() +
                        VerifyConstants.TIME_OUT);
        String encryptStr;
        encryptStr = EncryptionUtil.encryptDES(passStr);
        String base64Encrypt = new String(Base64.encodeBase64(encryptStr.getBytes("UTF-8")));
        String code = base64Encrypt;
        userVO.setVerifyCode(code);
        return userVO;
    }

    @Override
    public ResponseResult<UserVO> updateUserPassword(UserVO userVO, HttpServletRequest request){
        ResponseResult<UserVO> result = new ResponseResult<>();
        Long userId = Long.parseLong((String) request.getSession().getAttribute("userId"));
        try {
            if (userId == null)
                throw new Exception("用户未登录");
            if (userVO.getPassword().length() > 16 || userVO.getPassword().length() < 6){
                throw new Exception("密码长度应在6-16位");
            }
            User user = userService.findById(userId);
            if (!EncryptionUtil.encryptMD5(userVO.getOldPassword()).equals(user.getPassword()))
                throw new Exception("旧密码错误");

            String password = EncryptionUtil.encryptMD5(userVO.getPassword());
            user.setPassword(password);
            user = userService.update(user);
            userVO = userVOWrapper.wrap(user);
            userVO.setPassword("");
            userVO.setPassword2("");
            String redirectUrl = (String) request.getSession().getAttribute("redirectURL");
            redirectUrl = URLEncoder.encode(redirectUrl, "UTF-8");
            result.init(ResponseStatus.SUCCESS, redirectUrl, userVO);
            LOG.info(result.getMsg()+" userId: "+userVO.getId());
            request.getSession().removeAttribute("userId");
            request.getSession().invalidate();
        } catch (Exception e) {
            result.init(ResponseStatus.FAILED, e.getMessage(), userVO);
            LOG.error(result.getMsg(),e);
            return result;
        }
        return result;
    }

    @Override
    public ResponseResult<UserVO> updateUserPasswordNew(UserVO userVO, HttpServletRequest request){
        ResponseResult<UserVO> result = new ResponseResult<>();
        Long userId = userVO.getId();
        User user = userService.findById(userId);
        try {
            if(userId == null)
                throw new Exception("用户未登录");
            if (userVO.getPassword().length() > 16 || userVO.getPassword().length() < 6){
                throw new Exception("密码长度应在6-16位");
            }
            if (!EncryptionUtil.encryptMD5(userVO.getOldPassword()).equals(user.getPassword()))
                throw new Exception("旧密码错误");

            String password = EncryptionUtil.encryptMD5(userVO.getPassword());
            user.setPassword(password);
            user = userService.update(user);
            userVO = userVOWrapper.wrap(user);
            userVO.setPassword("");
            userVO.setPassword2("");
            result.init(ResponseStatus.SUCCESS, "密码修改成功", userVO);
            LOG.info(result.getMsg()+" userId: "+userVO.getId());
            request.getSession().removeAttribute("userId");
            request.getSession().invalidate();
        } catch (Exception e) {
            result.init(ResponseStatus.FAILED, e.getMessage(), userVO);
            LOG.error(result.getMsg(),e);
            return result;
        }
        return result;
    }

    @Override
    public ResponseResult<UserVO> updateUserEmail(UserVO userVO, HttpServletRequest request) {
        ResponseResult<UserVO> result = new ResponseResult<>();
        Long userId = userVO.getId();
        User user = userService.findById(userId);
        try {
            if(userId == null || !user.getPassword().equals(userVO.getPassword()))
                throw new Exception("用户未登录");
            if (!verifyCodeService.validateVerifyCode("email", userVO.getEmail(), userVO.getVerifyCode()))
                throw new Exception("验证码或邮箱填写错误");
            if (userVO.getEmail().equals(user.getEmail()) || userService.findByEmail(userVO.getEmail()) != null)
                throw new Exception("该邮箱已被注册");
            user.setEmail(userVO.getEmail());
            userVO = userVOWrapper.wrap(userService.update(user));
            result.init(ResponseStatus.SUCCESS, "邮箱修改成功", userVO);
            LOG.info(result.getMsg() + " userId: "+ userVO.getId() + " email: " + userVO.getEmail());
        } catch (Exception e){
            result.init(ResponseStatus.FAILED, e.getMessage(), userVO);
            LOG.info(result.getMsg(), e);
            return result;
        }
        return result;
    }

    @Override
    public ResponseResult<UserVO> updateUserMobile(UserVO userVO, HttpServletRequest request) {
        ResponseResult<UserVO> result = new ResponseResult<>();
        Long userId = userVO.getId();
        User user = userService.findById(userId);
        try {
            if(userId == null || !user.getPassword().equals(userVO.getPassword()))
                throw new Exception("用户未登录");
            if (!verifyCodeService.validateVerifyCode("mobile", userVO.getMobile(), userVO.getVerifyCode()))
                throw new Exception("验证码或手机号填写错误");
            if (userVO.getMobile().equals(user.getMobile()) || userService.findByMobile(userVO.getMobile()) != null)
                throw new Exception("该手机号码已被绑定");
            user.setMobile(userVO.getMobile());
            userVO = userVOWrapper.wrap(userService.update(user));
            result.init(ResponseStatus.SUCCESS, "手机号绑定成功", userVO);
            LOG.info(result.getMsg() + " userId: "+ userVO.getId() + " mobile: " + userVO.getMobile());
        } catch (Exception e){
            result.init(ResponseStatus.FAILED, e.getMessage(), userVO);
            LOG.info(result.getMsg(), e);
            return result;
        }
        return result;
    }

    @Override
    public ResponseResult<UserVO> verifyOldMobile(UserVO userVO, HttpServletRequest request) {
        ResponseResult<UserVO> result = new ResponseResult<>();
        Long userId = userVO.getId();
        User user = userService.findById(userId);
        try {
            if(userId == null || !user.getPassword().equals(userVO.getPassword()))
                throw new Exception("用户未登录");
            if (!verifyCodeService.validateVerifyCode("mobile", userVO.getMobile(), userVO.getVerifyCode()))
                throw new Exception("验证码或手机号填写错误");
            if (!userVO.getMobile().equals(user.getMobile()))
                throw new Exception("此手机号不是用户绑定的手机号");
            LOG.info(result.getMsg() + "旧手机验证成功 userId: "+ userVO.getId() + " mobile: " + userVO.getMobile());
            result.init(ResponseStatus.SUCCESS, "验证成功", userVO);
        } catch (Exception e){
            result.init(ResponseStatus.FAILED, e.getMessage(), userVO);
            LOG.info(result.getMsg(), e);
            return result;
        }
        return result;
    }

    @Override
    public ResponseResult<Object> setBankInfo(BankAccountInfoVO infoVO, HttpServletRequest request) {
        try {
            infoVO.setId_card_front_url(ossUtil.upload(infoVO.getID_card_front(), OSSUtil.FileDirType.BANKINFO));
            infoVO.setId_card_back_url(ossUtil.upload(infoVO.getID_card_back(), OSSUtil.FileDirType.BANKINFO));
        }catch (Exception e){
            return new ResponseResult<Object>(ResponseStatus.FAILED, "上传失败，请稍后再试",null);
        }
        infoVO.setUser_id(Long.parseLong((String) request.getSession().getAttribute("userId")));
        BankAccountInfo info = bankAccountInfoService.setBankAccountInfo(bankAccountInfoVOWrapper.unwrap(infoVO));
        if (info==null){
            return new ResponseResult<Object>(ResponseStatus.FAILED, "上传出错，请稍后再试",null);
        }
        return new ResponseResult<Object>(ResponseStatus.SUCCESS, "上传成功", null);
    }

    @Override
    public void saveRedirectUrl(String redirect, HttpServletRequest request) {
        try {
            redirect = URLDecoder.decode(redirect, "UTF-8");
            request.getSession().setAttribute("redirectURL", redirect);
        } catch (UnsupportedEncodingException e) {
            LOG.info("redirectURL出错", e);
            if(request.getSession().getAttribute("redirectURL")==null){
                request.getSession().setAttribute("redirectURL", redirect);
            }
        }
    }

    @Override
    public Boolean isLogin(HttpServletRequest request) {
        if (request.getSession().getAttribute("userId")==null)
            return false;
        return true;
    }

    @Override
    public String getPlatformName() throws ConfigurationNotExistException {
        return configurationService.getPlatformNameConfiguration();
    }

    @Override
    public Map<String, String> getConfiguration() {
        return configurationService.getConfiguration();
    }

    @Override
    public void recordLoginAction(HttpServletRequest request, Long userId, String resource) {
        OperationRecord record = this.buildUserOperation(request,userId,resource);
        if(record==null)
            return;
        record.setOperation("Login");
        userService.recordOperation(record);
        Timestamp current = new Timestamp(System.currentTimeMillis());
        log.info(String.format("User[%d] Login at [%s] IP(%s)",userId,current.toString(), record.getIp()));
    }

    @Override
    public void recordLogoutAction(HttpServletRequest request, Long userId, String resource) {
        OperationRecord userOperation = this.buildUserOperation(request,userId, resource);
        if(userOperation==null)
            return;
        userOperation.setOperation("Logout");
        userService.recordOperation(userOperation);
        Timestamp current = new Timestamp(System.currentTimeMillis());
        log.info(String.format("User[%d] Logout at [%s]",userId,current.toString()));
    }

    @Override
    public void recordUserOperation(HttpServletRequest request, Long userId, String operation, String resource) {
        OperationRecord record = this.buildUserOperation(request, userId, resource);
        record.setOperation(operation);
        userService.recordOperation(record);
        Timestamp current = new Timestamp(System.currentTimeMillis());
        log.info(String.format("User[%d] [%s] at [%s]", userId, operation,current.toString()));
    }

    @Override
    public void recordUserOperation(OperationRecord record) {
        userService.recordOperation(record);
        Timestamp current = new Timestamp(System.currentTimeMillis());
        log.info(String.format("User[%d] [%s] at [%s]",record.getUserId(),record.getOperation(),current.toString()));
    }

    @Override
    public void recordUserOperation(String ip, Long userId, String operation, String resource) {
        OperationRecord record = this.buildUserOperation(ip, userId, resource);
        record.setOperation(operation);
        userService.recordOperation(record);
        Timestamp current = new Timestamp(System.currentTimeMillis());
        log.info(String.format("User[%d] [%s] at [%s]", userId, operation,current.toString()));
    }

    private OperationRecord buildUserOperation(HttpServletRequest request, Long userId, String resource) {
        String ip = this.getRequestIp(request);
        if("101.37.78.167".equals(ip)) {
            return null;
        }
        OperationRecord userOperation = new OperationRecord();
        userOperation.setIp(ip);
        userOperation.setUserId(userId);
        userOperation.setResource(resource);
        return userOperation;
    }

    private OperationRecord buildUserOperation(String ip, Long userId, String resource) {
        if("101.37.78.167".equals(ip)) {
            return null;
        }
        OperationRecord userOperation = new OperationRecord();
        userOperation.setIp(ip);
        userOperation.setUserId(userId);
        userOperation.setResource(resource);
        return userOperation;
    }

    private String getRequestIp(HttpServletRequest request){
        String ip = request.getHeader("x-forwarded-for");
        if (isNotValidIP(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (isNotValidIP(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (isNotValidIP(ip)) {
            ip = request.getRemoteAddr();
        }
        if (isNotValidIP(ip)) {
            ip = request.getHeader("http_client_ip");
        }
        if (isNotValidIP(ip)) {
            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
        }
        if (ip.equals("0:0:0:0:0:0:0:1")) {
            ip = "127.0.0.1";
        }
        if (ip.split(",").length > 1) {
            ip = ip.split(",")[0];
        }
        return ip;
    }

    private boolean isNotValidIP(String ip) {
        return ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip);
    }



}
