package com.yinlihupo.enlish.service.service.role;

import com.yinlihupo.enlish.service.constant.RoleConstants;
import com.yinlihupo.enlish.service.domain.dataobject.RoleDO;
import com.yinlihupo.enlish.service.domain.dataobject.UserRoleRelDO;
import com.yinlihupo.enlish.service.domain.mapper.RoleDOMapper;
import com.yinlihupo.enlish.service.domain.mapper.UserDOMapper;
import com.yinlihupo.enlish.service.domain.mapper.UserRoleRelDOMapper;
import com.yinlihupo.enlish.service.service.RoleService;
import com.yinlihupo.framework.common.util.JsonUtils;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

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

@Service
@Slf4j
public class RoleServiceImpl implements RoleService {

    @Resource
    private RedisTemplate<String, Object> redisTemplate;
    @Resource
    private RoleDOMapper roleDOMapper;
    @Resource
    private UserRoleRelDOMapper userRoleRelDOMapper;


    @Override
    public void pushRolePermission2Redis() {
        List<RoleDO> roleDOS = roleDOMapper.selectAll();
        List<String> roleKeys = roleDOS.stream().map(RoleDO::getRoleKey).toList();
        log.info("将角色同步到 redis 中, {}", roleKeys);
        redisTemplate.opsForValue().set(RoleConstants.ROLE, JsonUtils.toJsonString(roleKeys));

        Map<Long, RoleDO> roleId2RoleDO = roleDOS.stream().collect(Collectors.toMap(RoleDO::getId, roleDO -> roleDO));

        List<UserRoleRelDO> userRoleRelDOS = userRoleRelDOMapper.selectAll();
        log.info("将用户角色关系同步到 redis 中, {}", userRoleRelDOS);
        Map<Long, List<UserRoleRelDO>> userId2UserRoleRelDOs = userRoleRelDOS.stream().collect(Collectors.groupingBy(UserRoleRelDO::getUserId));

        userId2UserRoleRelDOs.forEach((userId, userRoleRelDOs) -> {
            List<Long> roleIds = userRoleRelDOs.stream().map(UserRoleRelDO::getRoleId).toList();
            List<RoleDO> roleDOs = roleIds.stream().map(roleId2RoleDO::get).toList();
            List<String> user2RoleKeys = roleDOs.stream().map(RoleDO::getRoleKey).toList();
            log.info("将用户 {} 的角色同步到 redis 中, {}", userId, roleKeys);
            // 不要使用 JsonUtils.toJsonString(user2RoleKeys); 会造成二次序列化
            redisTemplate.opsForValue().set(RoleConstants.buildUserRoleKey(userId), user2RoleKeys);
        });
    }

    @Override
    public Map<Long, RoleDO> findUserId2RoleMap(List<Long> userIds) {
        List<UserRoleRelDO> userRoleRelDOS = userRoleRelDOMapper.selectByUserIds(userIds);
        Map<Long, UserRoleRelDO> userId2UserRoleRelDOs = userRoleRelDOS.stream().collect(Collectors.toMap(UserRoleRelDO::getUserId, userRoleRelDO -> userRoleRelDO));

        List<RoleDO> roleDOS = roleDOMapper.selectByIds(userRoleRelDOS.stream().map(UserRoleRelDO::getRoleId).toList());
        Map<Long, RoleDO> roleId2RoleDO = roleDOS.stream().collect(Collectors.toMap(RoleDO::getId, roleDO -> roleDO));

        return userIds.stream().collect(Collectors.toMap(userId -> userId, userId -> roleId2RoleDO.get(userId2UserRoleRelDOs.get(userId).getRoleId())));
    }
}
