package com.supervision.police.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.supervision.police.domain.SystemUser;
import com.supervision.police.dto.MenuDTO;
import com.supervision.police.dto.user.*;
import com.supervision.police.service.SystemMenuService;
import com.supervision.police.service.SystemUserRoleRelationService;
import com.supervision.police.service.SystemUserService;
import com.supervision.police.mapper.SystemUserMapper;
import com.supervision.utils.UserUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
* @author Administrator
* @description 针对表【system_user(用户表)】的数据库操作Service实现
* @createDate 2024-07-31 11:02:43
*/
@Slf4j
@Service
@RequiredArgsConstructor
public class SystemUserServiceImpl extends ServiceImpl<SystemUserMapper, SystemUser>
    implements SystemUserService{

    private final SystemUserRoleRelationService userRoleRelationManageService;

    private final SystemMenuService menuService;

    @Override
    public LoginResVO login(LoginReqVO reqVO) {

        // 校验用户信息是否正确
        Assert.isTrue(StrUtil.isAllNotEmpty(reqVO.getUserAccount(), reqVO.getPassword()), "用户名或密码不能为空");

        SystemUser systemUser = super.getOne(new LambdaQueryWrapper<SystemUser>().eq(SystemUser::getAccount, reqVO.getUserAccount()));
        Assert.notNull(systemUser, "用户名或密码有误!");
        Assert.isTrue(UserUtil.checkUserPassword(reqVO.getPassword(), systemUser.getUserPd()), "用户名或密码有误!");
        Assert.isTrue(Integer.valueOf(0).equals(systemUser.getStatus()), "该用户已被停用,请联系管理员!");

        // 组装用户信息
        LoginResVO loginResVO = new LoginResVO(systemUser);

        loginResVO.setRoleList(userRoleRelationManageService.listUserRoleByUserIdList(CollUtil.newArrayList(systemUser.getId())));
        // 设置用户权限信息
        List<RoleMenuDTO> roleMenuDTOS = userRoleRelationManageService.listUserRoleMenu(systemUser.getId());
        if (CollUtil.isNotEmpty(roleMenuDTOS)){
            List<MenuDTO> menuDTOS = menuService.treeMenuList();
            List<MenuDTO> menuBySelect = menuService.filterMenuBySelect(menuDTOS,roleMenuDTOS.stream().map(RoleMenuDTO::getMenuId).toList());
            loginResVO.setPermission(menuBySelect.stream().map(MenuDTO::getLabelCode).toList());
        }

        // 设置用户token信息
        loginResVO.setToken(new UserInfoDTO(systemUser));
        return loginResVO;
    }

    @Override
    public UserInfoDTO getCurrentUser() {
        return UserUtil.getUser();
    }

    @Override
    @Transactional(transactionManager = "dataSourceTransactionManager",rollbackFor = Exception.class)
    public String saveUserInfo(UserInfoReqVo userInfoReqVo) {
        Assert.notEmpty(userInfoReqVo.getAccount(), "账号不能为空");
        Assert.notEmpty(userInfoReqVo.getUserName(), "姓名不能为空");
        Assert.notEmpty(userInfoReqVo.getPassword(), "密码不能为空");
        Assert.notEmpty(userInfoReqVo.getRoleIdList(), "角色不能为空");

        Long count = super.lambdaQuery().eq(SystemUser::getAccount, userInfoReqVo.getAccount()).count();
        Assert.isTrue(count == 0, "账号已存在");

        SystemUser systemUser = userInfoReqVo.toSystemUser();
        // 设置默认密码
        super.save(systemUser);
        userRoleRelationManageService.saveUserRoleRelation(systemUser.getId(), userInfoReqVo.getRoleIdList());
        return systemUser.getId();
    }

    @Override
    @Transactional(transactionManager = "dataSourceTransactionManager",rollbackFor = Exception.class)
    public void updateUserInfo(UserInfoReqVo userInfoReqVo) {

        Assert.notEmpty(userInfoReqVo.getId(), "用户id不能为空");
        Assert.notEmpty(userInfoReqVo.getAccount(), "用户名不能为空");
        Assert.notEmpty(userInfoReqVo.getUserName(), "姓名不能为空");
        Assert.notEmpty(userInfoReqVo.getRoleIdList(), "角色不能为空");


        Long count = super.lambdaQuery()
                .eq(SystemUser::getAccount, userInfoReqVo.getAccount())
                .ne(SystemUser::getId, userInfoReqVo.getId()).count();
        Assert.isTrue(count == 0, "用户名已存在,请更改用户名");

        LambdaUpdateChainWrapper<SystemUser> updateChainWrapper = super.lambdaUpdate()
                .set(SystemUser::getHeadPicId, userInfoReqVo.getHeadPicId())
                .set(SystemUser::getUserName, userInfoReqVo.getUserName())
                .set(SystemUser::getAccount, userInfoReqVo.getAccount())
                .set(SystemUser::getPhoneNum, userInfoReqVo.getPhoneNum())
                .set(Objects.nonNull(userInfoReqVo.getStatus()), SystemUser::getStatus, userInfoReqVo.getStatus())
                .set(SystemUser::getRemark, userInfoReqVo.getRemark())
                .eq(SystemUser::getId, userInfoReqVo.getId());

        if (StrUtil.isNotEmpty(userInfoReqVo.getPassword())) {
            updateChainWrapper.set(SystemUser::getUserPd, UserUtil.signPassword(userInfoReqVo.getPassword()));
        }

        updateChainWrapper.update();

        userRoleRelationManageService.updateUserRoleRelation(userInfoReqVo.getId(), userInfoReqVo.getRoleIdList());
    }

    @Override
    @Transactional(transactionManager = "dataSourceTransactionManager",rollbackFor = Exception.class)
    public Boolean deleteUser(String id) {

        Assert.notEmpty(id, "用户id不能为空");
        SystemUser systemUser = super.getById(id);
        Assert.notNull(systemUser, "用户不存在");
        Assert.isFalse(systemUser.getStatus() == 0, "该用户已启用,不能删除");

        super.removeById(id);

        userRoleRelationManageService.deleteUserRoleRelation(id);
        return true;
    }

    @Override
    public IPage<UserInfoDTO> list(String userName, String roleId, String roleName, Integer pageNum, Integer pageSize) {

        List<UserRoleDTO> userRoleFilterList = new ArrayList<>();
        // 先对角色进行判断
        if (StrUtil.isNotEmpty(roleId) || StrUtil.isNotEmpty(roleName)){
            userRoleFilterList = userRoleRelationManageService.listUserRole(null, roleId, roleName);
            if (CollUtil.isEmpty(userRoleFilterList)){
                return Page.of(pageNum, pageSize, 0);
            }
        }

        //查询用户数据
        Page<SystemUser> userInfoPage = super.page(Page.of(pageNum, pageSize),
                new LambdaQueryWrapper<SystemUser>()
                        .like(StrUtil.isNotEmpty(userName), SystemUser::getUserName, userName)
                        .in(CollUtil.isNotEmpty(userRoleFilterList), SystemUser::getId, userRoleFilterList.stream().map(UserRoleDTO::getUserId).toList())
                        .orderBy(true,false, SystemUser::getUpdateTime));

        if (CollUtil.isEmpty(userInfoPage.getRecords())){
            return Page.of(pageNum, pageSize, userInfoPage.getTotal());
        }

        List<UserRoleDTO> userRoleList = userRoleRelationManageService.listUserRoleByUserIdList(userInfoPage.getRecords().stream().map(SystemUser::getId).toList());
        Map<String, List<UserRoleDTO>> userRoleMap = userRoleList.stream().collect(Collectors.groupingBy(UserRoleDTO::getUserId, Collectors.toList()));

        return  userInfoPage.convert(systemUser -> new UserInfoDTO(systemUser,userRoleMap));
    }


    @Override
    public void updateUserStatus(UserStatusReqVo userStatusReqVo) {
        Assert.notEmpty(userStatusReqVo.getId(), "用户id不能为空");
        Assert.notNull(userStatusReqVo.getStatus(), "用户状态不能为空");
        super.lambdaUpdate().set(SystemUser::getStatus, userStatusReqVo.getStatus())
                .eq(SystemUser::getId, userStatusReqVo.getId()).update();
    }

    @Override
    public boolean changePassWord(String account, String password) {
        UserInfoDTO user = UserUtil.getUser();
        Assert.notEmpty(password, "密码不能为空");

        Long count = super.lambdaQuery().eq(SystemUser::getId, user.getId()).count();
        if (count == 0){
            log.info("账号:{}不存在", account);
            return false;
        }

        return super.lambdaUpdate().set(SystemUser::getUserPd, UserUtil.signPassword(password))
                    .eq(SystemUser::getId, user.getId()).update();
    }
}