package com.njzscloud.dispose.sys.user.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.IService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.njzscloud.common.core.ex.Exceptions;
import com.njzscloud.common.security.util.EncryptUtil;
import com.njzscloud.dispose.sys.user.mapper.UserAccountMapper;
import com.njzscloud.dispose.sys.user.pojo.entity.UserAccountEntity;
import com.njzscloud.dispose.sys.user.pojo.param.AddUserAccountParam;
import com.njzscloud.dispose.sys.user.pojo.param.ModifyPasswdParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;

/**
 * 用户账号信息表
 */
@Slf4j
@Service
public class UserAccountService extends ServiceImpl<UserAccountMapper, UserAccountEntity> implements IService<UserAccountEntity> {

    /**
     * 新增
     */
    public void add(AddUserAccountParam addUserAccountParam) {
        String username = addUserAccountParam.getUsername();
        String secret = addUserAccountParam.getSecret();
        String email = addUserAccountParam.getEmail();
        String phone = addUserAccountParam.getPhone();
        String wechatOpenid = addUserAccountParam.getWechatOpenid();
        String wechatUnionid = addUserAccountParam.getWechatUnionid();

        List<UserAccountEntity> oldSysUserList = this.list(Wrappers.<UserAccountEntity>lambdaQuery()
            .eq(StrUtil.isNotBlank(username), UserAccountEntity::getUsername, username)
            .or().eq(StrUtil.isNotBlank(phone), UserAccountEntity::getPhone, phone)
            .or(StrUtil.isNotBlank(wechatOpenid), it -> it
                .eq(UserAccountEntity::getWechatOpenid, wechatOpenid)
                .eq(StrUtil.isNotBlank(wechatUnionid), UserAccountEntity::getWechatUnionid, wechatUnionid)
            )
        );

        if (StrUtil.isNotBlank(username)) {
            Assert.notBlank(secret, () -> Exceptions.clierr("密码不能为空"));
            Assert.isTrue(oldSysUserList.stream().noneMatch(it -> username.equals(it.getUsername())), () -> Exceptions.exception("用户名【{}】已被使用", username));
        }
        if (StrUtil.isNotBlank(phone)) {
            Assert.notBlank(secret, () -> Exceptions.clierr("密码不能为空"));
            Assert.isTrue(oldSysUserList.stream().noneMatch(it -> phone.equals(it.getPhone())), () -> Exceptions.exception("手机号【{}】已被使用", phone));
        }
        if (StrUtil.isNotBlank(wechatOpenid)) {
            Assert.isTrue(oldSysUserList.stream().noneMatch(it -> {
                String unionid = it.getWechatUnionid();
                return wechatOpenid.equals(it.getWechatOpenid()) && (StrUtil.isBlank(wechatUnionid) || wechatUnionid.equals(unionid));
            }), () -> Exceptions.exception("该微信账号已被使用"));
        }

        UserAccountEntity userAccountEntity = BeanUtil.copyProperties(addUserAccountParam, UserAccountEntity.class)
            .setSecret(EncryptUtil.encrypt(secret))
            .setRegdate(LocalDateTime.now());
        this.save(userAccountEntity);
    }

    /**
     * 删除
     */
    @Transactional(rollbackFor = Exception.class)
    public void delByUserIds(List<Long> ids) {
        this.remove(Wrappers.<UserAccountEntity>lambdaQuery().in(UserAccountEntity::getUserId, ids));
    }

    /**
     * 修改密码
     */
    @Transactional(rollbackFor = Exception.class)
    public void modifyPasswd(Long userId, ModifyPasswdParam modifyPasswdParam) {
        UserAccountEntity accountEntity = this.getOne(Wrappers.<UserAccountEntity>lambdaQuery().eq(UserAccountEntity::getUserId, userId));
        Assert.notNull(accountEntity, () -> Exceptions.clierr("未查询到用户信息"));
        boolean matches = EncryptUtil.matches(modifyPasswdParam.getOldPasswd(), accountEntity.getSecret());
        Assert.isTrue(matches, () -> Exceptions.exception("密码错误"));
        String newPasswd = EncryptUtil.encrypt(modifyPasswdParam.getNewPasswd());

        Long id = accountEntity.getId();

        this.updateById(new UserAccountEntity()
            .setId(id)
            .setSecret(newPasswd)
        );
    }
}
