//package com.fs.app.task;
//
//import cn.hutool.core.collection.CollUtil;
//import cn.hutool.json.JSONUtil;
//import com.alibaba.fastjson.JSON;
//import com.alibaba.fastjson.JSONObject;
//import com.fs.app.facade.LiveFacadeService;
//import com.fs.app.vo.LotteryVo;
//import com.fs.app.websocket.bean.SendMsgVo;
//import com.fs.app.websocket.service.WebSocketServer;
//import com.fs.common.annotation.QuartzRunnable;
//import com.fs.common.constant.LiveKeysConstant;
//import com.fs.common.core.domain.R;
//import com.fs.common.core.redis.RedisCache;
//import com.fs.common.core.redis.RedisUtil;
//import com.fs.common.utils.StringUtils;
//import com.fs.core.aspectj.lock.DistributeLock;
//import com.fs.erp.domain.ErpDeliverys;
//import com.fs.erp.domain.ErpOrderQuery;
//import com.fs.erp.dto.ErpOrderQueryRequert;
//import com.fs.erp.dto.ErpOrderQueryResponse;
//import com.fs.erp.service.FsJstAftersalePushService;
//import com.fs.erp.service.IErpOrderService;
//import com.fs.erp.utils.ErpContextHolder;
//import com.fs.live.domain.*;
//import com.fs.live.mapper.LiveLotteryRegistrationMapper;
//import com.fs.live.param.LiveReplayParam;
//import com.fs.live.service.*;
//import com.fs.live.vo.LiveConfigVo;
//import com.fs.live.vo.LiveLotteryConfVo;
//import com.fs.live.vo.LiveLotteryProductListVo;
//import com.fs.store.domain.FsExpress;
//import com.fs.store.enums.OrderLogEnum;
//import com.fs.store.mapper.FsWarehousesMapper;
//import com.fs.store.param.LiveAfterSalesAudit1Param;
//import com.fs.store.service.IFsExpressService;
//import com.fs.store.service.IFsUserService;
//import lombok.AllArgsConstructor;
//import org.apache.commons.collections4.CollectionUtils;
//import org.apache.commons.lang.ObjectUtils;
//import org.slf4j.Logger;
//import org.slf4j.LoggerFactory;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.scheduling.annotation.Scheduled;
//import org.springframework.stereotype.Component;
//import org.springframework.transaction.annotation.Transactional;
//
//import java.math.BigDecimal;
//import java.text.ParseException;
//import java.time.Instant;
//import java.time.LocalDateTime;
//import java.util.*;
//import java.util.stream.Collectors;
//
//@Component
//@AllArgsConstructor
//public class Task {
//
//    private static final Logger log = LoggerFactory.getLogger(Task.class);
//    private final ILiveService liveService;
//
//    private final ILiveDataService liveDataService;
//
//    private final RedisCache redisCache;
//
//    @Autowired
//    private ILiveWatchUserService liveWatchUserService;
//    @Autowired
//    private IFsUserService fsUserService;
//    @Autowired
//    private ILiveRewardRecordService liveRewardRecordService;
//    @Autowired
//    private WebSocketServer webSocketServer;
//    @Autowired
//    private ILiveAutoTaskService liveAutoTaskService;
//    @Autowired
//    private ILiveLotteryConfService liveLotteryConfService;
//    @Autowired
//    private ILiveUserLotteryRecordService liveUserLotteryRecordService;
//    @Autowired
//    private LiveLotteryRegistrationMapper liveLotteryRegistrationMapper;
//    @Autowired
//    private ILiveRedConfService liveRedConfService;
////1111
//    @Autowired
//    private ILiveOrderService liveOrderService;
//
//    @Autowired
//    private ILiveAfterSalesService afterSalesService;
//
//
//    @Autowired
//    private IErpOrderService erpOrderService;
//
//
//    @Autowired
//    private IFsExpressService expressService;
//
//
//    @Autowired
//    private ILiveOrderLogsService orderLogsService;
//
//
//    @Autowired
//    private FsWarehousesMapper fsWarehousesMapper;
//
//    @Autowired
//    public FsJstAftersalePushService fsJstAftersalePushService;
//    @Autowired
//    public RedisUtil redisUtil;
//    @Scheduled(cron = "0 0/1 * * * ?")
//    @DistributeLock(key = "updateLiveStatusByTime", scene = "task")
//    //public void selectSopUserLogsListByTime() {
//    public void updateLiveStatusByTime() {
//        List<Live> list = liveService.selectNoEndLiveList();
//        if (list.isEmpty())
//            return;
//        List<Long> liveIdLists = list.stream().map(Live::getLiveId).collect(Collectors.toList());
//        List<LiveAutoTask> liveAutoTasks = liveAutoTaskService.selectLiveAutoTaskByLiveIds(liveIdLists);
//        List<Live> activeLiveList = new ArrayList<>();
//        LocalDateTime now = LocalDateTime.now();
//        list.forEach(live -> {
//            if (live.getLiveType() != 3) {
//                if (live.getFinishTime() == null) {
//                    if (now.isAfter(live.getStartTime().minusSeconds(2L))){
//                        live.setStatus(2);
//                        activeLiveList.add( live);
//                    } else if (now.isBefore(live.getStartTime())) {
//                        live.setStatus(1);
//                    }
//                } else {
//                    if (now.isAfter(live.getStartTime().minusSeconds(2L)) && now.isBefore(live.getFinishTime())) {
//                        live.setStatus(2);
//                        activeLiveList.add( live);
//                    } else if (now.isBefore(live.getStartTime().minusSeconds(2L))) {
//                        live.setStatus(1);
//                    } else if (now.isAfter(live.getFinishTime().minusSeconds(2L))) {
//                        live.setStatus(3);
//                    }
//                }
//            } else {
//                // 直播回放只需要检测结束时间就好了
//                LiveReplayParam liveReplayParam = JSON.parseObject(live.getLiveConfig(), LiveReplayParam.class);
//                if (liveReplayParam.getIsPlaybackOpen()) {
//                    if (liveReplayParam.getFinishTime() != null) {
//                        if (now.isAfter(live.getFinishTime().minusSeconds(2L))) {
//                            live.setStatus(3);
//                        }
//                    }
//                }
//            }
//
//        });
//        String key = "live:auto_task:";
//        if(!activeLiveList.isEmpty()){
//            activeLiveList.forEach(live -> {
//                List<LiveAutoTask> collect = liveAutoTasks.stream().filter(liveAutoTask -> liveAutoTask.getLiveId().equals(live.getLiveId())).collect(Collectors.toList());
//                if (!collect.isEmpty()) {
//                    collect.forEach(liveAutoTask -> {
//                        liveAutoTask.setCreateTime(null);
//                        liveAutoTask.setUpdateTime(null);
//                        redisCache.redisTemplate.opsForZSet().add(key + live.getLiveId(), JSON.toJSONString(liveAutoTask),liveAutoTask.getAbsValue().getTime());
//                        redisCache.redisTemplate.expire(key+live.getLiveId(), 30, java.util.concurrent.TimeUnit.MINUTES);
//                    });
//                }
//            });
//        }
//
//        if(!list.isEmpty()){
//            for (Live live : list) {
//                liveService.updateLive(live);
//            }
//        }
//    }
//    @Scheduled(cron = "0/1 * * * * ?")
//    @DistributeLock(key = "liveLotteryTask", scene = "task")
//    public void liveLotteryTask() {
//        long currentTime = Instant.now().toEpochMilli(); // 当前时间戳（毫秒）
//        String lotteryKey = "live:lottery_task:*";
//        Set<String> allLiveKeys = redisCache.redisTemplate.keys(lotteryKey);
//        if (allLiveKeys != null && !allLiveKeys.isEmpty()) {
//            for (String liveKey : allLiveKeys) {
//                Set<String> range = redisCache.redisTemplate.opsForZSet().rangeByScore(liveKey, 0, currentTime);
//                if (range == null || range.isEmpty()) {
//                    continue;
//                }
//                processLotteryTask(range);
//                redisCache.redisTemplate.opsForZSet()
//                        .removeRangeByScore(liveKey, 0, currentTime);
//            }
//        }
//
//        String redKey = "live:red_task:*";
//        allLiveKeys = redisCache.redisTemplate.keys(redKey);
//        if (allLiveKeys == null || allLiveKeys.isEmpty()) {
//            return;
//        }
//        for (String liveKey : allLiveKeys) {
//            Set<String> range = redisCache.redisTemplate.opsForZSet().rangeByScore(liveKey, 0, currentTime);
//            if (range == null || range.isEmpty()) {
//                continue;
//            }
//
//            updateRedStatus(range);
//            redisCache.redisTemplate.opsForZSet()
//                    .removeRangeByScore(liveKey, 0, currentTime);
//            try {
//                // 广播红包关闭消息
//                SendMsgVo sendMsgVo = new SendMsgVo();
//                sendMsgVo.setLiveId(Long.valueOf(liveKey));
//                sendMsgVo.setCmd("red");
//                sendMsgVo.setStatus(-1);
//                webSocketServer.broadcastMessage(Long.valueOf(liveKey), JSONObject.toJSONString(R.ok().put("data", sendMsgVo)));
//            } catch (Exception e) {
//                log.error("更新红包状态异常", e);
//            }
//        }
//    }
//
//    private void updateRedStatus(Set<String> range) {
//
//        liveRedConfService.finishRedStatusBySetIds(range);
//    }
//
//    private void processLotteryTask(Set<String> range) {
//        List<LiveLotteryConfVo> liveLotteries = liveLotteryConfService.selectVoListByLotteryIds(range);
//        if(liveLotteries.isEmpty()) return;
//        Date now = new Date();
//        for (LiveLotteryConfVo liveLottery : liveLotteries) {
//            // 查询抽奖数量
//            List<LiveLotteryProductListVo> products = liveLottery.getProducts();
//            Integer totalLots = products.stream().mapToInt(liveLotteryProductListVo -> Math.toIntExact(liveLotteryProductListVo.getTotalLots())).sum();
//            if(totalLots <= 0) continue;
//            // 先将参与记录插入数据库
//            String hashKey = String.format(LiveKeysConstant.LIVE_HOME_PAGE_CONFIG_DRAW, liveLottery.getLiveId(), liveLottery.getLotteryId());
//            Map<Object, Object> hashEntries = redisUtil.hashEntries(hashKey);
//            List<LiveLotteryRegistration> registrationList = new ArrayList<>();
//            if (CollUtil.isNotEmpty(hashEntries)) {
//                registrationList = hashEntries.values().stream()
//                        .map(value -> JSONUtil.toBean(JSONUtil.parseObj(value), LiveLotteryRegistration.class))
//                        .collect(Collectors.toList());
//                liveLotteryRegistrationMapper.insertLiveLotteryRegistrationBatch(registrationList);
//            }
//
//            // 查询在线用户 并且参与了抽奖的用户
//            List<LiveWatchUser> liveWatchUsers = liveWatchUserService.selectLiveWatchAndRegisterUser(liveLottery.getLiveId(),liveLottery.getLotteryId(), totalLots);
//            if(liveWatchUsers.isEmpty()) continue;
//            LiveLotteryRegistration liveLotteryRegistration;
//            // 收集中奖信息
//            List<LotteryVo> lotteryVos = new ArrayList<>();
//            for (LiveLotteryProductListVo liveLotteryProductListVo : products) {
//                // 随机抽奖一个用户获取奖品
//                Long totalLotsPerProduct = liveLotteryProductListVo.getTotalLots();
//                for (int i = 0; i < totalLotsPerProduct && !liveWatchUsers.isEmpty(); i++) {
//                    // 随机选择一个用户
//                    int randomIndex = new Random().nextInt(liveWatchUsers.size());
//                    LiveWatchUser winningUser = liveWatchUsers.get(randomIndex);
//
//                    // 创建中奖记录
//                    LiveUserLotteryRecord record = new LiveUserLotteryRecord();
//                    record.setLotteryId(liveLottery.getLotteryId());
//                    record.setLiveId(liveLottery.getLiveId());
//                    record.setUserId(winningUser.getUserId());
//                    record.setProductId(liveLotteryProductListVo.getProductId());
//                    record.setCreateTime(new Date());
//
//                    // 保存中奖记录
//                    liveUserLotteryRecordService.insertLiveUserLotteryRecord(record);
//                    liveLotteryRegistration = new LiveLotteryRegistration();
//                    liveLotteryRegistration.setLotteryId(liveLottery.getLotteryId());
//                    liveLotteryRegistration.setLiveId(liveLottery.getLotteryId());
//                    liveLotteryRegistration.setUserId(winningUser.getUserId());
//                    liveLotteryRegistration.setIsWin(1L);
//                    liveLotteryRegistration.setUpdateTime(now);
//                    liveLotteryRegistration.setRizeLevel(liveLotteryProductListVo.getPrizeLevel());
//                    liveLotteryRegistrationMapper.updateLiveLotteryRegistrationNoId(liveLotteryRegistration);
//                    // 从候选列表中移除该用户，确保每人只能中奖一次
//                    liveWatchUsers.remove(randomIndex);
//                    LotteryVo lotteryVo = new LotteryVo();
//                    lotteryVo.setUserId(winningUser.getUserId());
//                    lotteryVo.setUserName(winningUser.getNickName());
//                    lotteryVo.setPrizeLevel(liveLotteryProductListVo.getPrizeLevel());
//                    lotteryVo.setProductName(liveLotteryProductListVo.getProductName());
//                    lotteryVos.add(lotteryVo);
//                }
//            }
//            SendMsgVo sendMsgVo = new SendMsgVo();
//            sendMsgVo.setLiveId(liveLottery.getLiveId());
//            sendMsgVo.setCmd("LotteryDetail");
//            sendMsgVo.setData(JSON.toJSONString(lotteryVos));
//            webSocketServer.broadcastMessage(liveLottery.getLiveId(), JSONObject.toJSONString(R.ok().put("data", sendMsgVo)));
//
//            // 删除缓存 同步抽奖记录
//            redisUtil.delete(hashKey);
//        }
//
//        List<Long> collect = liveLotteries.stream().map(LiveLotteryConfVo::getLotteryId).collect(Collectors.toList());
//        liveLotteryConfService.finishStatusByLotteryIds(collect);
//    }
//
//    @Scheduled(cron = "0/1 * * * * ?")
//    @DistributeLock(key = "liveAutoTask", scene = "task")
//    public void liveAutoTask() {
//        long currentTime = Instant.now().toEpochMilli(); // 当前时间戳（毫秒）
//
//        Set<String> allLiveKeys = redisCache.redisTemplate.keys("live:auto_task:*");
//        if (allLiveKeys == null || allLiveKeys.isEmpty()) {
//            return; // 没有数据，直接返回
//        }
//        // 2. 遍历每个直播间的ZSet键
//        for (String liveKey : allLiveKeys) {
//            // 3. 获取当前直播间ZSet中所有元素（按score排序）
//            // range方法：0表示第一个元素，-1表示最后一个元素，即获取全部
//            Set<String> range = redisCache.redisTemplate.opsForZSet().rangeByScore(liveKey, 0, currentTime);
//            if (range == null || range.isEmpty()) {
//                continue; // 没有数据，直接返回
//            }
//            redisCache.redisTemplate.opsForZSet()
//                    .removeRangeByScore(liveKey, 0, currentTime);
//            processAutoTask(range);
//        }
//    }
//
//    private void processAutoTask(Set<String> range) {
//        for (String liveAutoTask : range) {
//            LiveAutoTask task = JSON.parseObject(liveAutoTask, LiveAutoTask.class);
//            webSocketServer.handleAutoTask(task);
//            task.setFinishStatus(1L);
//            liveAutoTaskService.finishLiveAutoTask(task);
//        }
//    }
//
//    @Scheduled(cron = "0 0/1 * * * ?")
//    @DistributeLock(key = "autoUpdateWatchReward", scene = "task")
//    @Transactional
//    public void autoUpdateWatchReward() {
//
//        // 1.查询所有直播中的直播间
//        List<Live> lives = liveService.liveList();
//
//
//        // 2.检查是否开启观看奖励
//        List<Live> openRewardLives = lives.stream().filter(live -> StringUtils.isNotEmpty(live.getConfigJson())).collect(Collectors.toList());
//        Date now = new Date();
//
//        for (Live openRewardLive : openRewardLives) {
//            String configJson = openRewardLive.getConfigJson();
//            LiveWatchConfig config = JSON.parseObject(configJson, LiveWatchConfig.class);
//            if (config.getEnabled()) {
//                // 3.检查当前直播间的在线用户（可以传入一个时间，然后查出来当天没领取奖励的用户）
//                List<LiveWatchUser> onlineUser = liveWatchUserService.checkOnlineNoRewardUser(openRewardLive.getLiveId(), now)
//                        .stream().filter(user -> now.getTime() - user.getUpdateTime().getTime() > config.getWatchDuration() * 60 * 1000)
//                        .collect(Collectors.toList());
//                if(onlineUser.isEmpty()) continue;
//
//                List<Long> userIds = onlineUser.stream().map(LiveWatchUser::getUserId).collect(Collectors.toList());
//                // 4.保存用户领取记录
//                saveUserRewardRecord(openRewardLive, userIds,config.getScoreAmount());
//                // 5.更新用户积分（芳华币
//                fsUserService.incrIntegral(userIds,config.getScoreAmount());
//                // 6.发送websocket事件消息 通知用户自动领取成功
//                userIds.forEach(userId -> webSocketServer.sendIntegralMessage(openRewardLive.getLiveId(),userId,config.getScoreAmount()));
//
//            }
//        }
//    }
//    private void saveUserRewardRecord(Live live, List<Long> userIds,Long scoreAmount) {
//        for (Long userId : userIds) {
//            LiveRewardRecord record = new LiveRewardRecord();
//            record.setLiveId(live.getLiveId());
//            record.setUserId(userId);
//            record.setIncomeType(1L);
//            record.setSourceType(1L);
//            record.setSourceId(live.getCompanyId() == null ? 0L : live.getCompanyId());
//            record.setRewardType(2L);
//            record.setNum(BigDecimal.valueOf(scoreAmount));
//            record.setRewardType(2L);
//            record.setCreateTime(new Date());
//            record.setCreateBy(String.valueOf(userId));
//            liveRewardRecordService.insertLiveRewardRecord(record);
//        }
//    }
//
//    /**
//     * 更新红包领取数量
//     */
//    @Scheduled(cron = "0/5 * * * * ?")
//    @DistributeLock(key = "updateRedQuantityNum", scene = "task")
//    public void updateRedQuantityNum() {
//        liveRedConfService.updateRedQuantityNum();
//    }
//}
