package com.red.circle.other.app.scheduler.activity;

import com.alibaba.fastjson.JSON;
import com.red.circle.common.business.core.enums.SysOriginPlatformEnum;
import com.red.circle.component.redis.annotation.TaskCacheLock;
import com.red.circle.component.redis.service.RedisService;
import com.red.circle.framework.core.dto.ReqSysOrigin;
import com.red.circle.mq.business.model.event.GameKingRewardEvent;
import com.red.circle.mq.rocket.business.producer.UserMqMessageService;
import com.red.circle.other.app.command.activity.query.RankingListQryExe;
import com.red.circle.other.app.dto.clientobject.activity.RankingListCO;
import com.red.circle.other.app.dto.cmd.activity.RankingListQueryCmd;
import com.red.circle.other.app.service.activity.RankingActivityService;
import com.red.circle.other.domain.ranking.RankingActivityType;
import com.red.circle.other.domain.ranking.RankingCycleType;
import com.red.circle.tool.core.collection.CollectionUtils;
import com.red.circle.tool.core.date.ZonedDateTimeAsiaRiyadhUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * 游戏王排名奖励兜底任务.
 */
@Slf4j
@Component
@RequiredArgsConstructor
@ConditionalOnProperty(name = "scheduler.game-king-reward", havingValue = "true", matchIfMissing = true)
public class GameKingRewardTask {

    private final RankingActivityService rankingActivityService;
    private final RankingListQryExe rankingListQryExe;
    private final RedisService redisService;
    private static final String RANKING_LIST_CACHE_KEY_PREFIX = "ranking_list:";
    private static final int CACHE_EXPIRE_MINUTES = 10;
    private final UserMqMessageService userMqMessageService;

    /**
     * 每5分钟执行一次，兜底发送游戏王排名奖励.
     */
    @Scheduled(cron = "0 */5 * * * ?")
    @TaskCacheLock(key = "GAME_KING_REWARDTASK", expireSecond = 240)
    public void executeGameKingReward() {
        try {
            log.info("开始执行游戏王排名奖励兜底任务");

            RankingListQueryCmd cmd = new RankingListQueryCmd();
            cmd.setCycleKey(ZonedDateTimeAsiaRiyadhUtils.nowWeekMondayToInt().toString());
            cmd.setActivityType(RankingActivityType.KING_GAMES.getCode());
            cmd.setTemplateId("2001207026499137537");
            cmd.setReqSysOrigin(ReqSysOrigin.of("LIKEI"));

            RankingListQueryCmd top4Cmd = new RankingListQueryCmd();
            top4Cmd.setActivityType(cmd.getActivityType());
            top4Cmd.setCycleKey(cmd.getCycleKey());
            top4Cmd.setCycleType(RankingCycleType.WEEKLY.getCode());
            top4Cmd.setReqUserId(cmd.getReqUserId());
            top4Cmd.setReqSysOrigin(cmd.getReqSysOrigin());
            top4Cmd.setTopN(100);
            top4Cmd.setTemplateId(cmd.getTemplateId());

            RankingListCO result = rankingListQryExe.execute(top4Cmd);

            String cacheKey = buildRankingListCacheKey(cmd);
            if (result != null && CollectionUtils.isNotEmpty(result.getRankingList())) {
                redisService.setString(cacheKey, JSON.toJSONString(result), CACHE_EXPIRE_MINUTES, TimeUnit.MINUTES);

                result.setRankingList(result.getRankingList().stream().limit(10).toList());
                sendGameKingRewardEvent(cmd, result);
            }

            log.info("游戏王排名奖励兜底任务执行完成");
        } catch (Exception e) {
            log.error("游戏王排名奖励兜底任务执行失败", e);
        }
    }

    /**
     * 构建排行榜缓存Key.
     */
    private String buildRankingListCacheKey(RankingListQueryCmd cmd) {
        return RANKING_LIST_CACHE_KEY_PREFIX + RankingActivityType.getByCode(cmd.getActivityType()).name() + ":" + cmd.getCycleKey();
    }

    /**
     * 发送游戏王奖励消息.
     */
    private void sendGameKingRewardEvent(RankingListQueryCmd cmd, RankingListCO result) {
        if (CollectionUtils.isEmpty(result.getRankingList())) {
            return;
        }

        GameKingRewardEvent event = new GameKingRewardEvent()
                .setActivityType(RankingActivityType.getByCode(cmd.getActivityType()).name())
                .setOrigin(cmd.getReqSysOrigin().getOrigin())
                .setCycleKey(cmd.getCycleKey())
                .setTemplateId(cmd.getTemplateId())
                .setRankingUsers(result.getRankingList().stream()
                        .map(user -> new GameKingRewardEvent.RankingUser()
                                .setUserId(user.getUserId())
                                .setRank(user.getRank()))
                        .collect(Collectors.toList()));

        userMqMessageService.sendGameKingRewardEvent(event);
    }


}
