package com.ssm.manage.service.impl;

import com.ssm.core.service.impl.BaseServiceImpl;
import com.ssm.core.utils.AESUtils;
import com.ssm.core.utils.SmsType;
import com.ssm.manage.dao.BaseDao;
import com.ssm.manage.entity.*;
import com.ssm.manage.query.MenuPowerRequest;
import com.ssm.manage.query.RoleUserRequest;
import com.ssm.manage.response.ResponseCode;
import com.ssm.manage.dao.SsmLoginDao;
import com.ssm.manage.query.UserRequest;
import com.ssm.manage.response.UserResponse;
import com.ssm.manage.service.*;
import com.ssm.manage.utils.Constant;
import com.ssm.util.RedisClient;
import org.apache.commons.lang.ObjectUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpSession;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

@Service
public class SsmLoginServiceImpl extends BaseServiceImpl<SysUser> implements SsmLoginService {

    @Autowired
    public SsmLoginDao dao;
    @Autowired
    private RedisClient<UserResponse> templateRedisClient;
    @Autowired
    private SsmSysUserService ssmSysUserService;
    @Autowired
    private SsmSysRoleUserService ssmSysRoleUserService;
    @Autowired
    private SsmSysMenuPowerService ssmSysMenuPowerService;

    @Autowired
    private SsmBaseStoreService ssmBaseStoreService;
    @Override
    public BaseDao<SysUser> getDao() {
        return dao;
    }

    @Override
    public UserResponse accountLogin(UserRequest userRequest) throws SmsException {
        SysUser sysUser = new SysUser();
        sysUser.setUserNum(userRequest.getUserNum());
        //获取redis key值
        String key = getKey(userRequest.getUserNum());
        UserResponse userResponse = new UserResponse();
        String token = "";
        String password = null;
        try {
            password = AESUtils.encrypt(userRequest.getPassword());
        } catch (Exception e) {
            throw new SmsException(ResponseCode.DECRYPT_FAILED);
        }
        //查询数据库
        sysUser = dao.selectOne(sysUser);
        if (sysUser == null){
            throw new SmsException(ResponseCode.NO_USER);
        }else {
            //校验登录用户状态
            if (sysUser.getState() == 0){
                throw new SmsException(ResponseCode.NO_USER);
            }
            //对比密码是否一致
            if (password.equals(sysUser.getPassword())){
                //从redis查询
                if (templateRedisClient.hasKey(key)){
                    //存在 将redis数据删除
                    userResponse = templateRedisClient.get(key);
                    templateRedisClient.delete(key);
                }else {
                    //redis不存在 将数据库查询到的数据返回
                    BeanUtils.copyProperties(sysUser,userResponse);
                }
                //重新生成新的token 将数据放入redis中（二次登陆 把之前的挤掉）
                token = UUID.randomUUID().toString();
                userResponse.setToken(token);
                //查询当前登录用户的菜单权限
                List list = ssmSysUserService.userHasPower(sysUser.getId());
                userResponse.setList(list);
                //将登陆用户数据放入redis中
                templateRedisClient.set(key, userResponse, RedisClient.EXPIRE_TIME_ONE_DAY);
            }else {
                throw  new SmsException(ResponseCode.ACCOUNT_OR_PW_ERROR);
            }
        }
        return userResponse;
    }


    @Override
    public UserResponse getSmsCode(UserRequest userRequest) throws SmsException {
        UserResponse userResponse = new UserResponse();
        String code = ObjectUtils.toString((int)((Math.random()*9+1)*1000));//生成验证码
//        String msg = code+"(登录验证码，请完成验证)，如非本人操作，请忽略本短信。";
        String msg = "您的验证码是:" + code + ",请确认是您本人在操作,并注意保管,10分钟内有效";
        if(userRequest!=null&&userRequest.getGetType()==1){//1为在总店pc端获取，2为平台管理端获取
            BaseStore baseStore = ssmBaseStoreService.selectByPrimaryKey(userRequest.getStoreId());
            if (StringUtils.isNotBlank(baseStore.getSmsAccount()) && null != baseStore.getMessagingPlatform()) {
                userResponse = SmsType.sendSmsCode(baseStore.getSmsUrl(), baseStore.getSmsAccount(),
                        baseStore.getSmsPassword(), userRequest.getPhone(), msg);
            }else {
                throw  new SmsException(ResponseCode.MSG,"由于未设置门店短信平台，获取短信失败");
            }
        }else{
            userResponse = SmsType.sendSmsCode(Constant.smsUrl, Constant.smsAccount,
                    Constant.smsPassword, userRequest.getPhone(), msg);
        }

        if (userResponse.getSendSmsStatus()) {
            userResponse.setPassCode(code);
            //将验证码放入redis中
            templateRedisClient.set(getPasscodeKey(userRequest.getPhone()), userResponse,RedisClient.EXPIRE_TIME_TEN_MINUTES);
        }
        return userResponse;
    }

