package com.lightinit.hsdataportal.impl.open;

import com.lightinit.hsdataportal.common.PhoneSendUtils;
import com.lightinit.hsdataportal.dictionary.DicCodeType;
import com.lightinit.hsdataportal.dictionary.DicFuncCode;
import com.lightinit.hsdataportal.dictionary.DicUserAuthState;
import com.lightinit.hsdataportal.dictionary.DicUserType;
import com.lightinit.hsdataportal.entity.*;
import com.lightinit.hsdataportal.mapper.SmsSwitchMapper;
import com.lightinit.hsdataportal.mapper.UserAuthSettingMapper;
import com.lightinit.hsdataportal.mapper.UserMapper;
import com.lightinit.hsdataportal.mapper.UserSecurityCodeMapper;
import com.lightinit.hsdataportal.model.LoginUser;
import com.lightinit.hsdataportal.model.ResultState;
import com.lightinit.hsdataportal.model.ResultStateCode;
import com.lightinit.hsdataportal.model.ShareRegisterModel;
import com.lightinit.hsdataportal.service.open.IAccountService;
import com.lightinit.hsdataportal.spring.DynamicDataContextHolder;
import org.apache.shiro.crypto.SecureRandomNumberGenerator;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

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

/**
 * @author WangYao
 * @date 2018/6/22 11:13
 * @description 账户业务实现
 */
@Service("openAccountServiceImpl")
public class AccountServiceImpl implements IAccountService {

    @Autowired
    private UserMapper userMapper;
    @Autowired
    private UserAuthSettingMapper userAuthSettingMapper;
    @Autowired
    private UserSecurityCodeMapper userSecurityCodeMapper ;
    @Autowired
    private SmsSwitchMapper smsSwitchMapper ;


    public LoginUser getLoginUserByUsername(String username) {
        User user = getUserByUsername(username);
        if (user == null){
            return null;
        }
        LoginUser loginUser = new LoginUser();
        BeanUtils.copyProperties(user, loginUser);
        return loginUser;
    }

    public User getUserByUsername(String username) {
        DynamicDataContextHolder.setCustomerType(DynamicDataContextHolder.DEFAULT);
        UserExample example1 = new UserExample();
        UserExample.Criteria criteria1 = example1.createCriteria();
        criteria1.andUsernameEqualTo(username);
        List<User> userList= userMapper.selectByExample(example1);
        if (userList == null || userList.size() <= 0){
            return null;
        }
        return userList.get(0);
    }

    @Override
    public ResultState register(ShareRegisterModel shareRegisterModel) {
        DynamicDataContextHolder.setCustomerType(DynamicDataContextHolder.DEFAULT);
        ResultState<Long> resultState = new ResultState<>() ;
        if (StringUtils.isEmpty(shareRegisterModel)){
            resultState.setStateCode(ResultStateCode.INVALID_DATA);
            resultState.setMsg("参数不能为空");
            return resultState ;
        }
        if (!shareRegisterModel.getPassword().equals(shareRegisterModel.getPassword1())){
            resultState.setStateCode(ResultStateCode.INVALID_DATA);
            resultState.setMsg("密码不一致");
        }else {
            UserExample userExample = new UserExample();
            UserExample.Criteria criteria = userExample.createCriteria();
            criteria.andUsernameEqualTo(shareRegisterModel.getUsername());
            List<User> users = userMapper.selectByExample(userExample);
            if (users.size() > 0) {
                resultState.setStateCode(ResultStateCode.INVALID_DATA);
                resultState.setMsg("用户名已存在");
            }else {
                String salt = new SecureRandomNumberGenerator().nextBytes().toHex();
                String password_cipherText = new Md5Hash(shareRegisterModel.getPassword(), shareRegisterModel.getUsername() + salt, 3).toHex();
                User user = new User() ;
                user.setUsername(shareRegisterModel.getUsername());
                user.setPassword(password_cipherText);
                user.setSalt(salt);
                user.setPhone(shareRegisterModel.getPhone());
//                user.setUserType(DicUserType.PERSONAL);
//                user.setAuthState(DicUserAuthState.WAITING);
                user.setCreatedAt(new Date());
                user.setIsAuth((byte) 0);
                user.setIsBuildin((byte) 0);
                user.setIsLcokedOut((byte) 0);
                user.setAuthState(DicUserAuthState.APPROVED);
                int result = userMapper.insert(user) ;
                if (!(result>0)){
                    resultState.setStateCode(ResultStateCode.INVALID_DATA);
                    resultState.setMsg("新增用户失败");
                }
                resultState.setData(user.getId());
            }
        }
        return resultState;
    }

    @Override
    public ResultState insertUserAuthSetting(Long userId, Long passUserId) {
        ResultState<Long> resultState = new ResultState<>() ;
        UserAuthSetting userAuthSetting = new UserAuthSetting();
        userAuthSetting.setUserId(userId);
        userAuthSetting.setCreatedAt(new Date());
        userAuthSetting.setAuthKey(passUserId==null?null:passUserId+"");
        int i = userAuthSettingMapper.insert(userAuthSetting);
        if(i<0){
            resultState.setStateCode(ResultStateCode.INVALID_DATA);
            resultState.setMsg("同步pass失败");
        }else{
            resultState.setData(userAuthSetting.getId());
        }
        return resultState;
    }

