package com.ruoyi.framework.web.service;

import cn.hutool.core.util.StrUtil;
import com.ruoyi.buyerapi.domain.BuyerCompanyInfo;
import com.ruoyi.buyerapi.domain.Member;
import com.ruoyi.buyerapi.mapper.BuyerUserMapper;
import com.ruoyi.buyerapi.service.IBuyerCompanyInfoService;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.enums.UserStatus;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.exception.user.UserPasswordNotMatchException;
import com.ruoyi.common.utils.*;
import com.ruoyi.common.utils.ip.IpUtils;
import com.ruoyi.commonapi.cache.CachePrefix;
import com.ruoyi.commonapi.enums.ResultCode;
import com.ruoyi.framework.manager.AsyncManager;
import com.ruoyi.framework.manager.factory.AsyncFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

/**
 * 会员登录注册接口业务层实现
 *
 * @author Chopper
 * @since 2021-03-29 14:10:16
 */
@Service
public class MemberService {

    private static final Logger log = LoggerFactory.getLogger(MemberService.class);

    @Autowired
    private TokenService tokenService;

    /** 缓存 **/
    @Autowired
    private RedisCache redisCache;

    @Autowired
    private BuyerUserMapper buyerUserMapper;

    @Autowired
    private BuyerPermissionService buyerPermissionService;

    @Autowired
    private IBuyerCompanyInfoService buyerCompanyInfoService;

    public SysUser getUserInfo() {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        if (loginUser != null) {
            return buyerUserMapper.selectLoginInfo(SecurityUtils.getUsername());
        }
        throw new ServiceException(ResultCode.USER_NOT_LOGIN.message());
    }

    public SysUser findByMobile(String mobile) {
        Member m = new Member();
        m.setMobile(mobile);
        SysUser user = buyerUserMapper.checkPhoneUnique(mobile);
        if (user == null) {
            throw new ServiceException(ResultCode.USER_NOT_PHONE.message());
        }
        return user;
    }

    /**
     * 用户名或密码登录
     **/
    public String usernameLogin(String username, String password) {
        SysUser user = this.findMember(username);
        try
        {
            validateLoginInfo(user, username, password);
        }
        catch (Exception e)
        {
            if (e instanceof BadCredentialsException)
            {
                AsyncManager.me().execute(AsyncFactory.recordLogininfor(Constants.SYS_CUSTOMER, username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match")));
                throw new UserPasswordNotMatchException();
            }
            else
            {
                AsyncManager.me().execute(AsyncFactory.recordLogininfor(Constants.SYS_CUSTOMER, username, Constants.LOGIN_FAIL, e.getMessage()));
                throw new ServiceException(e.getMessage());
            }
        }
        // 判断当前用户的公司会员是否被停用
        if(StrUtil.isNotEmpty(user.getCompanyId())){
            BuyerCompanyInfo buyerCompanyInfo = buyerCompanyInfoService.selectBuyerCompanyInfoById(user.getCompanyId());
            if("1".equals(buyerCompanyInfo.getAccountStatus())) {
                throw new ServiceException("当前会员已被停用请联系管理员！");
            }
        }

        // 查询当前用户是否为超级管理员
        BuyerCompanyInfo buyerCompanyInfo = buyerCompanyInfoService.selectBuyerCompanyInfoByUserId(user.getUserId());
        if(null != buyerCompanyInfo && StrUtil.isNotEmpty(buyerCompanyInfo.getId())){
            user.setBuyerAdmin(true);
        }

        AsyncManager.me().execute(AsyncFactory.recordLogininfor(Constants.SYS_CUSTOMER, username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));
        LoginUser loginUser = new LoginUser(user.getUserId(), user.getDeptId(), user, buyerPermissionService.getMenuPermission(user));
        recordLoginInfo(loginUser.getUserId());
        // 生成token
        return tokenService.createToken(loginUser);
    }

    /**
     * 校验登录信息
     **/
    private void validateLoginInfo(SysUser user, String username, String password){
        //判断用户是否存在
        if (StringUtils.isNull(user))
        {
            log.info("登录用户：{} 不存在.", username);
            throw new com.ruoyi.common.exception.ServiceException("登录用户：" + username + " 不存在");
        }
        else if (UserStatus.DELETED.getCode().equals(user.getDelFlag()))
        {
            log.info("登录用户：{} 已被删除.", username);
            throw new com.ruoyi.common.exception.ServiceException("对不起，您的账号：" + username + " 已被删除");
        }
        else if (UserStatus.DISABLE.getCode().equals(user.getStatus()))
        {
            log.info("登录用户：{} 已被停用.", username);
            throw new com.ruoyi.common.exception.ServiceException("对不起，您的账号：" + username + " 已停用");
        }
        //判断密码是否输入正确
        if (!new BCryptPasswordEncoder().matches(password, user.getPassword())) {
            throw new ServiceException(ResultCode.USER_PASSWORD_ERROR.message());
        }
    }

    /**
     * 记录登录信息
     *
     * @param userId 用户ID
     */
    public void recordLoginInfo(Long userId)
    {
        SysUser sysUser = new SysUser();
        sysUser.setUserId(userId);
        sysUser.setLoginIp(IpUtils.getIpAddr(ServletUtils.getRequest()));
        sysUser.setLoginDate(DateUtils.getNowDate());
        buyerUserMapper.updateUser(sysUser);
    }

    /**
     * 传递手机号或者用户名
     *
     * @param userName 手机号或者用户名
     * @return 会员信息
     */
    private SysUser findMember(String userName) {
        SysUser member = buyerUserMapper.selectLoginInfo(userName);
        return member;
    }

    /**
    * 手机号登录
    **/
    public String mobilePhoneLogin(String mobilePhone) {
        SysUser user = buyerUserMapper.checkPhoneUnique(mobilePhone);
        //如果手机号不存在则自动注册用户
        if (user == null) {
            user = new SysUser();
            user.setPhonenumber(mobilePhone);
            user.setUserName(mobilePhone);
            user.setNickName(mobilePhone);
            buyerUserMapper.insertUser(user);
        }
        AsyncManager.me().execute(AsyncFactory.recordLogininfor(Constants.SYS_CUSTOMER, mobilePhone,
                Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));
        LoginUser loginUser = new LoginUser(user.getUserId(), user.getDeptId(), user, buyerPermissionService.getMenuPermission(user));
        recordLoginInfo(loginUser.getUserId());
        return tokenService.createToken(loginUser);
    }

    /**
     * 注册
     **/
    public void register(String userName, String password, String mobilePhone) {
        SysUser user = buyerUserMapper.checkPhoneUnique(mobilePhone);
        //判断手机号是否存在
        if (user != null) {
            throw new ServiceException(ResultCode.USER_EXIST.message());
        }
        user = new SysUser();
        user.setPhonenumber(mobilePhone);
        user.setUserName(userName);
        user.setNickName(userName);
        user.setPassword(SecurityUtils.encryptPassword(password));
        buyerUserMapper.insertUser(user);
    }
}
