package com.seer.teach.user.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.seer.teach.common.enums.ResultCodeEnum;
import com.seer.teach.common.utils.AssertUtils;
import com.seer.teach.user.entity.RoleEntity;
import com.seer.teach.user.entity.UserEntity;
import com.seer.teach.user.entity.UserRoleEntity;
import com.seer.teach.user.mapper.UserRoleMapper;
import com.seer.teach.user.service.IRoleService;
import com.seer.teach.user.service.IUserRoleService;
import com.seer.teach.user.service.IUserService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 *  用户角色服务实现类
 * </p>
 *
 * @author Wang
 * @since 2025-07-16 17:01:56
 */
@RequiredArgsConstructor
@Slf4j
@Service
public class UserRoleServiceImpl extends ServiceImpl<UserRoleMapper, UserRoleEntity> implements IUserRoleService {

    private final IRoleService roleService;

    private final IUserService userService;

    @Override
    public List<UserRoleEntity> getListByUserId(Integer userId) {
        return list(new LambdaQueryWrapper<>(UserRoleEntity.class).eq(UserRoleEntity::getUserId, userId));
    }

    @Override
    public List<String> getRoleCodeListByUserId(Integer userId) {
        List<UserRoleEntity> userRoleList = this.getListByUserId(userId);
        if(CollectionUtil.isNotEmpty(userRoleList)){
            List<Integer> roleIds = userRoleList.stream().map(UserRoleEntity::getRoleId).collect(Collectors.toList());
            if(CollectionUtil.isNotEmpty(roleIds)){
                Collection<RoleEntity> roles = roleService.getRoleListByRoleIds(roleIds);
                return roles.stream().map(RoleEntity::getRoleCode).collect(Collectors.toList());
            }
        }
        return List.of();
    }

    @Override
    public boolean assignUserRole(Integer userId, Set<Integer> roleIds) {
        List<UserRoleEntity> userRoleList = this.getListByUserId(userId);
        if(CollectionUtils.isEmpty(userRoleList)){
            List<UserRoleEntity> userRoles = roleIds.stream().map(roleId -> UserRoleEntity.builder().userId(userId).roleId(roleId.intValue()).build()).collect(Collectors.toList());
            boolean savedBatch = super.saveBatch(userRoles);
            log.info("分配角色[{}] result:{}", userRoles, savedBatch);
            return savedBatch;
        }
        Set<Integer> roleIdSet = userRoleList.stream().map(UserRoleEntity::getRoleId).collect(Collectors.toSet());
        Collection<Integer> createRoleIds = CollUtil.subtract(roleIds, roleIdSet);
        if (CollUtil.isNotEmpty(createRoleIds)) {
            List<UserRoleEntity> userRoles = createRoleIds.stream().map(roleId -> UserRoleEntity.builder().userId(userId).roleId(roleId.intValue()).build()).collect(Collectors.toList());
            boolean savedBatch = super.saveBatch(userRoles);
            log.info("新增角色[{}] result:{}", userRoles, savedBatch);
            return savedBatch;
        }
        return true;
    }

    @Override
    public boolean assignUserRole(Integer userId, Integer roleId) {
        Set<Integer> roleIds = new HashSet<>();
        roleIds.add(roleId);
        return assignUserRole(userId, roleIds);
    }

    @Override
    public boolean assignUserRoleByRoleCode(Integer userId, String roleCode) {
        Optional<RoleEntity> role = roleService.getRoleByCode(roleCode);
        if(role.isPresent()){
            return assignUserRole(userId, role.get().getId());
        }
        return false;
    }

    @Override
    public boolean allocUserRole(Integer userId, Collection<Integer> roleIds) {
        UserEntity user = userService.getById(userId);
        AssertUtils.notNull(user, ResultCodeEnum.USER_NOT_FOUND);

        List<UserRoleEntity> userRoleEntities = super.list(new LambdaQueryWrapper<>(UserRoleEntity.class).eq(UserRoleEntity::getUserId, userId)
                .in(CollectionUtil.isNotEmpty(roleIds), UserRoleEntity::getRoleId, roleIds));

        if(CollectionUtil.isNotEmpty(userRoleEntities)){
            roleIds.removeAll(userRoleEntities.stream().map(UserRoleEntity::getRoleId).collect(Collectors.toSet()));
        }
        if(CollectionUtil.isNotEmpty(roleIds)){
            List<UserRoleEntity> userRoleList = roleIds.stream().map(roleId -> UserRoleEntity.builder().userId(userId).roleId(roleId).build()).collect(Collectors.toList());
            boolean saved = super.saveOrUpdateBatch(userRoleList);
            log.info("用户[{}]分配角色 result:{}", StpUtil.getLoginIdAsString(), saved);
            return saved;
        }
        return false;
    }

    @Override
    public boolean deleteUserRole(Integer userId, Set<Integer> roleIds) {
        return super.remove(new LambdaQueryWrapper<>(UserRoleEntity.class).eq(UserRoleEntity::getUserId, userId).in(UserRoleEntity::getRoleId, roleIds));
    }

}
