package org.xyzh.achievement.service.impl;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.xyzh.achievement.checker.AchievementChecker;
import org.xyzh.achievement.mapper.AchievementMapper;
import org.xyzh.achievement.mapper.UserAchievementMapper;
import org.xyzh.achievement.mapper.UserAchievementProgressMapper;
import org.xyzh.api.achievement.AchievementService;
import org.xyzh.common.core.domain.LoginDomain;
import org.xyzh.common.core.domain.ResultDomain;
import org.xyzh.common.core.enums.AchievementEventType;
import org.xyzh.common.core.event.AchievementEvent;
import org.xyzh.common.core.page.PageDomain;
import org.xyzh.common.core.page.PageParam;
import org.xyzh.common.dto.user.TbSysUser;
import org.xyzh.common.dto.usercenter.TbAchievement;
import org.xyzh.common.dto.usercenter.TbUserAchievement;
import org.xyzh.common.dto.usercenter.TbUserAchievementProgress;
import org.xyzh.common.redis.service.RedisService;
import org.xyzh.common.utils.IDUtils;
import org.xyzh.common.vo.AchievementVO;
import org.xyzh.system.utils.LoginUtil;
import org.xyzh.api.system.permission.ResourcePermissionService;
import org.xyzh.common.vo.UserDeptRoleVO;
import org.xyzh.common.core.enums.ResourceType;

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

/**
 * @description 成就服务实现类
 * @filename ACHAchievementServiceImpl.java
 * @author yslg
 * @copyright xyzh
 * @since 2025-10-24
 */
@Service
public class ACHAchievementServiceImpl implements AchievementService {

    private static final Logger logger = LoggerFactory.getLogger(ACHAchievementServiceImpl.class);
    private static final String REDIS_LOGIN_PREFIX = "login:token:";

    @Autowired
    private AchievementMapper achievementMapper;

    @Autowired
    private UserAchievementMapper userAchievementMapper;

    @Autowired
    private UserAchievementProgressMapper progressMapper;

    @Autowired
    private List<AchievementChecker> checkers;

    @Autowired
    private ResourcePermissionService resourcePermissionService;
    
    @Autowired
    private RedisService redisService;

