package com.chushang.system.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.chushang.common.core.exception.ResultException;
import com.chushang.common.core.util.IdUtils;
import com.chushang.common.core.util.SpringUtils;
import com.chushang.common.core.web.AjaxResult;
import com.chushang.common.mybatis.utils.PageResult;
import com.chushang.datascope.annotation.DataScope;
import com.chushang.security.service.TokenService;
import com.chushang.security.utils.SecurityUtils;
import com.chushang.system.mapper.SysUserMapper;
import com.chushang.system.service.*;
import com.chushang.system.entity.dto.ListUserDTO;
import com.chushang.system.entity.po.SysUser;
import com.chushang.system.entity.po.SysUserRole;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author author
 * @since 2022-08-18
 */
@Slf4j
@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements ISysUserService {

    @Autowired
    ISysRoleService sysRoleService;
    @Autowired
    ISysMenuService sysMenuService;
    @Autowired
    ISysUserRoleService userRoleService;
    @Autowired
    TokenService tokenService;
    @Autowired
    ISysPostService sysPostService;

    @Override
    @DataScope(deptAlias = "d", userAlias = "u")
    public AjaxResult listUser(ListUserDTO listUser) {
        com.baomidou.mybatisplus.extension.plugins.pagination.Page<SysUser> page = new com.baomidou.mybatisplus.extension.plugins.pagination.Page<>(listUser.getPage(),listUser.getLimit());

        List<SysUser> listAfDataVOList = baseMapper.listUser(listUser,
                page);
        return AjaxResult.success(new PageResult(
                listAfDataVOList,
                page.getTotal(),
                page.getPages(),
                page.getCurrent()));
    }

    @Override
    public SysUser selectUserByUserName(String username) {
        return this.baseMapper.selectUserByUserName(username);
    }

    @Override
    public SysUser selectUserById(Long userId) {
        SysUser sysUser = baseMapper.selectUserById(userId);
        if (ObjectUtil.isNotEmpty(sysUser)){
            sysUser.setSalt("");
            sysUser.setPassword("");
        }
        return sysUser;
    }

    /**
     * 判断当前登录用户 有没有 被修改用户的权限
     */
    @Override
    @DataScope(deptAlias = "d", userAlias = "u")
    public void checkUserDataScope(SysUser user)
    {
        //登录用户非管理员时进行判断 && 待操作的用户也不为管理员
        if (!SecurityUtils.isAdmin())
        {
            List<SysUser> users = baseMapper.selectUserList(user);
            if (ObjectUtil.isEmpty(users))
            {
                throw new ResultException("没有权限访问用户数据！");
            }
        }
    }

    @Override
    @Transactional
    public void saveUser(SysUser user) {

        SpringUtils.getAopProxy(this).checkUsernameUnique(user.getUsername());
        user.setCreateTime(LocalDateTime.now());
        String salt = IdUtils.getId(10);
        user.setPassword(SecurityUtils.encryptPassword(user.getPassword(), salt));
        user.setSalt(salt);
        this.save(user);

        //保存用户与角色关系
        userRoleService.saveOrUpdate(user.getUserId(), user.getRoleIds());

    }

    @Override
    public void update(SysUser user) {
        if(StringUtils.isBlank(user.getPassword())){
            user.setPassword(null);
        }
        this.updateById(user);

        //保存用户与角色关系
        userRoleService.saveOrUpdate(user.getUserId(), user.getRoleIds());

    }

    @Override
    @Transactional
    public void deleteBatch(Long[] userIds) {

        for (Long userId : userIds)
        {
            SysUser sysUser = SysUser.builder().userId(userId).build();
            SpringUtils.getAopProxy(this).checkUserAllowed(sysUser);
            SpringUtils.getAopProxy(this).checkUserDataScope(sysUser);
        }

        this.removeByIds(Arrays.asList(userIds));

        //先删除用户与角色关系
        userRoleService.remove(new LambdaQueryWrapper<SysUserRole>()
                .in(SysUserRole::getUserId, Arrays.asList(userIds)));

    }


    @Override
    @Transactional
    public void insertUserAuth(Long userId, Long[] roleIds) {
        userRoleService.saveOrUpdate(userId, roleIds);
    }

    @Override
    @DataScope(deptAlias = "d", userAlias = "u")
    public AjaxResult selectAllocatedList(ListUserDTO listUser) {
        com.baomidou.mybatisplus.extension.plugins.pagination.Page<SysUser> page =
                new com.baomidou.mybatisplus.extension.plugins.pagination.Page<>(listUser.getPage(),listUser.getLimit());
        List<SysUser> userList = baseMapper.selectAllocatedList(listUser,
                page);
        return AjaxResult.success(new PageResult(
                userList,
                page.getTotal(),
                page.getPages(),
                page.getCurrent()));
    }

    @Override
    @DataScope(deptAlias = "d", userAlias = "u")
    public AjaxResult selectUnallocatedList(ListUserDTO listUser) {
        com.baomidou.mybatisplus.extension.plugins.pagination.Page<SysUser> page = new com.baomidou.mybatisplus.extension.plugins.pagination.Page<>(listUser.getPage(),listUser.getLimit());

        List<SysUser> userList = baseMapper.selectUnallocatedList(listUser,
                page);
        return AjaxResult.success(new PageResult(
                userList,
                page.getTotal(),
                page.getPages(),
                page.getCurrent()));
    }

    @Override
    public String selectUserRoleGroup(String username) {
        return sysRoleService.selectRolesByUserName(username);
    }

    /**
     * 查询用户所属岗位组
     *
     * @param username 用户名
     * @return 结果
     */
    @Override
    public String selectUserPostGroup(String username)
    {
        return sysPostService.selectUserPostGroup(username);
    }

    @Override
    public void resetPwd(Long userId, String newPassword) {
        SysUser user = getOne(new LambdaQueryWrapper<SysUser>()
                .eq(SysUser::getUserId, userId));
        if (ObjectUtil.isEmpty(user)){
            throw new ResultException("用户不存在");
        }
        String salt = IdUtils.getId(10);
        //sha256加密
        newPassword = SecurityUtils.encryptPassword(newPassword, salt);
        updateById(SysUser.builder()
                .userId(userId)
                .password(newPassword)
                .salt(salt)
                .updateBy(SecurityUtils.getUsername())
                .build());
        // 强退用户
        tokenService.forcedRetreat(userId);
    }


    private void checkUsernameUnique(String username) {
        long count = count(new LambdaQueryWrapper<SysUser>()
                .eq(SysUser::getUsername, username));
        if (count > 0){
            throw new ResultException("保存用户'" + username + "'失败，注册账号已存在");
        }
    }
}
