package com.CUST.brain.service.impl;

import com.CUST.brain.common.annotation.RedisCache;
import com.CUST.brain.common.constant.RedisKeyConstants;
import com.CUST.brain.common.dto.system.PermissionTreeVO;
import com.CUST.brain.common.dto.system.UpdateRolePermissionsRequestDTO;
import com.CUST.brain.dao.domain.system.SysPermission;
import com.CUST.brain.dao.domain.system.SysRole;
import com.CUST.brain.dao.domain.relation.SysRolePermission;
import com.CUST.brain.dao.mapper.SysPermissionMapper;
import com.CUST.brain.dao.mapper.SysRoleMapper;
import com.CUST.brain.service.SysPermissionService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.CUST.brain.common.utils.CacheCleanUtils;
import javax.annotation.Resource;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;

@Service
public class SysPermissionServiceImpl extends ServiceImpl<SysPermissionMapper, SysPermission> implements SysPermissionService {

    private static final Logger log = LoggerFactory.getLogger(SysPermissionServiceImpl.class);

    @Resource
    private CacheCleanUtils cacheCleanUtils;

    @Resource
    private SysRoleMapper sysRoleMapper;

    @Autowired
    private ObjectMapper objectMapper;

    @Override
    @RedisCache(key = "'user:permissions:' + #p0", expire = 1800, cacheNull = true)
    public List<SysPermission> getPermissionsByUserId(String userId) {
        log.debug("SysPermissionServiceImpl.getPermissionsByUserId 入参: {}", userId);
        List<SysPermission> permissions = baseMapper.selectPermissionsByUserId(userId);
        log.debug("SysPermissionServiceImpl.getPermissionsByUserId 查询结果: {}", permissions);
        return permissions;
    }

    @Override
    @RedisCache(key = RedisKeyConstants.SYS_PERMISSION + "code:${#permissionCode}", expire = 1800)
    public SysPermission getByPermissionCode(String permissionCode) {
        LambdaQueryWrapper<SysPermission> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysPermission::getPermissionCode, permissionCode)
                .eq(SysPermission::getFlag, 1);
        return getOne(wrapper);
    }

    /**
     * 获取分配角色权限的权限列表
     * @param roleId 角色ID
     * @return 权限列表
     */
    @Override
    @RedisCache(key = "'permission:listForRoleTree:' + #roleId", expire = 1800)
    public List<PermissionTreeVO> listForRoleTree(String roleId) {
        SysRole role = sysRoleMapper.selectById(roleId);
        boolean isSuperAdmin = role != null && "SUPER_ADMIN".equals(role.getRoleCode());
        List<PermissionTreeVO> flatList = baseMapper.selectPermissionsWithRoleStatus(roleId, isSuperAdmin);
        return buildTree(flatList, null);
    }

    private List<PermissionTreeVO> buildTree(List<PermissionTreeVO> list, String parentId) {
        List<PermissionTreeVO> children = list.stream()
                .filter(node -> (parentId == null ? node.getParentId() == null : parentId.equals(node.getParentId())))
                .peek(node -> {
                    List<PermissionTreeVO> childList = buildTree(list, node.getId());
                    node.setChildren(childList);
                })
                .collect(java.util.stream.Collectors.toList());
        return children;
    }

    @Override
    public List<SysPermission> getPermissionIdsByRoleId(String roleId) {
        return baseMapper.selectPermissionsByRoleId(roleId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateRolePermissions(UpdateRolePermissionsRequestDTO requestDTO) {
        String roleId = requestDTO.getRoleId();
        List<String> permissionIds = requestDTO.getPermissionIds();
        // 删除原有权限
        baseMapper.deleteRolePermissionsByRoleId(roleId);
        // 批量插入新权限
        if (permissionIds != null && !permissionIds.isEmpty()) {
            List<SysRolePermission> list = new java.util.ArrayList<>();
            for (String pid : permissionIds) {
                SysRolePermission rp = new SysRolePermission();
                rp.setRoleId(roleId);
                rp.setPermissionId(pid);
                list.add(rp);
            }
            baseMapper.insertRolePermissionsBatch(list);
        }
        // 清理相关缓存
        cacheCleanUtils.clearRoleCache(roleId);
        cacheCleanUtils.clearUsersByRole(roleId);
    }
} 