    // ==================== 成就定义管理 ====================

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultDomain<TbAchievement> createAchievement(TbAchievement achievement) {
        ResultDomain<TbAchievement> resultDomain = new ResultDomain<>();
        try {
            // 参数验证
            if (achievement == null || !StringUtils.hasText(achievement.getName())) {
                resultDomain.fail("成就名称不能为空");
                return resultDomain;
            }

            // 检查名称是否已存在
            List<UserDeptRoleVO> userDeptRoles = LoginUtil.getCurrentDeptRole();
            int count = achievementMapper.countByName(achievement.getName(), null, userDeptRoles);
            if (count > 0) {
                resultDomain.fail("成就名称已存在");
                return resultDomain;
            }

            // 设置默认值
            if (achievement.getID() == null) {
                achievement.setID(IDUtils.generateID());
            }
            if (achievement.getAchievementID() == null) {
                achievement.setAchievementID(IDUtils.generateID());
            }
            achievement.setCreateTime(new Date());
            achievement.setDeleted(false);

            // 插入数据库
            int result = achievementMapper.insertAchievement(achievement);
            if (result > 0) {
                // 创建成就资源权限
                try {
                    if (userDeptRoles != null && !userDeptRoles.isEmpty()) {
                        // 使用用户的第一个部门角色创建权限
                        resourcePermissionService.createResourcePermission(
                            ResourceType.ACHIEVEMENT.getCode(), 
                            achievement.getAchievementID(), 
                            userDeptRoles.get(0)
                        );
                        logger.info("创建成就权限成功: {}", achievement.getAchievementID());
                    }
                } catch (Exception e) {
                    logger.error("创建成就权限异常，但不影响成就创建: {}", e.getMessage(), e);
                }
                resultDomain.success("创建成就成功", achievement);
            } else {
                resultDomain.fail("创建成就失败");
            }
            return resultDomain;
        } catch (Exception e) {
            logger.error("创建成就异常: {}", e.getMessage(), e);
            resultDomain.fail("创建成就失败: " + e.getMessage());
            return resultDomain;
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultDomain<TbAchievement> updateAchievement(TbAchievement achievement) {
        ResultDomain<TbAchievement> resultDomain = new ResultDomain<>();
        try {
            // 参数验证
            if (achievement == null || !StringUtils.hasText(achievement.getAchievementID())) {
                resultDomain.fail("成就ID不能为空");
                return resultDomain;
            }

            // 检查成就是否存在
            TbAchievement existing = achievementMapper.selectByAchievementId(achievement.getAchievementID());
            if (existing == null) {
                resultDomain.fail("成就不存在");
                return resultDomain;
            }

            // 检查名称是否重复
            if (StringUtils.hasText(achievement.getName())) {
                List<UserDeptRoleVO> userDeptRoles = LoginUtil.getCurrentDeptRole();
                int count = achievementMapper.countByName(achievement.getName(), achievement.getAchievementID(), userDeptRoles);
                if (count > 0) {
                    resultDomain.fail("成就名称已存在");
                    return resultDomain;
                }
            }

            achievement.setUpdateTime(new Date());
            int result = achievementMapper.updateAchievement(achievement);
            if (result > 0) {
                resultDomain.success("更新成就成功", achievement);
            } else {
                resultDomain.fail("更新成就失败");
            }
            return resultDomain;
        } catch (Exception e) {
            logger.error("更新成就异常: {}", e.getMessage(), e);
            resultDomain.fail("更新成就失败: " + e.getMessage());
            return resultDomain;
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultDomain<Boolean> deleteAchievement(String achievementID) {
        ResultDomain<Boolean> resultDomain = new ResultDomain<>();
        try {
            if (!StringUtils.hasText(achievementID)) {
                resultDomain.fail("成就ID不能为空");
                return resultDomain;
            }

            TbAchievement achievement = achievementMapper.selectByAchievementId(achievementID);
            if (achievement == null) {
                resultDomain.fail("成就不存在");
                return resultDomain;
            }

            // 逻辑删除
            achievement.setDeleted(true);
            achievement.setDeleteTime(new Date());
            int result = achievementMapper.updateAchievement(achievement);
            
            if (result > 0) {
                resultDomain.success("删除成就成功", true);
            } else {
                resultDomain.fail("删除成就失败");
            }
            return resultDomain;
        } catch (Exception e) {
            logger.error("删除成就异常: {}", e.getMessage(), e);
            resultDomain.fail("删除成就失败: " + e.getMessage());
            return resultDomain;
        }
    }

    @Override
    public ResultDomain<TbAchievement> getAllAchievements(TbAchievement filter) {
        ResultDomain<TbAchievement> resultDomain = new ResultDomain<>();
        try {
            // 获取当前用户的部门角色
            List<UserDeptRoleVO> userDeptRoles = LoginUtil.getCurrentDeptRole();
            List<TbAchievement> list = achievementMapper.selectAchievements(filter, userDeptRoles);
            
            resultDomain.success("获取成就列表成功", list);
            return resultDomain;
        } catch (Exception e) {
            logger.error("获取成就列表异常: {}", e.getMessage(), e);
            resultDomain.fail("获取成就列表失败: " + e.getMessage());
            return resultDomain;
        }
    }

    @Override
    public ResultDomain<TbAchievement> getAchievementPage(TbAchievement filter, PageParam pageParam) {
        ResultDomain<TbAchievement> resultDomain = new ResultDomain<>();
        try {
            if (filter == null) {
                filter = new TbAchievement();
                filter.setDeleted(false);
            }
            
            // 获取当前用户的部门角色
            List<UserDeptRoleVO> userDeptRoles = LoginUtil.getCurrentDeptRole();
            List<TbAchievement> list = achievementMapper.selectAchievementsPage(filter, pageParam, userDeptRoles);
            long total = achievementMapper.countAchievements(filter, userDeptRoles);
            
            pageParam.setTotalElements(total);
            pageParam.setTotalPages((int) Math.ceil((double) total / pageParam.getPageSize()));
            
            resultDomain.success("获取成就分页成功", new PageDomain<>(pageParam, list));
            return resultDomain;
        } catch (Exception e) {
            logger.error("获取成就分页异常: {}", e.getMessage(), e);
            resultDomain.fail("获取成就分页失败: " + e.getMessage());
            return resultDomain;
        }
    }

    @Override
    public ResultDomain<TbAchievement> getAchievementDetail(String achievementID) {
        ResultDomain<TbAchievement> resultDomain = new ResultDomain<>();
        try {
            if (!StringUtils.hasText(achievementID)) {
                resultDomain.fail("成就ID不能为空");
                return resultDomain;
            }

            TbAchievement achievement = achievementMapper.selectByAchievementId(achievementID);
            if (achievement == null || achievement.getDeleted()) {
                resultDomain.fail("成就不存在");
                return resultDomain;
            }

            resultDomain.success("获取成就详情成功", achievement);
            return resultDomain;
        } catch (Exception e) {
            logger.error("获取成就详情异常: {}", e.getMessage(), e);
            resultDomain.fail("获取成就详情失败: " + e.getMessage());
            return resultDomain;
        }
    }

    // ==================== 用户成就管理 ====================

    @Override
    public ResultDomain<TbUserAchievement> getUserAchievements(String userID, Integer type) {
        ResultDomain<TbUserAchievement> resultDomain = new ResultDomain<>();
        try {
            if (!StringUtils.hasText(userID)) {
                resultDomain.fail("用户ID不能为空");
                return resultDomain;
            }

            List<TbUserAchievement> list;
            if (type != null) {
                list = userAchievementMapper.selectByUserIdAndType(userID, type);
            } else {
                list = userAchievementMapper.selectByUserId(userID);
            }

            resultDomain.success("获取用户成就成功", list);
            return resultDomain;
        } catch (Exception e) {
            logger.error("获取用户成就异常: {}", e.getMessage(), e);
            resultDomain.fail("获取用户成就失败: " + e.getMessage());
            return resultDomain;
        }
    }

    @Override
    public ResultDomain<TbUserAchievement> getMyAchievements(Integer type) {
        TbSysUser user = LoginUtil.getCurrentUser();
        if (user == null) {
            ResultDomain<TbUserAchievement> resultDomain = new ResultDomain<>();
            resultDomain.fail("请先登录");
            return resultDomain;
        }
        return getUserAchievements(user.getID(), type);
    }

    @Override
    public ResultDomain<AchievementVO> getMyAchievementsWithProgress(Integer type) {
        ResultDomain<AchievementVO> resultDomain = new ResultDomain<>();
        try {
            // 获取当前登录用户
            TbSysUser user = LoginUtil.getCurrentUser();
            if (user == null) {
                resultDomain.fail("请先登录");
                return resultDomain;
            }
            
            String userID = user.getID();
            
            // 使用联表查询一次性获取所有数据（包含成就、用户成就、进度信息及权限过滤）
            List<UserDeptRoleVO> userDeptRoles = LoginUtil.getCurrentDeptRole();
            List<AchievementVO> achievementVOList = achievementMapper.selectUserAchievementsWithProgress(
                userID, 
                type, 
                userDeptRoles
            );
            
            resultDomain.success("获取成就列表成功", achievementVOList);
            return resultDomain;
        } catch (Exception e) {
            logger.error("获取成就列表异常: {}", e.getMessage(), e);
            resultDomain.fail("获取成就列表失败: " + e.getMessage());
            return resultDomain;
        }
    }

    @Override
    public ResultDomain<Boolean> hasAchievement(String userID, String achievementID) {
        ResultDomain<Boolean> resultDomain = new ResultDomain<>();
        try {
            if (!StringUtils.hasText(userID) || !StringUtils.hasText(achievementID)) {
                resultDomain.fail("参数不能为空");
                return resultDomain;
            }

            TbUserAchievement userAchievement = userAchievementMapper.selectByUserIdAndAchievementId(userID, achievementID);
            resultDomain.success("检查成功", userAchievement != null);
            return resultDomain;
        } catch (Exception e) {
            logger.error("检查用户成就异常: {}", e.getMessage(), e);
            resultDomain.fail("检查用户成就失败: " + e.getMessage());
            return resultDomain;
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultDomain<TbUserAchievement> grantAchievement(String userID, String achievementID) {
        ResultDomain<TbUserAchievement> resultDomain = new ResultDomain<>();
        try {
            if (!StringUtils.hasText(userID) || !StringUtils.hasText(achievementID)) {
                resultDomain.fail("参数不能为空");
                return resultDomain;
            }

            // 检查成就是否存在
            TbAchievement achievement = achievementMapper.selectByAchievementId(achievementID);
            if (achievement == null || achievement.getDeleted()) {
                resultDomain.fail("成就不存在");
                return resultDomain;
            }

            // 检查用户是否已获得
            TbUserAchievement existing = userAchievementMapper.selectByUserIdAndAchievementId(userID, achievementID);
            if (existing != null) {
                resultDomain.fail("用户已获得该成就");
                return resultDomain;
            }

            // 创建用户成就记录
            TbUserAchievement userAchievement = new TbUserAchievement();
            userAchievement.setID(IDUtils.generateID());
            userAchievement.setUserID(userID);
            userAchievement.setAchievementID(achievementID);
            userAchievement.setObtainTime(new Date());

            int result = userAchievementMapper.insertUserAchievement(userAchievement);
            if (result > 0) {
                // 更新进度为完成
                updateProgressToCompleted(userID, achievementID);
                
                logger.info("用户 {} 获得成就: {}", userID, achievement.getName());
                resultDomain.success("授予成就成功", userAchievement);
            } else {
                resultDomain.fail("授予成就失败");
            }
            return resultDomain;
        } catch (Exception e) {
            logger.error("授予成就异常: {}", e.getMessage(), e);
            resultDomain.fail("授予成就失败: " + e.getMessage());
            return resultDomain;
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultDomain<Boolean> revokeAchievement(String userID, String achievementID) {
        ResultDomain<Boolean> resultDomain = new ResultDomain<>();
        try {
            if (!StringUtils.hasText(userID) || !StringUtils.hasText(achievementID)) {
                resultDomain.fail("参数不能为空");
                return resultDomain;
            }

            int result = userAchievementMapper.deleteByUserIdAndAchievementId(userID, achievementID);
            if (result > 0) {
                // 重置进度
                progressMapper.deleteProgress(userID, achievementID);
                resultDomain.success("撤销成就成功", true);
            } else {
                resultDomain.fail("撤销成就失败");
            }
            return resultDomain;
        } catch (Exception e) {
            logger.error("撤销成就异常: {}", e.getMessage(), e);
            resultDomain.fail("撤销成就失败: " + e.getMessage());
            return resultDomain;
        }
    }

    // ==================== 成就进度管理 ====================

    @Override
    public ResultDomain<TbUserAchievementProgress> getUserAchievementProgress(String userID, String achievementID) {
        ResultDomain<TbUserAchievementProgress> resultDomain = new ResultDomain<>();
        try {
            if (!StringUtils.hasText(userID)) {
                resultDomain.fail("用户ID不能为空");
                return resultDomain;
            }

            List<TbUserAchievementProgress> list;
            if (StringUtils.hasText(achievementID)) {
                TbUserAchievementProgress progress = progressMapper.selectByUserIdAndAchievementId(userID, achievementID);
                list = progress != null ? Collections.singletonList(progress) : new ArrayList<>();
            } else {
                list = progressMapper.selectByUserId(userID);
            }

            resultDomain.success("获取成就进度成功", list);
            return resultDomain;
        } catch (Exception e) {
            logger.error("获取成就进度异常: {}", e.getMessage(), e);
            resultDomain.fail("获取成就进度失败: " + e.getMessage());
            return resultDomain;
        }
    }

    @Override
    public ResultDomain<TbUserAchievementProgress> getMyAchievementProgress(String achievementID) {
        TbSysUser user = LoginUtil.getCurrentUser();
        if (user == null) {
            ResultDomain<TbUserAchievementProgress> resultDomain = new ResultDomain<>();
            resultDomain.fail("请先登录");
            return resultDomain;
        }
        return getUserAchievementProgress(user.getID(), achievementID);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultDomain<TbUserAchievementProgress> updateProgress(String userID, String achievementID, Integer incrementValue) {
        ResultDomain<TbUserAchievementProgress> resultDomain = new ResultDomain<>();
        try {
            if (!StringUtils.hasText(userID) || !StringUtils.hasText(achievementID)) {
                resultDomain.fail("参数不能为空");
                return resultDomain;
            }

            // 获取或创建进度记录
            TbUserAchievementProgress progress = getOrCreateProgress(userID, achievementID);
            if (progress == null) {
                resultDomain.fail("获取进度失败");
                return resultDomain;
            }

            // 更新进度
            progress.setCurrentValue(progress.getCurrentValue() + incrementValue);
            progress.setLastUpdateTime(new Date());
            progressMapper.updateProgress(progress);

            resultDomain.success("更新进度成功", progress);
            return resultDomain;
        } catch (Exception e) {
            logger.error("更新进度异常: {}", e.getMessage(), e);
            resultDomain.fail("更新进度失败: " + e.getMessage());
            return resultDomain;
        }
    }

    // ==================== 成就检测与触发 ====================

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultDomain<TbUserAchievement> processAchievementEvent(AchievementEvent event) {
        ResultDomain<TbUserAchievement> resultDomain = new ResultDomain<>();
        List<TbUserAchievement> newAchievements = new ArrayList<>();
        
        try {
            if (event == null || !StringUtils.hasText(event.getUserID()) || event.getEventType() == null) {
                resultDomain.fail("事件参数不完整");
                return resultDomain;
            }

            logger.debug("处理成就事件: {}", event);

            // 获取该事件类型相关的所有成就
            // 传入 userID，在异步线程中根据 userID 查询用户部门角色
            List<TbAchievement> achievements = getAchievementsByEventType(event.getEventType(), event.getUserID());
            if (achievements.isEmpty()) {
                resultDomain.success("无相关成就", newAchievements);
                return resultDomain;
            }

            // 遍历每个成就进行检测
            for (TbAchievement achievement : achievements) {
                // 检查用户是否已获得
                if (userAchievementMapper.selectByUserIdAndAchievementId(event.getUserID(), achievement.getAchievementID()) != null) {
                    continue; // 已获得，跳过
                }

                // 获取合适的检测器
                AchievementChecker checker = getCheckerForAchievement(achievement);
                if (checker == null || !checker.supportsEventType(event.getEventType())) {
                    continue;
                }

                // 获取当前进度
                TbUserAchievementProgress progress = getOrCreateProgress(event.getUserID(), achievement.getAchievementID());
                Integer currentProgress = progress.getCurrentValue();

                // 计算新进度
                Integer newProgress = checker.calculateNewProgress(event, currentProgress);
                
                // 更新进度
                progress.setCurrentValue(newProgress);
                progress.setTargetValue(achievement.getConditionValue());
                progress.setLastUpdateTime(new Date());
                progressMapper.updateProgress(progress);

                // 检查是否达成
                if (checker.check(event, achievement, currentProgress)) {
                    TbUserAchievement userAchievement = grantAchievementInternal(event.getUserID(), achievement.getAchievementID());
                    if (userAchievement != null) {
                        newAchievements.add(userAchievement);
                        logger.info("用户 {} 通过事件 {} 获得成就: {}", event.getUserID(), event.getEventType(), achievement.getName());
                    }
                }
            }

            resultDomain.success("处理成就事件成功", newAchievements);
            return resultDomain;
        } catch (Exception e) {
            logger.error("处理成就事件异常: {}", e.getMessage(), e);
            resultDomain.fail("处理成就事件失败: " + e.getMessage());
            return resultDomain;
        }
    }

    @Override
    public ResultDomain<Boolean> checkAchievementCondition(String userID, String achievementID) {
        ResultDomain<Boolean> resultDomain = new ResultDomain<>();
        try {
            if (!StringUtils.hasText(userID) || !StringUtils.hasText(achievementID)) {
                resultDomain.fail("参数不能为空");
                return resultDomain;
            }

            // 获取成就定义
            TbAchievement achievement = achievementMapper.selectByAchievementId(achievementID);
            if (achievement == null) {
                resultDomain.fail("成就不存在");
                return resultDomain;
            }

            // 获取进度
            TbUserAchievementProgress progress = progressMapper.selectByUserIdAndAchievementId(userID, achievementID);
            Integer currentValue = progress != null ? progress.getCurrentValue() : 0;
            Integer targetValue = achievement.getConditionValue();

            boolean satisfied = currentValue >= targetValue;
            resultDomain.success("检查完成", satisfied);
            return resultDomain;
        } catch (Exception e) {
            logger.error("检查成就条件异常: {}", e.getMessage(), e);
            resultDomain.fail("检查成就条件失败: " + e.getMessage());
            return resultDomain;
        }
    }

    @Override
    public ResultDomain<TbAchievement> checkAvailableAchievements(String userID) {
        ResultDomain<TbAchievement> resultDomain = new ResultDomain<>();
        try {
            if (!StringUtils.hasText(userID)) {
                resultDomain.fail("用户ID不能为空");
                return resultDomain;
            }

            // 获取所有成就
            TbAchievement filter = new TbAchievement();
            filter.setDeleted(false);
            List<UserDeptRoleVO> userDeptRoles = LoginUtil.getCurrentDeptRole();
            List<TbAchievement> allAchievements = achievementMapper.selectAchievements(filter, userDeptRoles);

            // 获取用户进度
            List<TbUserAchievementProgress> progressList = progressMapper.selectIncompletedByUserId(userID);
            Map<String, Integer> progressMap = progressList.stream()
                .collect(Collectors.toMap(
                    TbUserAchievementProgress::getAchievementID,
                    TbUserAchievementProgress::getCurrentValue
                ));

            // 筛选可获得的成就
            List<TbAchievement> availableAchievements = allAchievements.stream()
                .filter(achievement -> {
                    Integer currentValue = progressMap.getOrDefault(achievement.getAchievementID(), 0);
                    return currentValue >= achievement.getConditionValue();
                })
                .collect(Collectors.toList());

            resultDomain.success("检查可获得成就成功", availableAchievements);
            return resultDomain;
        } catch (Exception e) {
            logger.error("检查可获得成就异常: {}", e.getMessage(), e);
            resultDomain.fail("检查可获得成就失败: " + e.getMessage());
            return resultDomain;
        }
    }

    // ==================== 成就统计 ====================

    @Override
    public ResultDomain<Map<String, Object>> getUserAchievementStatistics(String userID) {
        ResultDomain<Map<String, Object>> resultDomain = new ResultDomain<>();
        try {
            if (!StringUtils.hasText(userID)) {
                resultDomain.fail("用户ID不能为空");
                return resultDomain;
            }

            Map<String, Object> statistics = userAchievementMapper.selectAchievementStatistics(userID);
            if (statistics == null) {
                statistics = new HashMap<>();
                statistics.put("totalAchievements", 0);
                statistics.put("totalPoints", 0);
            }

            resultDomain.success("获取统计信息成功", statistics);
            return resultDomain;
        } catch (Exception e) {
            logger.error("获取统计信息异常: {}", e.getMessage(), e);
            resultDomain.fail("获取统计信息失败: " + e.getMessage());
            return resultDomain;
        }
    }

    @Override
    public ResultDomain<Map<String, Object>> getAchievementRanking(Integer limit) {
        ResultDomain<Map<String, Object>> resultDomain = new ResultDomain<>();
        try {
            if (limit == null || limit <= 0) {
                limit = 10; // 默认10条
            }

            List<Map<String, Object>> ranking = userAchievementMapper.selectUserAchievementRanking(limit);
            
            Map<String, Object> result = new HashMap<>();
            result.put("ranking", ranking);
            result.put("limit", limit);
            
            resultDomain.success("获取排行榜成功", result);
            return resultDomain;
        } catch (Exception e) {
            logger.error("获取排行榜异常: {}", e.getMessage(), e);
            resultDomain.fail("获取排行榜失败: " + e.getMessage());
            return resultDomain;
        }
    }

    @Override
    public ResultDomain<TbUserAchievement> getRecentAchievers(TbUserAchievement filter, PageParam pageParam) {
        ResultDomain<TbUserAchievement> resultDomain = new ResultDomain<>();
        try {
            List<TbUserAchievement> achievers = userAchievementMapper.selectUserAchievementsPage(filter, pageParam);
            resultDomain.success("获取最近获得者成功", achievers);
            return resultDomain;
        } catch (Exception e) {
            logger.error("获取最近获得者异常: {}", e.getMessage(), e);
            resultDomain.fail("获取最近获得者失败: " + e.getMessage());
            return resultDomain;
        }
    }

    // ==================== 私有辅助方法 ====================

    /**
     * 获取或创建进度记录
     */
    private TbUserAchievementProgress getOrCreateProgress(String userID, String achievementID) {
        TbUserAchievementProgress progress = progressMapper.selectByUserIdAndAchievementId(userID, achievementID);
        if (progress == null) {
            // 创建新的进度记录
            TbAchievement achievement = achievementMapper.selectByAchievementId(achievementID);
            if (achievement == null) {
                return null;
            }

            progress = new TbUserAchievementProgress();
            progress.setID(IDUtils.generateID());
            progress.setUserID(userID);
            progress.setAchievementID(achievementID);
            progress.setCurrentValue(0);
            progress.setTargetValue(achievement.getConditionValue());
            progress.setCompleted(false);
            progress.setLastUpdateTime(new Date());
            progress.setCreateTime(new Date());
            
            progressMapper.insertProgress(progress);
        }
        return progress;
    }

    /**
     * 更新进度为已完成
     */
    private void updateProgressToCompleted(String userID, String achievementID) {
        TbUserAchievementProgress progress = progressMapper.selectByUserIdAndAchievementId(userID, achievementID);
        if (progress != null) {
            progress.setCompleted(true);
            progress.setCurrentValue(progress.getTargetValue());
            progress.setLastUpdateTime(new Date());
            progressMapper.updateProgress(progress);
        }
    }

    /**
     * 内部授予成就方法（不检查是否已获得）
     */
    private TbUserAchievement grantAchievementInternal(String userID, String achievementID) {
        try {
            TbUserAchievement userAchievement = new TbUserAchievement();
            userAchievement.setID(IDUtils.generateID());
            userAchievement.setUserID(userID);
            userAchievement.setAchievementID(achievementID);
            userAchievement.setObtainTime(new Date());

            int result = userAchievementMapper.insertUserAchievement(userAchievement);
            if (result > 0) {
                updateProgressToCompleted(userID, achievementID);
                return userAchievement;
            }
            return null;
        } catch (Exception e) {
            logger.error("内部授予成就失败: {}", e.getMessage(), e);
            return null;
        }
    }

    /**
     * 根据事件类型获取相关成就
     * @param eventType 事件类型
     * @param userID 用户ID（用于在异步线程中从Redis获取用户登录信息）
     */
    private List<TbAchievement> getAchievementsByEventType(AchievementEventType eventType, String userID) {
        // 获取所有成就
        TbAchievement filter = new TbAchievement();
        filter.setDeleted(false);
        
        // 【关键优化】在异步线程中从Redis缓存获取用户的LoginDomain
        // 避免数据库查询，性能更好
        List<UserDeptRoleVO> userDeptRoles = new ArrayList<>();
        
        if (StringUtils.hasText(userID)) {
            try {
                // 从Redis获取用户登录信息
                String redisKey = REDIS_LOGIN_PREFIX + userID;
                LoginDomain loginDomain = (LoginDomain) redisService.get(redisKey);
                
                if (loginDomain != null && loginDomain.getRoles() != null) {
                    userDeptRoles = loginDomain.getRoles();
                    logger.debug("从Redis缓存获取用户部门角色成功，userID: {}, 角色数: {}", 
                        userID, userDeptRoles.size());
                } else {
                    logger.warn("Redis缓存中未找到用户登录信息或角色为空，userID: {}", userID);
                }
            } catch (Exception e) {
                logger.error("从Redis获取用户部门角色异常，userID: {}", userID, e);
            }
        } else {
            logger.warn("userID为空，无法获取用户部门角色");
        }
        
        List<TbAchievement> allAchievements = achievementMapper.selectAchievements(filter, userDeptRoles);

        // 筛选支持该事件类型的成就
        return allAchievements.stream()
            .filter(achievement -> {
                AchievementChecker checker = getCheckerForAchievement(achievement);
                return checker != null && checker.supportsEventType(eventType);
            })
            .collect(Collectors.toList());
    }

    /**
     * 获取成就对应的检测器
     */
    private AchievementChecker getCheckerForAchievement(TbAchievement achievement) {
        for (AchievementChecker checker : checkers) {
            if (checker.supports(achievement)) {
                return checker;
            }
        }
        return null;
    }
}