    @Override
    public UserResponse phoneLogin(UserRequest userRequest) throws SmsException {
        SysUser sysUser = new SysUser();
        sysUser.setMobilePhone(userRequest.getPhone());
        //查询数据库
        sysUser = dao.selectOne(sysUser);
        if (sysUser == null){
            throw new SmsException(ResponseCode.NO_USER);
        }else {
            //校验登录用户状态
            if (sysUser.getState() == 0){
                throw new SmsException(ResponseCode.NO_USER);
            }
        }
        //获取redis codeKey值
        String codeKey = getPasscodeKey(userRequest.getPhone());
        String key = getKey(sysUser.getUserNum());
        UserResponse userResponse = new UserResponse();
        String token = "";
        String passCode = userRequest.getPassCode();
        //从redis查询
        if (templateRedisClient.hasKey(codeKey)){
            //校验验证码
            if (passCode.equals(templateRedisClient.get(codeKey).getPassCode())) {
                //从redis查询
                if (templateRedisClient.hasKey(key)){
                    //存在 将redis数据删除
                    userResponse = templateRedisClient.get(key);
                    templateRedisClient.delete(key);
                }else {
                    //redis不存在 将数据库查询到的数据返回
                    BeanUtils.copyProperties(sysUser,userResponse);
                }
                // 重新生成新的token 将数据放入redis中（二次登陆 把之前的挤掉）
                token = UUID.randomUUID().toString();
                BeanUtils.copyProperties(sysUser,userResponse);
                userResponse.setToken(token);
                //查询当前登录用户的菜单权限
                List list = ssmSysUserService.userHasPower(sysUser.getId());
                userResponse.setList(list);
                templateRedisClient.set(key, userResponse, RedisClient.EXPIRE_TIME_ONE_DAY);

            }
        }else {
            //redis不存在 验证码已过期
            throw new SmsException(ResponseCode.SMS_CODE_IS_OVER);
        }
        return userResponse;
    }


    @Override
    public int changePassword(UserRequest userRequest) throws SmsException {

        SysUser sysUser = new SysUser();
        sysUser.setUserNum(userRequest.getUserNum());
        sysUser.setState(1);
        sysUser.setPassword(AESUtils.encrypt(userRequest.getPassword()));
        sysUser = dao.selectOne(sysUser);
        String newPassword = "";
        try {
            newPassword = AESUtils.encrypt(userRequest.getNewPassword());
        } catch (Exception e) {
            throw new SmsException(ResponseCode.DECRYPT_FAILED);
        }
        sysUser.setPassword(newPassword);
        int i = dao.updateByPrimaryKey(sysUser);
        if (i <= 0){
            throw new SmsException(ResponseCode.FAILED);
        }else {
            //修改成功 删除redis缓存
            String key = getKey(userRequest.getUserNum());
            templateRedisClient.delete(key);
        }
        return i;
    }

    @Override
    public UserResponse phonePassLogin(UserRequest userRequest) throws SmsException {
        SysUser sysUser = new SysUser();
        sysUser.setMobilePhone(userRequest.getPhone());

        UserResponse userResponse = new UserResponse();
        String token = "";
        String password = null;
        try {
            password = AESUtils.encrypt(userRequest.getPassword());
        } catch (Exception e) {
            throw new SmsException(ResponseCode.DECRYPT_FAILED);
        }
        //查询数据库
        sysUser = dao.selectOne(sysUser);
        if (sysUser == null){
            throw new SmsException(ResponseCode.NO_USER);
        }else {
            //获取redis key值
            String key = sysUser.getUserNum();
            //对比密码是否一致
            if (password.equals(sysUser.getPassword())){
                //从redis查询
                if (templateRedisClient.hasKey(key)){
                    //存在 将redis数据删除
                    userResponse = templateRedisClient.get(key);
                    templateRedisClient.delete(key);
                }else {
                    //redis不存在 将数据库查询到的数据返回
                    BeanUtils.copyProperties(sysUser,userResponse);
                }
                //重新生成新的token 将数据放入redis中（二次登陆 把之前的挤掉）
                token = UUID.randomUUID().toString();
                userResponse.setToken(token);
                //查询当前登录用户的菜单权限
                List list = ssmSysUserService.userHasPower(sysUser.getId());
                userResponse.setList(list);
                //将登陆用户数据放入redis中
                templateRedisClient.set(key, userResponse, RedisClient.EXPIRE_TIME_ONE_DAY);
            }else {
                throw  new SmsException(ResponseCode.ACCOUNT_OR_PW_ERROR);
            }
        }
        return userResponse;
    }


    @Override
    public void logout(UserRequest userRequest,HttpSession session) throws SmsException {
        //清除redis
        if (templateRedisClient.hasKey(getKey(userRequest.getUserNum()))){
            templateRedisClient.delete(getKey(userRequest.getUserNum()));
        }
        //清除session
        session.invalidate();

    }

    public String getKey(String userNum){
        String key = "";
        if (StringUtils.isNotBlank(userNum)){
            key = Constant.userKey + userNum;
        }
        return key;
    }

    public String getPasscodeKey(String phone){
        String key = "";
        if (StringUtils.isNotBlank(phone)){
            key = Constant.userPasscode + phone;
        }
        return key;
    }

    public  UserResponse getAuth(UserResponse userResponse){
        //查询用户角色表
        RoleUserRequest roleUserRequest = new RoleUserRequest();
        roleUserRequest.setUserId(userResponse.getId());
        List<SysRoleUser> roleUserList = ssmSysRoleUserService.roleUserList(roleUserRequest);
        List<SysMenuPower> totalList = new ArrayList<>();
        //查询角色权限表
        for (SysRoleUser sysRoleUser : roleUserList) {
            MenuPowerRequest menuPowerRequest = new MenuPowerRequest();
            menuPowerRequest.setRoleId(sysRoleUser.getRoleId());
            List<SysMenuPower> list = ssmSysMenuPowerService.listByRole(menuPowerRequest);
            totalList.addAll(list);
        }
        userResponse.setList(totalList);

        return  userResponse;
    }
}
