package com.fs.his.service.impl;

import com.fs.common.core.domain.R;
import com.fs.course.domain.FsCourseRedPacketLog;
import com.fs.course.mapper.FsCourseRedPacketLogMapper;
import com.fs.his.domain.FsPackage;
import com.fs.his.mapper.FsPackageMapper;
import com.fs.hisStore.domain.FsStoreProductScrm;
import com.fs.hisStore.mapper.FsStoreProductScrmMapper;
import me.chanjar.weixin.common.util.locks.RedisTemplateSimpleDistributedLock;
import com.fs.app.domain.FsAppRole;
import com.fs.app.mapper.FsAppRoleMapper;
import com.fs.common.core.redis.RedisCache;
import com.fs.common.exception.CustomException;
import com.fs.common.utils.DateUtils;
import com.fs.his.domain.FsUser;
import com.fs.his.domain.FsUserRewards;
import com.fs.his.dto.ClaimRewardsAddDTO;
import com.fs.his.enums.ActivityTypeEnum;
import com.fs.his.mapper.FsUserMapper;
import com.fs.his.mapper.FsUserRewardsMapper;
import com.fs.his.service.IAppUserRewardService;
import com.fs.his.strategy.RewardResult;
import com.fs.his.strategy.RewardStrategy;
import com.fs.his.strategy.RewardStrategyFactory;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.TimeUnit;

@Slf4j
@Service
public class AppUserRewardServiceImpl implements IAppUserRewardService {

    @Autowired
    private FsUserRewardsMapper rewardsMapper;

    @Autowired
    private FsUserMapper fsUserMapper;

    @Autowired
    private FsAppRoleMapper appRoleMapper;

    @Autowired
    private ObjectMapper objectMapper;

    @Autowired
    private RewardStrategyFactory strategyFactory;

    @Autowired
    private RedisCache redisCache;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private FsCourseRedPacketLogMapper redPacketLogMapper;

    @Autowired
    private FsPackageMapper fsPackageMapper;
    
    @Autowired
    private FsStoreProductScrmMapper fsStoreProductMapper;

    /** App用户每天的有效看课标识*/
    private static final String APP_WATCH_COURSE_DAY_KEY = "app:watch:course:day:";

    /**  下发奖励锁 */
    private static final String LOCK_WATCH_REWARD_KEY = "lock:watch:reward:";

