package com.xiaoniu.subsystem.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xiaoniu.api.vo.ApiLoginUserVO;
import com.xiaoniu.common.core.constant.Constants;
import com.xiaoniu.common.core.constant.UserConstants;
import com.xiaoniu.common.core.exception.ServiceException;
import com.xiaoniu.common.core.utils.DateUtils;
import com.xiaoniu.common.core.utils.StringUtils;
import com.xiaoniu.common.core.utils.bean.BeanUtils;
import com.xiaoniu.common.datascope.annotation.DataScope;
import com.xiaoniu.common.security.utils.SecurityUtils;
import com.xiaoniu.subsystem.system.domain.*;
import com.xiaoniu.subsystem.system.domain.dto.AddSysUserDTO;
import com.xiaoniu.subsystem.system.domain.dto.EditSysUserDTO;
import com.xiaoniu.subsystem.system.domain.dto.UserDetailVO;
import com.xiaoniu.subsystem.system.domain.dto.UserListQueryDTO;
import com.xiaoniu.subsystem.system.domain.vo.UserListVO;
import com.xiaoniu.subsystem.system.mapper.*;
import com.xiaoniu.subsystem.system.service.ISysPermissionService;
import com.xiaoniu.subsystem.system.service.ISysUserService;
import jakarta.annotation.Resource;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 用户 业务层处理
 *
 * @author xiaoniu
 */
