package org.dromara.system.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.constant.CacheNames;
import org.dromara.common.core.constant.TenantConstants;
import org.dromara.common.core.constant.UserConstants;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.SpringUtils;
import org.dromara.common.core.utils.StreamUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.mybatis.helper.DataBaseHelper;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.system.domain.*;
import org.dromara.system.domain.bo.SysRoleBo;
import org.dromara.system.domain.bo.SysUserBo;
import org.dromara.system.domain.vo.SysPostVo;
import org.dromara.system.domain.vo.SysRoleVo;
import org.dromara.system.domain.vo.SysUserExportVo;
import org.dromara.system.domain.vo.SysUserVo;
import org.dromara.system.mapper.*;
import org.dromara.system.service.ISysUserService;
import org.dromara.system.zwy.client.HmacClient;
import org.dromara.system.zwy.utils.ObjectHashGenerator;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 用户 业务层处理
 *
 * @author Lion Li
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class SysUserServiceImpl implements ISysUserService {

    private final SysUserMapper baseMapper;
    private final SysDeptMapper deptMapper;
    private final SysRoleMapper roleMapper;
    private final SysPostMapper postMapper;
    private final SysUserRoleMapper userRoleMapper;
    private final SysUserPostMapper userPostMapper;

    private final HmacClient hmacClient;

    @Override
    public TableDataInfo<SysUserVo> selectPageUserList(SysUserBo user, PageQuery pageQuery) {
        Page<SysUserVo> page = baseMapper.selectPageUserList(pageQuery.build(), this.buildQueryWrapper(user));
        return TableDataInfo.build(page);
    }

    /**
     * 根据条件分页查询用户列表
     *
     * @param user 用户信息
     * @return 用户信息集合信息
     */
    @Override
    public List<SysUserExportVo> selectUserExportList(SysUserBo user) {
        return baseMapper.selectUserExportList(this.buildQueryWrapper(user));
    }

    private Wrapper<SysUser> buildQueryWrapper(SysUserBo user) {
        Map<String, Object> params = user.getParams();
        QueryWrapper<SysUser> wrapper = Wrappers.query();
        wrapper.eq("u.del_flag", UserConstants.USER_NORMAL)
            .eq(ObjectUtil.isNotNull(user.getUserId()), "u.user_id", user.getUserId())
            .like(StringUtils.isNotBlank(user.getUserName()), "u.user_name", user.getUserName())
            .eq(StringUtils.isNotBlank(user.getStatus()), "u.status", user.getStatus())
            .like(StringUtils.isNotBlank(user.getPhonenumber()), "u.phonenumber", user.getPhonenumber())
            .between(params.get("beginTime") != null && params.get("endTime") != null,
                "u.create_time", params.get("beginTime"), params.get("endTime"))
            .and(ObjectUtil.isNotNull(user.getDeptId()), w -> {
                List<SysDept> deptList = deptMapper.selectList(new LambdaQueryWrapper<SysDept>()
                    .select(SysDept::getDeptId)
                    .apply(DataBaseHelper.findInSet(user.getDeptId(), "ancestors")));
                List<Long> ids = StreamUtils.toList(deptList, SysDept::getDeptId);
                ids.add(user.getDeptId());
                w.in("u.dept_id", ids);
            }).orderByAsc("u.user_id");
        if (StringUtils.isNotBlank(user.getExcludeUserIds())) {
            wrapper.notIn("u.user_id", StringUtils.splitList(user.getExcludeUserIds()));
        }
        return wrapper;
    }

    /**
     * 根据条件分页查询已分配用户角色列表
     *
     * @param user 用户信息
     * @return 用户信息集合信息
     */
    @Override
    public TableDataInfo<SysUserVo> selectAllocatedList(SysUserBo user, PageQuery pageQuery) {
        QueryWrapper<SysUser> wrapper = Wrappers.query();
        wrapper.eq("u.del_flag", UserConstants.USER_NORMAL)
            .eq(ObjectUtil.isNotNull(user.getRoleId()), "r.role_id", user.getRoleId())
            .like(StringUtils.isNotBlank(user.getUserName()), "u.user_name", user.getUserName())
            .eq(StringUtils.isNotBlank(user.getStatus()), "u.status", user.getStatus())
            .like(StringUtils.isNotBlank(user.getPhonenumber()), "u.phonenumber", user.getPhonenumber())
            .orderByAsc("u.user_id");
        Page<SysUserVo> page = baseMapper.selectAllocatedList(pageQuery.build(), wrapper);
        return TableDataInfo.build(page);
    }

    /**
     * 根据条件分页查询未分配用户角色列表
     *
     * @param user 用户信息
     * @return 用户信息集合信息
     */
    @Override
    public TableDataInfo<SysUserVo> selectUnallocatedList(SysUserBo user, PageQuery pageQuery) {
        List<Long> userIds = userRoleMapper.selectUserIdsByRoleId(user.getRoleId());
        QueryWrapper<SysUser> wrapper = Wrappers.query();
        wrapper.eq("u.del_flag", UserConstants.USER_NORMAL)
            .and(w -> w.ne("r.role_id", user.getRoleId()).or().isNull("r.role_id"))
            .notIn(CollUtil.isNotEmpty(userIds), "u.user_id", userIds)
            .like(StringUtils.isNotBlank(user.getUserName()), "u.user_name", user.getUserName())
            .like(StringUtils.isNotBlank(user.getPhonenumber()), "u.phonenumber", user.getPhonenumber())
            .orderByAsc("u.user_id");
        Page<SysUserVo> page = baseMapper.selectUnallocatedList(pageQuery.build(), wrapper);
        return TableDataInfo.build(page);
    }

    /**
     * 通过用户名查询用户
     *
     * @param userName 用户名
     * @return 用户对象信息
     */
    @Override
    public SysUserVo selectUserByUserName(String userName) {
        return baseMapper.selectVoOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getUserName, userName));
    }

    /**
     * 通过手机号查询用户
     *
     * @param phonenumber 手机号
     * @return 用户对象信息
     */
    @Override
    public SysUserVo selectUserByPhonenumber(String phonenumber) {
        return baseMapper.selectVoOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getPhonenumber, phonenumber));
    }

    /**
     * 通过用户ID查询用户
     *
     * @param userId 用户ID
     * @return 用户对象信息
     */
    @Override
    public SysUserVo selectUserById(Long userId) {
        SysUserVo user = baseMapper.selectVoById(userId);
        if (ObjectUtil.isNull(user)) {
            return user;
        }

        List<SysRoleVo> sysRoleVos = roleMapper.selectRolesByUserId(user.getUserId());
        user.setRoles(sysRoleVos);
        List<String> roleKye = sysRoleVos.stream().map(SysRoleVo::getRoleKey).toList();
        if(roleKye.contains(TenantConstants.EXPERT_ROLE_KEY)){
            try {
                Long expertStatus = baseMapper.getExpertStatus(userId);
                user.setCertification(null != expertStatus);
            }catch (Exception e) {
                e.printStackTrace();
            }
        }else {
            user.setCertification(true);
        }
        return user;
    }

    /**
     * 通过用户ID串查询用户
     *
     * @param userIds 用户ID串
     * @param deptId  部门id
     * @return 用户列表信息
     */
    @Override
    public List<SysUserVo> selectUserByIds(List<Long> userIds, Long deptId) {
        return baseMapper.selectUserList(new LambdaQueryWrapper<SysUser>()
            .select(SysUser::getUserId, SysUser::getUserName, SysUser::getNickName, SysUser::getEmail, SysUser::getPhonenumber)            .eq(SysUser::getStatus, UserConstants.USER_NORMAL)
            .eq(ObjectUtil.isNotNull(deptId), SysUser::getDeptId, deptId)
            .in(CollUtil.isNotEmpty(userIds), SysUser::getUserId, userIds));
    }

    @Override
    public List<SysUserVo> selectListByUserName(List<String> userNames) {
        return baseMapper.selectUserList(new LambdaQueryWrapper<SysUser>()
            .select(SysUser::getUserId, SysUser::getUserName, SysUser::getNickName, SysUser::getEmail, SysUser::getPhonenumber)            .eq(SysUser::getStatus, UserConstants.USER_NORMAL)
            .in(CollUtil.isNotEmpty(userNames), SysUser::getUserName, userNames));
    }

    /**
     * 查询用户所属角色组
     *
     * @param userId 用户ID
     * @return 结果
     */
    @Override
    public String selectUserRoleGroup(Long userId) {
        List<SysRoleVo> list = roleMapper.selectRolesByUserId(userId);
        if (CollUtil.isEmpty(list)) {
            return StringUtils.EMPTY;
        }
        return StreamUtils.join(list, SysRoleVo::getRoleName);
    }

    /**
     * 查询用户所属岗位组
     *
     * @param userId 用户ID
     * @return 结果
     */
    @Override
    public String selectUserPostGroup(Long userId) {
        List<SysPostVo> list = postMapper.selectPostsByUserId(userId);
        if (CollUtil.isEmpty(list)) {
            return StringUtils.EMPTY;
        }
        return StreamUtils.join(list, SysPostVo::getPostName);
    }

    /**
     * 校验用户名称是否唯一
     *
     * @param user 用户信息
     * @return 结果
     */
    @Override
    public boolean checkUserNameUnique(SysUserBo user) {
        boolean exist = baseMapper.exists(new LambdaQueryWrapper<SysUser>()
            .eq(SysUser::getUserName, user.getUserName())
            .ne(ObjectUtil.isNotNull(user.getUserId()), SysUser::getUserId, user.getUserId()));
        return !exist;
    }

    /**
     * 校验手机号码是否唯一
     *
     * @param user 用户信息
     */
    @Override
    public boolean checkPhoneUnique(SysUserBo user) {
        boolean exist = baseMapper.exists(new LambdaQueryWrapper<SysUser>()
            .eq(SysUser::getPhonenumber, user.getPhonenumber())
            .ne(ObjectUtil.isNotNull(user.getUserId()), SysUser::getUserId, user.getUserId()));
        return !exist;
    }

    /**
     * 校验email是否唯一
     *
     * @param user 用户信息
     */
    @Override
    public boolean checkEmailUnique(SysUserBo user) {
        boolean exist = baseMapper.exists(new LambdaQueryWrapper<SysUser>()
            .eq(SysUser::getEmail, user.getEmail())
            .ne(ObjectUtil.isNotNull(user.getUserId()), SysUser::getUserId, user.getUserId()));
        return !exist;
    }

    /**
     * 校验用户是否允许操作
     *
     * @param userId 用户ID
     */
    @Override
    public void checkUserAllowed(Long userId) {

        if (LoginHelper.getUserId().equals(userId)) {
            return;
        }
        if (ObjectUtil.isNotNull(userId) && LoginHelper.isSuperAdmin(userId)) {
            throw new ServiceException("不允许操作超级管理员用户");
        }
    }

    /**
     * 校验用户是否有数据权限
     *
     * @param userId 用户id
     */
    @Override
    public void checkUserDataScope(Long userId) {
        if (ObjectUtil.isNull(userId)) {
            return;
        }
        if (LoginHelper.isSuperAdmin()) {
            return;
        }
        // 如果是操作自己，就放行
        if (LoginHelper.getUserId().equals(userId)) {
            return;
        }
        if (baseMapper.countUserById(userId) == 0) {
            throw new ServiceException("没有权限访问用户数据！");
        }
    }

    /**
     * 新增保存用户信息
     *
     * @param user 用户信息
     * @return 结果
     */