    @Override
    @Transactional
    public ResultState validatePhone(String phone) {
        DynamicDataContextHolder.setCustomerType(DynamicDataContextHolder.DEFAULT);
        ResultState<Object> resultState = new ResultState<>();
        UserExample example = new UserExample() ;
        UserExample.Criteria criteria = example.createCriteria() ;
        criteria.andPhoneEqualTo(phone) ;
        List<User> users = userMapper.selectByExample(example);
        if (users.size()>0){
            resultState.setStateCode(ResultStateCode.UNAUTHORIZED);
            resultState.setMsg("手机号已注册！");
        }else {
            Map<String, Object> map = PhoneSendUtils.send(phone);
            if (map!=null){
                if (map.get("Message").equals("OK")&&map.get("Code").equals("OK")){
                    String code = (String) map.get("returnCode") ;
                    UserSecurityCode userSecurityCode = new UserSecurityCode() ;
                    userSecurityCode.setUsername(phone);
                    userSecurityCode.setCode(code);
                    userSecurityCode.setCodeType(DicCodeType.CODE);
                    Calendar nowTime = Calendar.getInstance();
                    userSecurityCode.setEffectiveTime(nowTime.getTime());
                    nowTime.add(Calendar.MINUTE, 5);
                    userSecurityCode.setExpiredTime(nowTime.getTime());
                    //如果存在更新，否则添加
                    UserSecurityCodeExample example1 = new UserSecurityCodeExample() ;
                    UserSecurityCodeExample.Criteria criteria1 = example1.createCriteria() ;
                    criteria1.andUsernameEqualTo(phone) ;
                    criteria1.andCodeTypeEqualTo(DicCodeType.CODE) ;
                    List<UserSecurityCode> userSecurityCodes = userSecurityCodeMapper.selectByExample(example1);
                    if (userSecurityCodes.size()>0){
                        //更新
                        userSecurityCodeMapper.updateByPhone(userSecurityCode) ;
                    }else {
                        //新增
                        userSecurityCodeMapper.insert(userSecurityCode);
                    }
                }else {
                    resultState.setStateCode(ResultStateCode.UNAUTHORIZED);
                    resultState.setMsg("获取短信验证码异常！");
                }
            }else {
                resultState.setStateCode(ResultStateCode.UNAUTHORIZED);
                resultState.setMsg("获取短信验证码异常！");
            }
        }
        return resultState;
    }

    @Override
    public ResultState isCode(String phone, String code) {
        DynamicDataContextHolder.setCustomerType(DynamicDataContextHolder.DEFAULT);
        ResultState resultState = new ResultState() ;
        UserSecurityCodeExample example = new UserSecurityCodeExample() ;
        UserSecurityCodeExample.Criteria criteria = example.createCriteria() ;
        criteria.andUsernameEqualTo(phone) ;
        criteria.andCodeTypeEqualTo(DicCodeType.CODE) ;
        List<UserSecurityCode> userSecurityCodes = userSecurityCodeMapper.selectByExample(example);
        if (userSecurityCodes.size()>0){
            UserSecurityCode userSecurityCode = userSecurityCodes.get(0);
            if (userSecurityCode.getCode().equals(code)){
                Date date = new Date() ;
                Date effectiveTime = userSecurityCode.getEffectiveTime();
                Date expiredTime = userSecurityCode.getExpiredTime();
                if (!((date.compareTo(effectiveTime)==1)&&(date.compareTo(expiredTime)==0||date.compareTo(expiredTime)==-1))){
                    resultState.setStateCode(ResultStateCode.UNAUTHORIZED);
                    resultState.setMsg("验证码已过期！");
                }
            }else {
                resultState.setStateCode(ResultStateCode.UNAUTHORIZED);
                resultState.setMsg("验证码不正确！");
            }
        }else {
            resultState.setStateCode(ResultStateCode.UNAUTHORIZED);
            resultState.setMsg("手机号没有获取过验证码！");
        }
        return resultState;
    }

    @Override
    public boolean isSecurityCode() {
        DynamicDataContextHolder.setCustomerType(DynamicDataContextHolder.DEFAULT);
        boolean falg = false ;
        SmsSwitchExample example = new SmsSwitchExample() ;
        example.createCriteria().andFuncCodeEqualTo(DicFuncCode.REGIST) ;
        List<SmsSwitch> smsSwitches = smsSwitchMapper.selectByExample(example);
        if (smsSwitches.size()>0){
            SmsSwitch smsSwitch = smsSwitches.get(0);
            if (smsSwitch.getIsSend()!=null){
                if (smsSwitch.getIsSend()==1){
                    falg = true ;
                }
            }
        }
        return falg;
    }
}
