package com.CUST.brain.service.impl;

import com.CUST.brain.common.annotation.RedisCache;
import com.CUST.brain.common.exception.BusinessException;
import com.CUST.brain.dao.domain.system.SysRole;
import com.CUST.brain.dao.mapper.SysRoleMapper;
import com.CUST.brain.service.SysRoleService;
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 com.CUST.brain.dao.mapper.SysUserRoleMapper;
import com.CUST.brain.common.utils.RedisUtils;
import javax.annotation.Resource;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.commons.lang3.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.CUST.brain.common.utils.CacheCleanUtils;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import com.fasterxml.jackson.core.type.TypeReference;

import java.util.List;

@Service
public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> implements SysRoleService {
    private static final Logger log = LoggerFactory.getLogger(SysRoleServiceImpl.class);

    @Resource
    private RedisUtils redisUtils;
    @Resource
    private SysUserRoleMapper sysUserRoleMapper;
    @Resource
    private CacheCleanUtils cacheCleanUtils;

    @Resource
    private SysRoleMapper sysRoleMapper;

    @Autowired
    private ObjectMapper objectMapper;

    @Override
    @RedisCache(key = "'user:roles:' + #p0", expire = 1800, cacheNull = true)
    public List<SysRole> getRolesByUserId(String userId) {
        String cacheKey = "cache:user:roles:" + userId;
        Object obj = redisUtils.get(cacheKey);
        if (obj != null) {
            try {
                return objectMapper.readValue(obj.toString(), new TypeReference<List<SysRole>>(){});
            } catch (Exception e) {
                log.error("角色缓存反序列化失败", e);
                // 反序列化失败时可选择清理缓存或降级为数据库查询
            }
        }
        return baseMapper.selectRolesByUserId(userId);
    }

    @Override
    public SysRole getByRoleCode(String roleCode) {
        LambdaQueryWrapper<SysRole> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysRole::getRoleCode, roleCode)
                .eq(SysRole::getFlag, 0);
        return getOne(wrapper);
    }

    @Override
    public void addRole(SysRole role) {
        save(role);
    }

    @Override
    public void updateRole(SysRole role) {
        updateById(role);
        cacheCleanUtils.clearUsersByRole(role.getId());
        cacheCleanUtils.clearRoleCache(role.getId());
    }

    @Override
    public void deleteRole(String roleId) {
        SysRole role = getById(roleId);
        if (role != null && "USER".equals(role.getRoleCode())) {
            throw new BusinessException(400, "基础角色不能被删除");
        }
        if (role != null && "SUPER_ADMIN".equals(role.getRoleCode())) {
            throw new BusinessException(400, "超级管理员不能被删除");
        }
        removeById(roleId);
        cacheCleanUtils.clearUsersByRole(roleId);
        cacheCleanUtils.clearRoleCache(roleId);
    }

    public void disableRole(String roleId) {
        SysRole role = getById(roleId);
        if (role != null && "USER".equals(role.getRoleCode())) {
            throw new BusinessException(400, "基础角色不能被禁用");
        }
        if (role != null && "SUPER_ADMIN".equals(role.getRoleCode())) {
            throw new BusinessException(400, "超级管理员不能被禁用");
        }
        int count = sysRoleMapper.disableRole(roleId);
        if (count == 0) {
            throw new BusinessException(400, "禁用失败，角色不存在或未被删除");
        }
        cacheCleanUtils.clearRoleCache(roleId);
        cacheCleanUtils.clearUsersByRole(roleId);
    }

    public void restoreRole(String roleId) {
        int count = sysRoleMapper.restoreRole(roleId);
        if (count == 0) {
            throw new BusinessException(400, "恢复失败，角色不存在或未被删除");
        }
        cacheCleanUtils.clearRoleCache(roleId);
        cacheCleanUtils.clearUsersByRole(roleId);
    }

    @Override
    @RedisCache(key = "'sys:role:detail:' + #p0", expire = 1800)
    public SysRole getRoleDetail(String roleId) {
        log.debug("SysRoleServiceImpl.getRoleDetail 入参: {}", roleId);
        SysRole role = getById(roleId);
        if (role == null) {
            log.warn("SysRoleServiceImpl.getRoleDetail 未找到角色信息, roleId: {}", roleId);
            return null;
        }
        log.debug("SysRoleServiceImpl.getRoleDetail 查询结果: {}", role);
        return role;
    }

    @Override
    public Page<SysRole> pageRoles(Integer pageNum, Integer pageSize, String roleName, String roleCode, Integer status) {
        Page<SysRole> page = new Page<>(pageNum, pageSize);
        LambdaQueryWrapper<SysRole> wrapper = new LambdaQueryWrapper<>();
        
        // 构建查询条件
        wrapper.eq(SysRole::getFlag, 0)  // 未删除的记录
               .like(StringUtils.isNotBlank(roleName), SysRole::getRoleName, roleName)
               .like(StringUtils.isNotBlank(roleCode), SysRole::getRoleCode, roleCode)
               .eq(status != null, SysRole::getStatus, status)
               .orderByAsc(SysRole::getSort);  // 按排序字段升序
        
        // 执行分页查询
        Page<SysRole> result = page(page, wrapper);
        log.debug("SysRoleServiceImpl.pageRoles 查询结果: {}", result);
        return result;
    }

    @Override
    @RedisCache(key = "'sys:role:select:' + (#p0 != null ? #p0 : '') + ':' + (#p1 != null ? #p1 : '')", expire = 1800)
    public List<SysRole> listRoles(String roleName, Integer status) {
        log.debug("SysRoleServiceImpl.listRoles 入参: roleName={}, status={}", roleName, status);
        
        QueryWrapper<SysRole> wrapper = new QueryWrapper<>();
        wrapper.select("id", "role_name", "role_code")  // 只查询需要的字段
               .eq("flag", 0)  // 未删除的记录
               .like(StringUtils.isNotBlank(roleName), "role_name", roleName)
               .eq(status != null, "status", status)
               .orderByAsc("sort");  // 按排序字段升序
        
        List<SysRole> roles = list(wrapper);
        log.debug("SysRoleServiceImpl.listRoles 查询结果: {}", roles);
        return roles;
    }
} 