/*    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insertUser(SysUserBo user) {
        SysUser sysUser = MapstructUtils.convert(user, SysUser.class);
        // 新增用户信息
        int rows = baseMapper.insert(sysUser);
        user.setUserId(sysUser.getUserId());
        // 新增用户岗位关联
        insertUserPost(user, false);
        // 新增用户与角色管理
        insertUserRole(user, false);
        return rows;
    }*/
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insertUser(SysUserBo userBo) {
        // 1. 插入用户主表
        SysUser sysUser = MapstructUtils.convert(userBo, SysUser.class);
        int rows = baseMapper.insert(sysUser);
        userBo.setUserId(sysUser.getUserId());

        // 2. 插入岗位和角色桥表
        insertUserPost(userBo, false);
        insertUserRole(userBo, false);

        // 3. 查询角色和桥表用于生成 HMAC
        try {
            // 查询用户角色桥表
            List<SysUserRole> userRoles = userRoleMapper.selectList(
                new LambdaQueryWrapper<SysUserRole>()
                    .eq(SysUserRole::getUserId, sysUser.getUserId())
            );

            // 查询角色信息
            List<Long> roleIds = userRoles.stream()
                .map(SysUserRole::getRoleId)
                .distinct()
                .toList();

            List<SysRoleVo> roles = roleIds.isEmpty() ? Collections.emptyList() : roleMapper.selectRolesByUserId(sysUser.getUserId());

            SysUser dbUser = baseMapper.selectById(sysUser.getUserId());
            // 构建组合对象用于生成哈希
            Map<String, Object> composite = new HashMap<>();
            composite.put("user", dbUser);
            composite.put("userRoles", userRoles);
            //composite.put("roles", roles);

            // 生成哈希字符串
            String hash = ObjectHashGenerator.generateHash(composite);
            String base64 = Base64.getEncoder().encodeToString(hash.getBytes(StandardCharsets.UTF_8));

            // 调用 HMAC 接口生成签名
            String hmac = hmacClient.calculateHmac(base64);
//            String hmac = base64;
            sysUser.setHmac(hmac);

            // 更新用户表中的 HMAC 字段
            baseMapper.updateById(sysUser);

            log.info("用户创建成功，HMAC 已生成。用户ID: {}, HMAC: {}", sysUser.getUserId(), hmac);
        } catch (Exception e) {
            log.error("生成用户 HMAC 失败，用户ID: {}", sysUser.getUserId(), e);
        }

        return rows;
    }

    /**
     * 注册用户信息
     *
     * @param user 用户信息
     * @return 结果
     */
    @Override
    public boolean registerUser(SysUserBo user, String tenantId) {
        user.setCreateBy(0L);
        user.setUpdateBy(0L);
        SysUser sysUser = MapstructUtils.convert(user, SysUser.class);
        sysUser.setTenantId(tenantId);
        baseMapper.insert(sysUser);
        // 新增用户与角色管理
        //insertUserRole(user.getUserId(), tenantId,true);
        return true;
    }

    @Override
    public boolean registerUser(List<SysUserBo> userList) {
        List<SysUser> sysUsers = BeanUtil.copyToList(userList, SysUser.class);
        for (SysUser user : sysUsers) {
            user.setCreateBy(0L);
            user.setUpdateBy(0L);
            user.setPasswordUpdateTime(new Date());
        }
        baseMapper.insertBatch(sysUsers);
        insertUserRole(sysUsers, false);
        return false;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean registerExpertUser(List<SysUserBo> sysUserBoList, String tenantId) {
        List<SysUser> sysUsers = BeanUtil.copyToList(sysUserBoList, SysUser.class);
        for (SysUser user : sysUsers) {
            user.setCreateBy(0L);
            user.setUpdateBy(0L);
        }
        baseMapper.insertBatch(sysUsers);
        insertUserRole(sysUsers, true,tenantId);
        return false;
    }

    /**
     * 修改保存用户信息
     *
     * @param userBo 用户信息
     * @return 结果
     */
/*    @Override
    @CacheEvict(cacheNames = CacheNames.SYS_NICKNAME, key = "#user.userId")
    @Transactional(rollbackFor = Exception.class)
    public int updateUser(SysUserBo user) {
        // 新增用户与角色管理
        insertUserRole(user, true);
        // 新增用户与岗位管理
        insertUserPost(user, true);
        SysUser sysUser = MapstructUtils.convert(user, SysUser.class);
        // 防止错误更新后导致的数据误删除
        int flag = baseMapper.updateById(sysUser);
        if (flag < 1) {
            throw new ServiceException("修改用户" + user.getUserName() + "信息失败");
        }
        return flag;
    }*/
    @Override
    @CacheEvict(cacheNames = CacheNames.SYS_NICKNAME, key = "#userBo != null ? #userBo.userId : null")
    @Transactional(rollbackFor = Exception.class)
    public int updateUser(SysUserBo userBo) {
        // 1. 更新用户-角色关联关系
        insertUserRole(userBo, true);
        // 2. 更新用户-岗位关联关系
        insertUserPost(userBo, true);

        // 3. 更新用户主表信息
        SysUser sysUser = MapstructUtils.convert(userBo, SysUser.class);
        int flag = baseMapper.updateById(sysUser);
        if (flag < 1) {
            throw new ServiceException("修改用户" + userBo.getUserName() + "信息失败");
        }

        // 4. 重新生成 HMAC
        try {
            List<SysUserRole> userRoles = userRoleMapper.selectList(
                new LambdaQueryWrapper<SysUserRole>()
                    .eq(SysUserRole::getUserId, sysUser.getUserId())
            );

            List<Long> roleIds = userRoles.stream()
                .map(SysUserRole::getRoleId)
                .distinct()
                .toList();

            List<SysRoleVo> roles = roleIds.isEmpty() ? Collections.emptyList() : roleMapper.selectRolesByUserId(sysUser.getUserId());

            SysUser dbUser = baseMapper.selectById(sysUser.getUserId());
            // 构造组合数据对象（支持深层字段统一处理）
            Map<String, Object> composite = new HashMap<>();
            composite.put("user", dbUser);
            composite.put("userRoles", userRoles);
            //composite.put("roles", roles);

            String hash = ObjectHashGenerator.generateHash(composite);
            String base64 = Base64.getEncoder().encodeToString(hash.getBytes(StandardCharsets.UTF_8));

            String hmac = hmacClient.calculateHmac(base64);
//            String hmac = base64;
            sysUser.setHmac(hmac);

            baseMapper.updateById(sysUser); // 更新 HMAC 字段
            log.info("用户更新成功，HMAC 已刷新，用户ID: {}", sysUser.getUserId());
        } catch (Exception e) {
            log.error("更新用户 HMAC 失败，用户ID: {}", sysUser.getUserId(), e);
        }

        return flag;
    }

    @Override
    public Object selectSysUserById(Long userId) {
        if (userId == null) {
            return null;
        }
        SysUser sysUser = baseMapper.selectById(userId);
        if (sysUser == null) {
            return null;
        }

        List<SysUserPost> userPosts = userPostMapper.selectList(
            new LambdaQueryWrapper<SysUserPost>().eq(SysUserPost::getUserId, userId)
        );

        List<SysUserRole> userRoles = userRoleMapper.selectList(
            new LambdaQueryWrapper<SysUserRole>().eq(SysUserRole::getUserId, userId)
        );

        List<Long> roleIds = userRoles.stream()
            .map(SysUserRole::getRoleId)
            .distinct()
            .toList();

        //List<SysRoleVo> roles = roleIds.isEmpty() ? Collections.emptyList() : roleMapper.selectRolesByUserId(sysUser.getUserId());

        Map<String, Object> composite = new HashMap<>();
        composite.put("user", sysUser);
        composite.put("userRoles", userRoles);
        //composite.put("roles", roles);

        return composite;

    }

    @Override
    public void updateUserHmac(SysUser update) {
        baseMapper.updateHmacById(update);
    }

    /**
     * 用户授权角色
     *
     * @param userId  用户ID
     * @param roleIds 角色组
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void insertUserAuth(Long userId, Long[] roleIds) {
        insertUserRole(userId, roleIds, true);
    }

    /**
     * 修改用户状态
     *
     * @param userId 用户ID
     * @param status 帐号状态
     * @return 结果
     */
    @Override
    public int updateUserStatus(Long userId, String status) {
        return baseMapper.update(null,
            new LambdaUpdateWrapper<SysUser>()
                .set(SysUser::getStatus, status)
                .eq(SysUser::getUserId, userId));
    }

    @Override
    public int updateUserStatus(Long userId) {
        return baseMapper.update(null,
            new LambdaUpdateWrapper<SysUser>()
                .set(SysUser::getSourceTenant, 1)
                .eq(SysUser::getUserId, userId));
    }

    /**
     * 修改用户基本信息
     *
     * @param user 用户信息
     * @return 结果
     */
    @CacheEvict(cacheNames = CacheNames.SYS_NICKNAME, key = "#user.userId")
    @Override
    public int updateUserProfile(SysUserBo user) {
        return baseMapper.update(null,
            new LambdaUpdateWrapper<SysUser>()
                .set(ObjectUtil.isNotNull(user.getNickName()), SysUser::getNickName, user.getNickName())
                .set(SysUser::getPhonenumber, user.getPhonenumber())
                .set(SysUser::getEmail, user.getEmail())
                .set(SysUser::getSex, user.getSex())
                .eq(SysUser::getUserId, user.getUserId())
                .set(SysUser::getPasswordUpdateTime, user.getPasswordUpdateTime())
                .set(ObjectUtil.isNotNull(user.getBankName()), SysUser::getBankName, user.getBankName())
                .set(ObjectUtil.isNotNull(user.getBankCode()), SysUser::getBankCode, user.getBankCode())
                .set(ObjectUtil.isNotNull(user.getBankAddr()), SysUser::getBankAddr, user.getBankAddr())
        );

    }

    /**
     * 修改用户头像
     *
     * @param userId 用户ID
     * @param avatar 头像地址
     * @return 结果
     */
    @Override
    public boolean updateUserAvatar(Long userId, Long avatar) {
        return baseMapper.update(null,
            new LambdaUpdateWrapper<SysUser>()
                .set(SysUser::getAvatar, avatar)
                .eq(SysUser::getUserId, userId)) > 0;
    }

    /**
     * 重置用户密码
     *
     * @param userId   用户ID
     * @param password 密码
     * @return 结果
     */
    @Override
    public int resetUserPwd(Long userId, String password) {
        return baseMapper.update(null,
            new LambdaUpdateWrapper<SysUser>()
                .set(SysUser::getPassword, password)
                .eq(SysUser::getUserId, userId));
    }
    @Override
    public int updaetUserPwd(Long userId, String password) {
        return baseMapper.updatePasswordById(userId, password);
    }


    @Override
    public int updateIsFirstLogin(Long userId, Integer isFirstLogin) {
        return baseMapper.update(null,
            new LambdaUpdateWrapper<SysUser>()
                .set(SysUser::getIsFirstLogin, isFirstLogin)
                .eq(SysUser::getUserId, userId));
    }

    /**
     * 新增用户角色信息
     *
     * @param user  用户对象
     * @param clear 清除已存在的关联数据
     */
    private void insertUserRole(SysUserBo user, boolean clear) {
        this.insertUserRole(user.getUserId(), user.getRoleIds(), clear);
    }

    /**
     * 新增用户岗位信息
     *
     * @param user  用户对象
     * @param clear 清除已存在的关联数据
     */
    private void insertUserPost(SysUserBo user, boolean clear) {
        Long[] posts = user.getPostIds();
        if (ArrayUtil.isNotEmpty(posts)) {
            if (clear) {
                // 删除用户与岗位关联
                userPostMapper.delete(new LambdaQueryWrapper<SysUserPost>().eq(SysUserPost::getUserId, user.getUserId()));
            }
            // 新增用户与岗位管理
            List<SysUserPost> list = StreamUtils.toList(List.of(posts), postId -> {
                SysUserPost up = new SysUserPost();
                up.setUserId(user.getUserId());
                up.setPostId(postId);
                return up;
            });
            userPostMapper.insertBatch(list);
        }
    }

    /**
     * 新增用户角色信息
     *
     * @param userId  用户ID
     * @param roleIds 角色组
     * @param clear   清除已存在的关联数据
     */
    private void insertUserRole(Long userId, Long[] roleIds, boolean clear) {
        if (ArrayUtil.isNotEmpty(roleIds)) {
            List<Long> roleList = new ArrayList<>(List.of(roleIds));
            if (!LoginHelper.isSuperAdmin(userId)) {
                roleList.remove(UserConstants.SUPER_ADMIN_ID);
            }
            // 判断是否具有此角色的操作权限
            List<SysRoleVo> roles = roleMapper.selectRoleList(
                new QueryWrapper<SysRole>().in("r.role_id", roleList));
            if (CollUtil.isEmpty(roles)) {
                throw new ServiceException("没有权限访问角色的数据");
            }
            if (clear) {
                // 删除用户与角色关联
                userRoleMapper.delete(new LambdaQueryWrapper<SysUserRole>().eq(SysUserRole::getUserId, userId));
            }
            // 新增用户与角色管理
            List<SysUserRole> list = StreamUtils.toList(roleList, roleId -> {
                SysUserRole ur = new SysUserRole();
                ur.setUserId(userId);
                ur.setRoleId(roleId);
                return ur;
            });
            userRoleMapper.insertBatch(list);
        }
        List<Long> roleList = new ArrayList<>(List.of(roleIds));
        if (!LoginHelper.isSuperAdmin(userId)) {
            roleList.remove(UserConstants.SUPER_ADMIN_ID);
        }
        // 判断是否具有此角色的操作权限
        List<SysRoleVo> roles = roleMapper.selectRoleList(
            new QueryWrapper<SysRole>().in("r.role_id", roleList));
        if (CollUtil.isEmpty(roles)) {
            throw new ServiceException("没有权限访问角色的数据");
        }
        if (clear) {
            // 删除用户与角色关联
            userRoleMapper.delete(new LambdaQueryWrapper<SysUserRole>().eq(SysUserRole::getUserId, userId));
        }
        // 新增用户与角色管理
        List<SysUserRole> list = StreamUtils.toList(roleList, roleId -> {
            SysUserRole ur = new SysUserRole();
            ur.setUserId(userId);
            ur.setRoleId(roleId);
            return ur;
        });
        userRoleMapper.insertBatch(list);
    }

    private void insertUserRole(List<SysUser> sysUserList, boolean clear) {
        Set<String> userNameSet = sysUserList.stream().map(SysUser::getUserName).collect(Collectors.toSet());
        if (clear) {
            // 删除用户与角色关联
            userRoleMapper.delete(new LambdaQueryWrapper<SysUserRole>().in(SysUserRole::getUserId, userNameSet));
        }

        List<SysRole> specialRole = roleMapper.selectList(new LambdaQueryWrapper<SysRole>().eq(SysRole::getRoleName, "专家"));


        Map<String, Long> TenantIdMap = specialRole.stream().collect(Collectors.toMap(SysRole::getTenantId, SysRole::getRoleId));

        List<SysUserRole> list = new ArrayList<>();

        for (SysUser sysUser : sysUserList) {
            SysUserRole ur = new SysUserRole();
            String tenantId = sysUser.getTenantId();
            if (TenantIdMap.containsKey(tenantId)) {
                Long l = TenantIdMap.get(tenantId);
                ur.setRoleId(l);
                ur.setUserId(sysUser.getUserId());
                list.add(ur);
            }
        }
        userRoleMapper.insertBatch(list);
    }


    private void insertUserRole(List<SysUser> sysUserList, boolean clear,String tenantId) {
        Set<Long> userNameSet = sysUserList.stream().map(SysUser::getUserId).collect(Collectors.toSet());
        if (clear) {
            // 删除用户与角色关联
            userRoleMapper.delete(new LambdaQueryWrapper<SysUserRole>().in(SysUserRole::getUserId, userNameSet));
        }

        List<SysRole> specialRole = roleMapper.selectList(new LambdaQueryWrapper<SysRole>().eq(SysRole::getRoleName, "专家").eq(SysRole::getTenantId, tenantId));


        Map<String, Long> TenantIdMap = specialRole.stream().collect(Collectors.toMap(SysRole::getTenantId, SysRole::getRoleId));

        List<SysUserRole> list = new ArrayList<>();

        for (SysUser sysUser : sysUserList) {
            SysUserRole ur = new SysUserRole();
            if (TenantIdMap.containsKey(tenantId)) {
                Long l = TenantIdMap.get(tenantId);
                ur.setRoleId(l);
                ur.setUserId(sysUser.getUserId());
                list.add(ur);
            }
        }
        userRoleMapper.insertBatch(list);
    }





    /**
     * 通过用户ID删除用户
     *
     * @param userId 用户ID
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteUserById(Long userId) {
        // 删除用户与角色关联
        userRoleMapper.delete(new LambdaQueryWrapper<SysUserRole>().eq(SysUserRole::getUserId, userId));
        // 删除用户与岗位表
        userPostMapper.delete(new LambdaQueryWrapper<SysUserPost>().eq(SysUserPost::getUserId, userId));
        // 防止更新失败导致的数据删除
        int flag = baseMapper.deleteById(userId);
        if (flag < 1) {
            throw new ServiceException("删除用户失败!");
        }
        return flag;
    }

    /**
     * 批量删除用户信息
     *
     * @param userIds 需要删除的用户ID
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteUserByIds(Long[] userIds) {
        for (Long userId : userIds) {
            checkUserAllowed(userId);
            checkUserDataScope(userId);
        }
        List<Long> ids = List.of(userIds);
        // 删除用户与角色关联
        userRoleMapper.delete(new LambdaQueryWrapper<SysUserRole>().in(SysUserRole::getUserId, ids));
        // 删除用户与岗位表
        userPostMapper.delete(new LambdaQueryWrapper<SysUserPost>().in(SysUserPost::getUserId, ids));
        // 防止更新失败导致的数据删除
        int flag = baseMapper.deleteByIds(ids);
        if (flag < 1) {
            throw new ServiceException("删除用户失败!");
        }
        return flag;
    }

    /**
     * 通过部门id查询当前部门所有用户
     *
     * @param deptId 部门ID
     * @return 用户信息集合信息
     */
    @Override
    public List<SysUserVo> selectUserListByDept(Long deptId) {
        LambdaQueryWrapper<SysUser> lqw = Wrappers.lambdaQuery();
        lqw.eq(SysUser::getDeptId, deptId);
        lqw.orderByAsc(SysUser::getUserId);
        return baseMapper.selectVoList(lqw);
    }

    @Override
    public List<Long> selectUserIdsByRoleIds(List<Long> roleIds) {
        List<SysUserRole> userRoles = userRoleMapper.selectList(
            new LambdaQueryWrapper<SysUserRole>().in(SysUserRole::getRoleId, roleIds));
        return StreamUtils.toList(userRoles, SysUserRole::getUserId);
    }

    @Override
    public List<SysUser> selectListByUserNames(List<String> userNameSet) {
        return baseMapper.selectListByUserNames(userNameSet);
    }

    @Override
    public SysUserVo selectVoById(Long userId) {
        return baseMapper.selectUserById(userId);
    }


    /**
     * 通过用户ID查询用户账户
     *
     * @param userId 用户ID
     * @return 用户账户
     */
    @Cacheable(cacheNames = CacheNames.SYS_USER_NAME, key = "#userId")
    @Override
    public String selectUserNameById(Long userId) {
        SysUser sysUser = baseMapper.selectOne(new LambdaQueryWrapper<SysUser>()
            .select(SysUser::getUserName).eq(SysUser::getUserId, userId));
        return ObjectUtil.isNull(sysUser) ? null : sysUser.getUserName();
    }

    /**
     * 通过用户ID查询用户昵称
     *
     * @param userId 用户ID
     * @return 用户昵称
     */
    @Override
    @Cacheable(cacheNames = CacheNames.SYS_NICKNAME, key = "#userId")
    public String selectNicknameById(Long userId) {
        SysUser sysUser = baseMapper.selectOne(new LambdaQueryWrapper<SysUser>()
            .select(SysUser::getNickName).eq(SysUser::getUserId, userId));
        return ObjectUtil.isNull(sysUser) ? null : sysUser.getNickName();
    }

    @Override
    public String selectNicknameByIds(String userIds) {
        List<String> list = new ArrayList<>();
        for (Long id : StringUtils.splitTo(userIds, Convert::toLong)) {
            String nickname = SpringUtils.getAopProxy(this).selectNicknameById(id);
            if (StringUtils.isNotBlank(nickname)) {
                list.add(nickname);
            }
        }
        return String.join(StringUtils.SEPARATOR, list);
    }

    /**
     * 通过用户ID查询用户手机号
     *
     * @param userId 用户id
     * @return 用户手机号
     */
    @Override
    public String selectPhonenumberById(Long userId) {
        SysUser sysUser = baseMapper.selectOne(new LambdaQueryWrapper<SysUser>()
            .select(SysUser::getPhonenumber).eq(SysUser::getUserId, userId));
        return ObjectUtil.isNull(sysUser) ? null : sysUser.getPhonenumber();
    }

    /**
     * 通过用户ID查询用户邮箱
     *
     * @param userId 用户id
     * @return 用户邮箱
     */
    @Override
    public String selectEmailById(Long userId) {
        SysUser sysUser = baseMapper.selectOne(new LambdaQueryWrapper<SysUser>()
            .select(SysUser::getEmail).eq(SysUser::getUserId, userId));
        return ObjectUtil.isNull(sysUser) ? null : sysUser.getEmail();
    }

}