@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements ISysUserService {

    @Resource
    private SysRoleMapper roleMapper;
    @Resource
    private UnitMapper unitMapper;
    @Resource
    private SysUserRoleMapper sysUserRoleMapper;
    @Resource
    private SysUserPostMapper sysUserPostMapper;
    @Resource
    private ISysPermissionService permissionService;

    /**
     * 根据条件分页查询已分配用户角色列表
     *
     * @param user 用户信息
     * @return 用户信息集合信息
     */
    @Override
    @DataScope(deptAlias = "d", userAlias = "u")
    public List<SysUser> selectAllocatedList(SysUser user) {
        return baseMapper.selectAllocatedList(user);
    }

    /**
     * 根据条件分页查询未分配用户角色列表
     *
     * @param user 用户信息
     * @return 用户信息集合信息
     */
    @Override
    @DataScope(deptAlias = "d", userAlias = "u")
    public List<SysUser> selectUnallocatedList(SysUser user) {
        return baseMapper.selectUnallocatedList(user);
    }

    /**
     * 通过用户名查询用户
     *
     * @param userName 用户名
     * @return 用户对象信息
     */
    @Override
    public ApiLoginUserVO selectUserByUserName(String userName) {
        LambdaQueryWrapper<SysUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysUser::getUserName, userName);
        wrapper.eq(SysUser::getDelFlag, Constants.ZERO);
        wrapper.last("limit 1");
        SysUser user = baseMapper.selectOne(wrapper);
        // 角色集合
        Set<String> roles = permissionService.getRolePermission(user);
        // 权限集合
        Set<String> permissions = permissionService.getMenuPermission(user);
        ApiLoginUserVO apiLoginUserVO = new ApiLoginUserVO();
        apiLoginUserVO.setUserId(user.getUserId());
        apiLoginUserVO.setUserName(user.getUserName());
        apiLoginUserVO.setPassWord(user.getPassword());
        apiLoginUserVO.setDelFlag(user.getDelFlag());
        apiLoginUserVO.setStatus(user.getStatus());
        apiLoginUserVO.setPermissions(permissions);
        apiLoginUserVO.setUnitId(user.getUnitId());
        apiLoginUserVO.setRoles(roles);
        return apiLoginUserVO;
    }

    /**
     * 通过用户ID查询用户
     *
     * @param userId 用户ID
     * @return 用户对象信息
     */
    @Override
    public SysUser selectUserById(Long userId) {
        return baseMapper.selectById(userId);
    }

    /**
     * 查询用户所属角色组
     *
     * @param userName 用户名
     * @return 结果
     */
    @Override
    public String selectUserRoleGroup(String userName) {
        List<SysRole> list = roleMapper.selectRolesByUserName(userName);
        if (CollectionUtils.isEmpty(list)) {
            return StringUtils.EMPTY;
        }
        return list.stream().map(SysRole::getRoleName).collect(Collectors.joining(","));
    }

    /**
     * 校验用户名称是否唯一
     *
     * @return 结果
     */
    public boolean checkUserNameUnique(String userName, Long userId) {
        LambdaQueryWrapper<SysUser> wrapper = new LambdaQueryWrapper<>();
        if (StringUtils.isNotNull(userId)) {
            wrapper.ne(SysUser::getUserId, userId);
        }
        wrapper.eq(SysUser::getUserName, userName);
        wrapper.eq(SysUser::getDelFlag, Constants.ZERO);
        Long count = baseMapper.selectCount(wrapper);
        if (count > 0) {
            return UserConstants.NOT_UNIQUE;
        }
        return UserConstants.UNIQUE;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean editUser(EditSysUserDTO dto) {
        SysUser sysUser = baseMapper.selectById(dto.getUserId());
        if (StringUtils.isNull(sysUser)) {
            throw new ServiceException("当前用户不存在");
        }
        BeanUtils.copyProperties(dto, sysUser);
        //校验用户名唯一性
        checkUserNameUnique(dto.getUserName(), sysUser.getUserId());
        //保存用户信息
        sysUser.setBirthday(DateUtils.parseDate(dto.getBirthday()));
        sysUser.setUpdateBy(SecurityUtils.getUsername());
        sysUser.setUpdateTime(new Date());
        sysUser.setPassword(SecurityUtils.encryptPassword(sysUser.getPassword()));
        baseMapper.updateById(sysUser);
        //删除角色和用户关联表
        sysUserRoleMapper.delete(new LambdaQueryWrapper<SysUserRole>().eq(SysUserRole::getUserId, dto.getUserId()));
        if (StringUtils.isNotNull(dto.getRoleId())) {
            //处理角色和用户关联表
            SysUserRole sysUserRole = new SysUserRole();
            sysUserRole.setUserId(dto.getUserId());
            sysUserRole.setRoleId(dto.getRoleId());
            sysUserRoleMapper.insert(sysUserRole);
        }
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean addUser(AddSysUserDTO dto) {
        SysUser sysUser = new SysUser();
        BeanUtils.copyProperties(dto, sysUser);
        if (StringUtils.isBlank(dto.getRealName())){
            sysUser.setRealName(dto.getUserName());
        }
        if (StringUtils.isBlank(dto.getNickName())){
            sysUser.setRealName(dto.getRealName());
        }
        //校验用户名唯一性
        boolean b = checkUserNameUnique(dto.getUserName(), null);
        if (b) {
            sysUser.setBirthday(DateUtils.parseDate(dto.getBirthday()));
            sysUser.setPassword(SecurityUtils.encryptPassword(sysUser.getPassword()));
            baseMapper.insert(sysUser);
            if (StringUtils.isNotNull(dto.getRoleId())) {
                //处理角色和用户关联表
                SysUserRole sysUserRole = new SysUserRole();
                sysUserRole.setUserId(sysUser.getUserId());
                sysUserRole.setRoleId(dto.getRoleId());
                sysUserRoleMapper.insert(sysUserRole);
            }
        }
        return b;
    }


    /**
     * 获取用户列表
     *
     * @return
     */
    @Override
    public IPage<UserListVO> selectUserList(IPage<UserListVO> page, UserListQueryDTO dto) {
        if (StringUtils.isNotNull(dto.getUnitId())) {
            //获取子部门
            List<Long> ids = new ArrayList<>();
            ids.add(dto.getUnitId());
            List<Unit> units = unitMapper.selectList(new LambdaQueryWrapper<Unit>()
                    .eq(Unit::getParentId, dto.getUnitId()));
            if (CollectionUtils.isNotEmpty(units)){
                List<Long> longs = units.stream().map(Unit::getUnitId).toList();
                ids.addAll(longs);
                List<Unit> list = unitMapper.selectList(new LambdaQueryWrapper<Unit>()
                        .in(Unit::getParentId,longs));
                setUnit(list,ids);
            }
            if (CollectionUtils.isNotEmpty(ids)){
                dto.setUnitIdList(ids);
            }
        }
        return page.setRecords(baseMapper.selectUserList(page, dto));
    }

    private void setUnit(List<Unit> list, List<Long> ids){
        if (CollectionUtils.isNotEmpty(list)){
            List<Long> longs = list.stream().map(Unit::getUnitId).toList();
            ids.addAll(longs);
            List<Unit> units = unitMapper.selectList(new LambdaQueryWrapper<Unit>()
                    .in(Unit::getParentId,longs));
            setUnit(units,ids);
        }
    }

    /**
     * 用户详情
     *
     * @return
     */
    @Override
    public UserDetailVO detail(Long userId) {
        return baseMapper.detail(userId);
    }

    /**
     * 校验用户是否允许操作
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean del(List<Long> ids) {
        LambdaUpdateWrapper<SysUser> wrapper = new LambdaUpdateWrapper<>();
        wrapper.in(SysUser::getUserId, ids);
        wrapper.set(SysUser::getDelFlag, Constants.TWO);
        int count = baseMapper.update(wrapper);
        //删除角色和用户关联表
        sysUserRoleMapper.delete(new LambdaQueryWrapper<SysUserRole>().in(SysUserRole::getUserId, ids));
        //删除角色和用户关联表
        sysUserPostMapper.delete(new LambdaQueryWrapper<SysUserPost>().in(SysUserPost::getUserId, ids));
        return count > 0;
    }

}