    @Override
    @Transactional(rollbackFor = Exception.class)
    public R claimRewards(ClaimRewardsAddDTO claimRewardsAddDTO) {
        Long fsUserId = claimRewardsAddDTO.getFsUserId();
        Long rewardsId = claimRewardsAddDTO.getRewardsId();
        FsUserRewards reward = rewardsMapper.selectByUserIdAndRewardsIdForUpdate(claimRewardsAddDTO.getFsUserId(), rewardsId);
        if (reward == null) {
            log.info("用户:{}没有可领取的奖品:{}", fsUserId, rewardsId);
            return R.error("操作频繁，请稍后再试！");
        }
        if (reward.getStatus() == 1 || reward.getStatus() == 2) {
            log.info("用户:{}奖品已领取: rewardsId={}", fsUserId, rewardsId);
            return R.error("操作频繁，请稍后再试！");
        }
        // 校验是否过期（目前只有看课奖品需要校验过期）
        if (ActivityTypeEnum.WATCH_COURSE.getCode().equals(reward.getActivityType())) {
            if (isExpired(reward)) {
                log.info("奖品已过期: rewardsId={}", rewardsId);
                // 更新奖品状态为已过期
                rewardsMapper.updateStatus(reward.getId(), 2, null, null);
                return R.error("操作频繁，请稍后再试！");
            }
        }
        reward.setAddressId(claimRewardsAddDTO.getAddressId());
        //执行奖品领取逻辑(红包、积分、商品)
        RewardStrategy strategy = strategyFactory.getStrategy(reward.getActivityType(), reward.getRewardType());
        RewardResult result = strategy.process(reward);
        if (result.isSuccess()) {
            // 更新奖品状态
            rewardsMapper.updateStatus(rewardsId, 1, result.getOrderCode(), DateUtils.getNowDate());
            log.info("奖品领取成功: rewardsId={}, orderCode={}", rewardsId, result.getOrderCode());
            // 构建统一的返回对象
            R response = R.ok();

            // 如果是红包类型，从extData中提取需要的信息放入返回对象
            //if (reward.getRewardType() == 1) return result.getExtData();
            if (reward.getRewardType() == 1 && result.getExtData() != null) {
                R extR = result.getExtData();
                // 创建一个data对象存放特定字段
                Map<String, Object> dataMap = new HashMap<>();

                // 只提取需要的字段放入data
                if (extR.containsKey("packageInfo")) {
                    dataMap.put("packageInfo", extR.get("packageInfo"));
                }
                if (extR.containsKey("mchId")) {
                    dataMap.put("mchId", extR.get("mchId"));
                }
                if (extR.containsKey("appId")) {
                    dataMap.put("appId", extR.get("appId"));
                }

                // 将data放入response
                response.put("data", dataMap);
            }
            return response;
        } else {
            log.error("奖品领取失败: rewardsId={}, reason={}", rewardsId, result.getMessage());
            throw new CustomException(result.getMessage(), result.getCode());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addUserFirstLoginRewards(Long fsUserId) {
        String activityType = ActivityTypeEnum.FIRST_LOGIN.getCode();

        FsAppRole appRoleConfig = getAppRoleConfigFirstRegister(fsUserId);
        if (appRoleConfig == null) {
            log.info("登录注册奖励-当前用户未匹配到App奖励角色");
            return;
        }
        // 构建奖品记录
        FsUserRewards reward = buildAppUserReward(fsUserId, activityType, appRoleConfig, null, null);
        try {
            // 插入奖品表
            int insertResult = rewardsMapper.insertFsUserRewards(reward);
            if (insertResult > 0) {
                // 更新用户表的首次登录时间
                FsUser updateFsUser = new FsUser();
                updateFsUser.setUserId(fsUserId);
                updateFsUser.setFirstLoginTime(DateUtils.getNowDate());

                int updateResult = fsUserMapper.updateFsUser(updateFsUser);

                if (updateResult > 0) {
                    log.info("用户首次注册奖励发放成功: userId={}, rewardType={}, rewardsId={}",
                            fsUserId, reward.getRewardType(), reward.getId());
                } else {
                    log.error("用户首次登录时间更新失败: userId={}, 但奖品已发放, rewardsId={}",
                            fsUserId, reward.getId());
                }
            }
        } catch (DuplicateKeyException e) {
            log.info("用户首次注册奖励已存在: userId={}", fsUserId);
        } catch (Exception e) {
            log.error("用户首次注册奖励发放异常: userId={}, error={}", fsUserId, e.getMessage(), e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addUserWatchCourseRewards(Long fsUserId, Long videoId) {
        String watchCourseKey = APP_WATCH_COURSE_DAY_KEY + fsUserId;
        Object cacheObject = redisCache.getCacheObject(watchCourseKey);
        if (cacheObject == null) {
            log.info("用户:{}今日无有效看课记录", fsUserId);
            return;
        }
        // 1. 生成锁的key：用户ID+视频ID
        String lockKey = LOCK_WATCH_REWARD_KEY + fsUserId + ":" + videoId;
        // 2. 创建分布式锁，设置10秒过期
        RedisTemplateSimpleDistributedLock lock = new RedisTemplateSimpleDistributedLock(
                stringRedisTemplate, lockKey, 10000); // 10秒
        boolean locked = false;
        try {
            // 3. 尝试获取锁
            locked = lock.tryLock();
            if (!locked) {
                log.warn("获取分布式锁失败，可能有其他请求正在处理: userId={}, videoId={}", fsUserId, videoId);
                throw new CustomException("系统处理中，请勿重复操作");
            }

            log.info("获取分布式锁成功: userId={}, videoId={}, secret={}",
                    fsUserId, videoId, lock.getLockSecretValue());

            String toDay = DateUtils.getDate();
            // 4. 双重检查：再次确认是否已发放过奖励（防止锁内重复）
            FsUserRewards existingReward = rewardsMapper.selectByUserIdAndVideoId(fsUserId, videoId, toDay);
            if (existingReward != null) {
                log.info("看课奖励已存在，不再重复发放: userId={}, videoId={}", fsUserId, videoId);
                return;
            }

            // 5. 原有的业务逻辑
            String activityType = ActivityTypeEnum.WATCH_COURSE.getCode();

            // 根据配置获取奖品类型、金额等
            FsAppRole appRoleConfig = getAppRoleConfigWatchCourse(fsUserId);
            if (appRoleConfig == null) {
                log.info("看课奖励-当前用户未匹配到App角色");
                return;
            }

            // 构建奖品记录
            FsUserRewards reward = buildAppUserReward(fsUserId, activityType, appRoleConfig, videoId, toDay);

            // 插入奖品表
            try {
                int insertResult = rewardsMapper.insertFsUserRewards(reward);
                if (insertResult > 0) {
                    log.info("用户看课奖励发放成功: userId={}, rewardType={}, rewardsId={}",
                            fsUserId, reward.getRewardType(), reward.getId());
                } else {
                    log.error("用户看课奖励发放失败: userId={}", fsUserId);
                }
            } catch (DuplicateKeyException e) {
                // 6. 唯一索引兜底
                log.warn("看课奖励唯一索引冲突，已存在记录: userId={}, videoId={}", fsUserId, videoId);
            }

        } catch (DuplicateKeyException e) {
            log.warn("看课奖励唯一索引冲突: userId={}, videoId={}", fsUserId, videoId);
        } catch (Exception e) {
            log.error("看课奖励发放异常: userId={}, videoId={}", fsUserId, videoId, e);
            throw new CustomException("奖励发放失败，请稍后重试");
        } finally {
            // 7. 释放锁
            if (locked) {
                try {
                    lock.unlock();
                    log.debug("释放分布式锁: key={}", lockKey);
                } catch (Exception e) {
                    log.error("释放分布式锁异常: key={}", lockKey, e);
                }
            }
        }
    }

    /**
     * 根据活动类型和角色配置，构建奖品记录
     *
     * @param fsUserId      用户ID
     * @param activityType  活动类型
     * @param appRoleConfig 角色配置
     */
    private FsUserRewards buildAppUserReward(Long fsUserId, String activityType, FsAppRole appRoleConfig, Long videoId, String toDay) {
        FsUserRewards reward = new FsUserRewards();
        reward.setFsUserId(fsUserId);
        reward.setActivityType(activityType);
        reward.setStatus(0); // 待领取
        reward.setCreateTime(DateUtils.getNowDate());
        // 根据活动类型设置不同字段
        if (ActivityTypeEnum.FIRST_LOGIN.getCode().equals(activityType)) {
            // 首次登录奖励
            reward.setIsFirstLogin(1); // 标记为首次注册奖励

            // 首次登录用 register 相关字段
            reward.setRewardType(appRoleConfig.getRegisterRewardType());

            if (appRoleConfig.getRegisterRewardType() == 1) { // 红包
                reward.setRewardAmount(appRoleConfig.getRegisterRedPacket());
            } else if (appRoleConfig.getRegisterRewardType() == 2) { // 积分
                reward.setRewardPoints(appRoleConfig.getRegisterIntegral() != null ?
                        appRoleConfig.getRegisterIntegral().longValue() : 0L);
            } else if (appRoleConfig.getRegisterRewardType() == 3) { // 实物商品
                reward.setProductType(appRoleConfig.getRegisterProductType());
                reward.setGoodsId(appRoleConfig.getRegisterProductId());
                reward.setGoodsName(appRoleConfig.getGoodsName());
                reward.setGoodsUrl(appRoleConfig.getGoodsUrl());
            }

        } else if (ActivityTypeEnum.WATCH_COURSE.getCode().equals(activityType)) {
            // 看课奖励
            reward.setRewardType(appRoleConfig.getCourseRewardType());
            reward.setVideoId(videoId);
            reward.setRewardDate(toDay);
            // 获取当前用户的有效看课天数
            FsUser fsUser = fsUserMapper.selectFsUserById(fsUserId);
            if (fsUser == null) {
                log.info("用户不存在,用户id:{}", fsUserId);
                return reward;
            }
            //Integer targetDay = fsUser.getAppRewardsViewedDays() == null ? 0 : fsUser.getAppRewardsViewedDays();

            // 根据奖品类型设置具体值
            if (appRoleConfig.getCourseRewardType() == 1) { // 红包
                //BigDecimal amount = calculateRewardValue(appRoleConfig, targetDay, true);
                BigDecimal amount = appRoleConfig.getCourseRedPacket();
                reward.setRewardAmount(amount);
            } else if (appRoleConfig.getCourseRewardType() == 2) { // 积分
                //Long points = calculateRewardValue(appRoleConfig, targetDay, false);
                Long points = appRoleConfig.getCourseIntegral().longValue();
                reward.setRewardPoints(points);
            } else if (appRoleConfig.getCourseRewardType() == 3) { // 实物商品
                reward.setProductType(appRoleConfig.getCourseProductType());
                reward.setGoodsId(appRoleConfig.getCourseProductId());
                reward.setGoodsName(appRoleConfig.getGoodsName());
                reward.setGoodsUrl(appRoleConfig.getGoodsUrl());
            }
        }

        return reward;
    }

    /**
     * 计算奖励值（红包或积分）
     *
     * @param appRoleConfig 角色配置
     * @param targetDay     目标天数
     * @param isRedPackage  true-红包，false-积分
     */
    private <T extends Number> T calculateRewardValue(FsAppRole appRoleConfig, Integer targetDay, boolean isRedPackage) {
        if (appRoleConfig.getCourseRewardRuleType() == 2) {
            // 定制规则
            String courseRewardRule = appRoleConfig.getCourseRewardRule();
            if (courseRewardRule == null || courseRewardRule.isEmpty()) {
                return isRedPackage ? (T) BigDecimal.ZERO : (T) Long.valueOf(0L);
            }

            try {
                List<Map<String, Object>> rewardList = objectMapper.readValue(
                        courseRewardRule,
                        new TypeReference<List<Map<String, Object>>>() {
                        }
                );

                for (Map<String, Object> item : rewardList) {
                    Integer day = ((Number) item.get("day")).intValue();
                    if (day.equals(targetDay)) {
                        if (isRedPackage) {
                            return (T) new BigDecimal(item.get("value").toString());
                        } else {
                            return (T) Long.valueOf(((Number) item.get("value")).longValue());
                        }
                    }
                }
                return isRedPackage ? (T) BigDecimal.ZERO : (T) Long.valueOf(0L);

            } catch (Exception e) {
                log.error("解析规则失败: {}", courseRewardRule, e);
                return isRedPackage ? (T) BigDecimal.ZERO : (T) Long.valueOf(0L);
            }
        } else {
            // 平均规则
            if (isRedPackage) {
                BigDecimal total = appRoleConfig.getCourseRedPacket();
                Long days = appRoleConfig.getCourseNeedDay();
                if (total == null || days == null || days == 0) {
                    return (T) BigDecimal.ZERO;
                }
                return (T) total.divide(BigDecimal.valueOf(days), 2, RoundingMode.HALF_UP);
            } else {
                Long total = appRoleConfig.getCourseIntegral() != null ?
                        appRoleConfig.getCourseIntegral().longValue() : 0L;
                Long days = appRoleConfig.getCourseNeedDay();
                if (days == null || days == 0) {
                    return (T) Long.valueOf(0L);
                }
                return (T) Long.valueOf(total / days);
            }
        }
    }


    @Override
    public List<FsUserRewards> getMyRewardList(FsUserRewards fsUserRewards) {
        List<FsUserRewards> fsUserRewardsList = rewardsMapper.selectFsUserRewardsList(fsUserRewards);
        if (CollectionUtils.isEmpty(fsUserRewardsList)) {
            return Collections.emptyList();
        }
        // 计算每个奖品的剩余过期天数
        for (FsUserRewards reward : fsUserRewardsList) {
            Long expireDays = calculateExpireDays(reward);
            reward.setExpireDays(expireDays);
        }
        return fsUserRewardsList;
    }

    @Override
    public boolean checkFirstLoginRewardStatus(Long fsUserId) {
        // 1. 查用户表判断是否首次登录注册App
        FsUser fsUser = fsUserMapper.selectFsUserById(fsUserId);
        if (fsUser != null && fsUser.getFirstLoginTime() != null) {
            log.info("用户:{}已注册登录过，非首次登录", fsUserId);
            return false;
        }
        // 2. 查奖品表判断是否已发放奖励
        FsUserRewards queryReward = rewardsMapper.selectByUserIdAndFirstLoginType(fsUserId);
        if (queryReward != null) {
            log.info("用户:{}已下发过首次注册奖励, status={}", fsUserId, queryReward.getStatus());
            return false;
        }
        return true;
    }

    @Override
    public FsAppRole showFirstLoginRewardWindows(Long fsUserId) {
        FsAppRole fsAppRole = new FsAppRole();
        // 1. 查用户表判断是否首次登录注册App
        FsUser fsUser = fsUserMapper.selectFsUserById(fsUserId);
        if (fsUser != null && fsUser.getFirstLoginTime() != null) {
            log.info("用户:{}已注册登录过，非首次登录", fsUserId);
            return fsAppRole;
        }
        // 2. 查奖品表判断是否已发放登录注册奖励
        FsUserRewards queryReward = rewardsMapper.selectByUserIdAndFirstLoginType(fsUserId);
        if (queryReward == null) {
            //查询当前用户对应的角色配置返回红包、积分、商品弹窗信息
            fsAppRole = getAppRoleConfigFirstRegister(fsUserId);
            return fsAppRole;
        }
        return fsAppRole;
    }

    @Override
    public FsAppRole showWatchCourseRewardWindows(Long fsUserId) {
        String watchCourseKey = APP_WATCH_COURSE_DAY_KEY + fsUserId;
        FsAppRole noShowWindow = new FsAppRole();
        Object cacheObject = redisCache.getCacheObject(watchCourseKey);
        if (cacheObject == null) {
            return noShowWindow;
        }
        // 获取用户和配置
        FsUser fsUser = fsUserMapper.selectFsUserById(fsUserId);
        FsAppRole defaultConfig = getAppRoleConfigWatchCourse(fsUserId);
        if (defaultConfig == null) {
            return noShowWindow;
        }
        if (fsUser.getAppRewardsViewedDays()<defaultConfig.getCourseNeedDay()){
            return noShowWindow;
        }
        //查询今日领取红包记录
        FsCourseRedPacketLog fsCourseRedPacketLog = redPacketLogMapper.selectRedPacketLogByUserIdToday(fsUserId);
        if (fsCourseRedPacketLog != null) {
            log.info("用户:{}已领取过课程看课红包，status={}", fsUserId, fsCourseRedPacketLog.getStatus());
            return noShowWindow;
        }
        String activityType = ActivityTypeEnum.WATCH_COURSE.getCode();

        // 1. 有效期检查
        if (isRewardPeriodExpired(fsUser, defaultConfig)) {
            return noShowWindow;
        }

        // 2. 累计天数超标检查
        if (isExceedMaxDays(fsUser, defaultConfig)) {
            return noShowWindow;
        }

        // 3. 获取今日已领数据
        List<FsUserRewards> todayRewards = rewardsMapper.selectTodayListDataByUserIdAndActivityType(fsUserId, activityType);

        // 4. 实物商品逻辑
        if (defaultConfig.getCourseRewardType() == 3) {
            Long courseNeedDay = defaultConfig.getCourseNeedDay();// 商品领取所需天数
            Integer courseDay = fsUser.getAppRewardsViewedDays();// 用户累计看课天数

            if (courseNeedDay == null || courseNeedDay <= 0 || courseDay < courseNeedDay) {
                return noShowWindow;
            }
            if (CollectionUtils.isNotEmpty(todayRewards)) {
                return noShowWindow;
            }
            return defaultConfig;
        }

        // 5. 积分/红包逻辑
        if (CollectionUtils.isNotEmpty(todayRewards)) {
            return noShowWindow;
        }
        return defaultConfig;
    }

    /**
     * 检查奖励是否过期（首次登录时间+有效期）
     */
    private boolean isRewardPeriodExpired(FsUser fsUser, FsAppRole config) {
        Date firstLoginTime = fsUser.getFirstLoginTime();// 首次登录时间
        Long validDays = config.getCourseDay();// 有效期

        if (firstLoginTime == null || validDays == null || validDays <= 0) {
            return false;
        }

        // 计算过期日期
        Calendar expireCal = Calendar.getInstance();
        expireCal.setTime(firstLoginTime);
        expireCal.add(Calendar.DAY_OF_MONTH, validDays.intValue());

        // 只比较年月日
        Date expireDate = DateUtils.truncate(expireCal.getTime(), Calendar.DAY_OF_MONTH);
        Date today = DateUtils.truncate(new Date(), Calendar.DAY_OF_MONTH);

        boolean expired = today.after(expireDate);
        if (expired) {
            log.info("用户看课奖励已过期, userId: {}, expireDate: {}", fsUser.getUserId(), expireDate);
        }
        return expired;
    }

    /**
     * 检查是否超过最大领取天数
     */
    private boolean isExceedMaxDays(FsUser fsUser, FsAppRole config) {
        Integer viewedDays = fsUser.getAppRewardsViewedDays();// 用户累计看课天数
        Long needDays = config.getCourseNeedDay();// 看课商品领取所需天数

        if (viewedDays == null || needDays == null) {
            return false;
        }

        boolean exceeded = viewedDays > needDays;
        if (exceeded) {
            log.info("用户累计看课天数已超过领取所需天数, userId: {}, viewedDays: {}, needDays: {}",
                    fsUser.getUserId(), viewedDays, needDays);
        }
        return exceeded;
    }

    @Override
    public void recordUserWatchCourseDays(Long fsUserId) {
        String watchCourseKey = APP_WATCH_COURSE_DAY_KEY + fsUserId;

        // 1. 检查Redis中是否有今日已记录的标记
        Object cacheObject = redisCache.getCacheObject(watchCourseKey);
        if (cacheObject != null) {
            log.info("用户今日有效看课天数已记录, userId: {}", fsUserId);
            return;
        }

        // 2. 计算到今晚23:59:59的剩余秒数
        long secondsUntilEndOfDay = getSecondsUntilEndOfDay();

        // 3. Redis记录今日已看课标记（过期时间为今晚23:59:59）
        redisCache.setCacheObject(watchCourseKey, fsUserId, (int) secondsUntilEndOfDay, TimeUnit.SECONDS);

        // 4. 更新数据库中的累计看课天数
        FsUser fsUser = fsUserMapper.selectFsUserById(fsUserId);
        if (fsUser != null) {
            // 获取当前累计天数，如果为null则默认为0
            Integer currentDays = fsUser.getAppRewardsViewedDays();
            if (currentDays == null) {
                currentDays = 0;
            }

            // 更新累计天数
            FsUser updateUser = new FsUser();
            updateUser.setUserId(fsUserId);
            updateUser.setAppRewardsViewedDays(currentDays + 1);
            fsUserMapper.updateFsUser(updateUser);

            log.info("用户累计看课天数更新成功, userId: {}, 当前天数: {}", fsUserId, currentDays + 1);
        } else {
            log.error("用户不存在, userId: {}", fsUserId);
        }
    }
    //根据用户id、角色id获取配置的奖品信息(实物商品包含商品名称和图片)
    private FsAppRole getAppRoleConfigFirstRegister(Long fsUserId) {
        //获取当前用户最高权重角色, "false"表示查询等级数字最大的权重角色
        FsAppRole fsAppRole = appRoleMapper.selectHighestLevelAppRoleByUserId(fsUserId, "false");
        if (fsAppRole == null) {
            log.info("未找到用户:{}对应的角色首次注册配置", fsUserId);
            return null;
        }
        fsAppRole.setShow(true);//显示弹窗
        //补充实物商品名称以及商品图片
        if (fsAppRole.getRegisterRewardType()!=null&&fsAppRole.getRegisterRewardType()==3){
            if (fsAppRole.getRegisterProductType()!=null&&fsAppRole.getRegisterProductType()==1){
                FsPackage fsPackage = fsPackageMapper.selectFsPackageByPackageId(fsAppRole.getRegisterProductId());
                if (fsPackage != null){
                    fsAppRole.setGoodsName(fsPackage.getPackageName());
                    fsAppRole.setGoodsUrl(fsPackage.getImgUrl());
                    return fsAppRole;
                }
            } else if (fsAppRole.getRegisterProductType()!=null&&fsAppRole.getRegisterProductType()==2){
                FsStoreProductScrm storeProductScrm = getProductInfo(fsAppRole.getRegisterProductId());
                if (storeProductScrm != null){
                    fsAppRole.setGoodsName(storeProductScrm.getProductName());
                    fsAppRole.setGoodsUrl(storeProductScrm.getImage());
                    return fsAppRole;
                }
            }
        }
        return fsAppRole;
    }
    //根据用户id、角色id获取配置的奖品信息(实物商品包含商品名称和图片)
    private FsAppRole  getAppRoleConfigWatchCourse(Long fsUserId) {
        //获取当前用户最高权重角色, "false"表示查询等级数字最大的权重角色
        FsAppRole fsAppRole = appRoleMapper.selectHighestLevelAppRoleByUserId(fsUserId, "false");
        if (fsAppRole == null) {
            log.info("未找到用户:{}对应的角色看课奖励配置", fsUserId);
            return null;
        }
        //补充实物商品名称以及商品图片
        if (fsAppRole.getCourseRewardType()!=null&&fsAppRole.getCourseRewardType()==3){
            if (fsAppRole.getCourseProductType()!=null&&fsAppRole.getCourseProductType()==1){
                FsPackage fsPackage = fsPackageMapper.selectFsPackageByPackageId(fsAppRole.getCourseProductId());
                if (fsPackage != null){
                    fsAppRole.setGoodsName(fsPackage.getPackageName());
                    fsAppRole.setGoodsUrl(fsPackage.getImgUrl());
                    fsAppRole.setShow(true);//显示弹窗
                    return fsAppRole;
                }
            } else if ( fsAppRole.getCourseProductType()!=null&&fsAppRole.getCourseProductType()==2){
                FsStoreProductScrm storeProductScrm = getProductInfo(fsAppRole.getCourseProductId());
                if (storeProductScrm != null){
                    fsAppRole.setGoodsName(storeProductScrm.getProductName());
                    fsAppRole.setGoodsUrl(storeProductScrm.getImage());
                    fsAppRole.setShow(true);//显示弹窗
                    return fsAppRole;
                }
            }
        }
        fsAppRole.setShow(true);//显示弹窗
        return fsAppRole;
    }

    /**
     * 查询套餐包信息
     * @param goodsId 商品id
     * @return 返回 FsPackage对象
     */
    private FsPackage getPackageInfo(Long goodsId) {
        return fsPackageMapper.selectFsPackageByPackageId(goodsId);
    }

    /**
     * 查询商城商品信息
     * @param goodsId 商品id
     * @return 返回FsStoreProductScrm 对象
     */
    private FsStoreProductScrm getProductInfo(Long goodsId) {
        return fsStoreProductMapper.selectFsStoreProductById(goodsId);
    }

    /**
     * 获取到今晚23:59:59的剩余秒数
     */
    private long getSecondsUntilEndOfDay() {
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime endOfDay = now.toLocalDate().atTime(23, 59, 59);

        // 如果当前时间已经超过23:59:59，用明天
        if (now.isAfter(endOfDay)) {
            endOfDay = endOfDay.plusDays(1);
        }

        return Duration.between(now, endOfDay).getSeconds();
    }

    /**
     * 积分、商品是否过期的判断方法(红包需要另外方法计算)
     *
     * @param reward: 奖品
     * @return true: 过期 false: 未过期
     */
    private boolean isExpired(FsUserRewards reward) {
        // 奖品产生时间
        Date rewardTime = reward.getCreateTime();
        // 获取当前时间
        Date currentTime = DateUtils.getNowDate();
        // 获取当前角色配置(奖品有效期)
        FsAppRole fsAppRole = appRoleMapper.selectHighestLevelAppRoleByUserId(reward.getFsUserId(), "false");

        // 有效天数
        if (fsAppRole == null) {
            log.info("未找到用户:{}对应的角色配置", reward.getFsUserId());
            return false;
        }

        // 奖品有效期(天)
        Long validDays = fsAppRole.getCourseDay();
        if (validDays == null || validDays <= 0) {
            // 如果有效期配置为0或负数，可以认为是永久有效
            return false;
        }
        // 将奖品生成时间加上有效天数，得到过期时间点
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(rewardTime);
        calendar.add(Calendar.DAY_OF_MONTH, validDays.intValue()); // 加上有效天数

        // 获取加完天数后的日期，清零时分秒，只比较日期
        Date expirationDate = DateUtils.truncate(calendar.getTime(), Calendar.DAY_OF_MONTH);
        // 同样，将当前时间也清零时分秒进行比较
        Date currentDate = DateUtils.truncate(currentTime, Calendar.DAY_OF_MONTH);

        // 如果过期日期 < 当前日期，则表示已过期
        return expirationDate.before(currentDate);
    }

    /**
     * 用于计算奖品列表里面的单个奖品的剩余过期天数
     *
     * @param reward 奖品实体
     * @return 剩余天数。null: 表示无有效期或查询失败；0: 今天过期或已过期；正数: 剩余天数
     */
    private Long calculateExpireDays(FsUserRewards reward) {
        // 1. 获取奖品创建时间
        Date rewardCreateTime = reward.getCreateTime();
        if (rewardCreateTime == null) {
            return null; // 如果创建时间为空，无法计算
        }

        // 2. 获取用户的角色配置，以确定有效期
        FsAppRole fsAppRole = appRoleMapper.selectHighestLevelAppRoleByUserId(reward.getFsUserId(), "false");
        if (fsAppRole == null) {
            // 如果找不到角色配置，可以视为永不过期，返回null
            return null;
        }

        Long validDays = fsAppRole.getCourseDay();
        if (validDays == null || validDays <= 0) {
            // 如果有效期配置为0或负数，也视为永不过期
            return null;
        }

        // 3. 计算过期日期
        Calendar cal = Calendar.getInstance();
        cal.setTime(rewardCreateTime);
        cal.add(Calendar.DAY_OF_MONTH, validDays.intValue());
        Date expireDate = DateUtils.truncate(cal.getTime(), Calendar.DAY_OF_MONTH);

        // 4. 计算剩余天数
        Date now = DateUtils.truncate(new Date(), Calendar.DAY_OF_MONTH);

        long diffInMillis = expireDate.getTime() - now.getTime();
        long daysDiff = diffInMillis / (1000 * 60 * 60 * 24);

        // 5. 返回结果
        // 如果差值小于0，说明已过期，返回0
        // 如果差值>=0，说明未过期，返回剩余天数
        return Math.max(0L, daysDiff);
    }
}
