package com.jeequan.jeepay.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.model.security.JeeUserDetails;
import com.jeequan.jeepay.core.utils.StringKit;
import com.jeequan.jeepay.db.entity.SysUserAuth;
import com.jeequan.jeepay.db.entity.SysUserEntity;
import com.jeequan.jeepay.service.mapper.SysUserAuthMapper;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * <p>
 * 操作员认证表 服务实现类
 * </p>
 *
 * @author [mybatis plus generator]
 * @since 2020-06-13
 */
@Service
public class SysUserAuthService extends ServiceImpl<SysUserAuthMapper, SysUserAuth> {

    @Autowired
    private SysConfigService sysConfigService;

    @Autowired
    private SysUserService sysUserService;

    /**
     * 根据登录信息查询用户认证信息
     **/
    public SysUserAuth selectByLogin(String identifier, Byte identityType, String sysType) {
        return baseMapper.selectByLogin(identifier, identityType, sysType);
    }

    /**
     * 添加用户认证表
     **/
    @Transactional
    public void addUserAuthDefault(Long userId, String loginUserName, String telPhone, String pwdRaw, String sysType) {

        // 若为空， 那么使用系统默认密码
        String passwordEncode = new BCryptPasswordEncoder().encode(ObjectUtils.firstNonNull(pwdRaw, sysConfigService.queryDefaultPasswordRaw()));

        String salt = StringKit.getUUID(6); //6位随机数

//        /** 用户名登录方式 */
        SysUserAuth record = new SysUserAuth();
        record.setUserId(userId);
        record.setCredential(passwordEncode);
        record.setSalt(salt);
        record.setSysType(sysType);
        record.setIdentityType(CS.AUTH_TYPE.LOGIN_USER_NAME);
        record.setIdentifier(loginUserName);
        save(record);

        /** 手机号登录方式 */
        record = new SysUserAuth();
        record.setUserId(userId);
        record.setCredential(passwordEncode);
        record.setSalt(salt);
        record.setSysType(sysType);
        record.setIdentityType(CS.AUTH_TYPE.TELPHONE);
        record.setIdentifier(telPhone);
        save(record);
    }


    /**
     * 重置密码,  如果 resetPassword = true && newPwd = null 那么使用的系统默认密码。
     */
    @Transactional(rollbackFor = Exception.class)
    public void resetAuthInfo(Long resetUserId, String authLoginUserName, String telphone, boolean resetPassword, String newPwd, String sysType) {

        //更改登录用户名
//        if(StringKit.isNotEmpty(authLoginUserName)){
//            SysUserAuth updateRecord = new SysUserAuth();
//            updateRecord.setIdentifier(authLoginUserName);
//            update(updateRecord, SysUserAuth.gw().eq(SysUserAuth::getSystem, system).eq(SysUserAuth::getUserId, resetUserId).eq(SysUserAuth::getIdentityType, CS.AUTH_TYPE.LOGIN_USER_NAME));
//        }
        //更新手机号
        if (StringUtils.isNotEmpty(telphone)) {
            List<SysUserAuth> list = lambdaQuery().eq(SysUserAuth::getIdentifier, telphone)
                    .eq(SysUserAuth::getIdentityType, CS.AUTH_TYPE.TELPHONE)
                    .eq(SysUserAuth::getSysType, sysType).list();

            if (!list.isEmpty() && !(list.get(0).getUserId().equals(resetUserId))) {
                throw new BizException("当前手机号已存在， 请修改");
            }

            SysUserAuth updateRecord = new SysUserAuth();
            updateRecord.setIdentifier(telphone);
            update(updateRecord, SysUserAuth.gw().eq(SysUserAuth::getSysType, sysType).eq(SysUserAuth::getUserId, resetUserId).eq(SysUserAuth::getIdentityType, CS.AUTH_TYPE.TELPHONE));
        }

        //更改密码
        if (resetPassword) {

            // 若为空， 那么使用系统默认密码
            String passwordEncode = new BCryptPasswordEncoder().encode(StringUtils.defaultString(newPwd, sysConfigService.queryDefaultPasswordRaw()));

            //根据当前用户ID 查询出用户的所有认证记录
            List<SysUserAuth> authList = list(SysUserAuth.gw().eq(SysUserAuth::getSysType, sysType).eq(SysUserAuth::getUserId, resetUserId));
            for (SysUserAuth auth : authList) {
                if (StringUtils.isEmpty(auth.getSalt())) { //可能为其他登录方式， 不存在salt
                    continue;
                }
                SysUserAuth updateRecord = new SysUserAuth();
                updateRecord.setAuthId(auth.getAuthId());
                updateRecord.setCredential(passwordEncode);
                updateById(updateRecord);
            }

            // 更新密码过期时间
            SysUserEntity updateRecord = new SysUserEntity();
            updateRecord.setSysUserId(resetUserId);
            sysUserService.resetSysUserPwdTime(updateRecord, newPwd);
            sysUserService.updateById(updateRecord);
        }
    }


    /**
     * 查询当前用户密码是否正确
     */
    public boolean validateCurrentUserPwd(String pwdRaw) {

        //根据当前用户ID + 认证方式为 登录用户名的方式 查询一条记录
        SysUserAuth auth = getOne(SysUserAuth.gw()
                .eq(SysUserAuth::getUserId, JeeUserDetails.getCurrentUserDetails().getSysUser().getSysUserId())
                .eq(SysUserAuth::getIdentityType, CS.AUTH_TYPE.LOGIN_USER_NAME)
        );
        if (auth != null && new BCryptPasswordEncoder().matches(pwdRaw, auth.getCredential())) {
            return true;
        }

        return false;
    }


}
