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

import com.red.circle.common.business.core.enums.SysOriginPlatformEnum;
import com.red.circle.component.redis.annotation.TaskCacheLock;
import com.red.circle.other.domain.ranking.RankingActivityType;
import com.red.circle.other.domain.ranking.RankingCycleType;
import com.red.circle.other.infra.database.mongo.entity.activity.RankingActivityRecord;
import com.red.circle.other.infra.database.mongo.entity.user.count.WeekCpValueCount;
import com.red.circle.other.infra.database.mongo.service.user.count.WeekCpValueCountService;
import org.apache.commons.lang3.tuple.ImmutablePair;
import com.red.circle.other.infra.database.rds.entity.sys.StartPageUser;
import com.red.circle.other.infra.database.rds.service.sys.StartPageUserService;
import com.red.circle.other.infra.gateway.RankingActivityGateway;
import com.red.circle.tool.core.collection.CollectionUtils;
import com.red.circle.tool.core.date.DateFormatConstant;
import com.red.circle.tool.core.date.ZonedDateTimeAsiaRiyadhUtils;
import com.red.circle.tool.core.date.ZonedDateTimeUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.sql.Timestamp;
import java.time.ZonedDateTime;
import java.util.List;

/**
 * 更新启动页用户定时任务
 * 每周一查询上周排名第一的用户并更新到启动页
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class UpdateStartPageUserTask {

    private final RankingActivityGateway rankingActivityGateway;
    private final StartPageUserService startPageUserService;
    private final WeekCpValueCountService weekCpValueCountService;

    private static final String START_PAGE_TYPE = "KING_GAMES";
    private static final String CP_START_PAGE_TYPE = "CP";
    private static final Integer EXPIRE_DAYS = 7;

    /**
     * 每周一 0点5分执行
     */
    @Scheduled(cron = "0 5 0 ? * MON", zone = "Asia/Riyadh")
    @TaskCacheLock(key = "UPDATE_START_PAGE_USER_TASK", expireSecond = 86400)
    @Transactional(rollbackFor = Exception.class)
    public void updateStartPageUser() {
        long startTime = System.currentTimeMillis();
        log.warn("========== 更新启动页用户定时任务开始 ==========");

        try {
            String sysOrigin = SysOriginPlatformEnum.LIKEI.name();
            String lastWeekDate = getLastWeekDate();

            Long topUserId = getLastWeekTopUser(sysOrigin, lastWeekDate);

            if (topUserId == null) {
                log.warn("未找到上周排名第一的用户，跳过更新");
                return;
            }

            updateOrCreateStartPageUser(sysOrigin, topUserId);

            log.warn("========== 更新启动页用户定时任务完成，耗时：{} ms，用户ID：{} ==========",
                    System.currentTimeMillis() - startTime, topUserId);

        } catch (Exception e) {
            log.error("========== 更新启动页用户定时任务异常 ==========", e);
            throw e;
        }
    }

    /**
     * 每周一 0点10分执行，更新CP启动页用户
     */
    @Scheduled(cron = "0 10 0 ? * MON", zone = "Asia/Riyadh")
    @TaskCacheLock(key = "UPDATE_CP_START_PAGE_USER_TASK", expireSecond = 86400)
    @Transactional(rollbackFor = Exception.class)
    public void updateCpStartPage() {
        log.warn("========== 更新CP启动页用户定时任务开始 ==========");
        long startTime = System.currentTimeMillis();

        try {
            String sysOrigin = SysOriginPlatformEnum.LIKEI.name();

            List<WeekCpValueCount> topList = weekCpValueCountService.listLastWeekTop(sysOrigin, 1);

            if (CollectionUtils.isEmpty(topList)) {
                log.warn("上周CP排行榜为空，跳过更新");
                return;
            }

            String topId = topList.get(0).getId();
            ImmutablePair<Long, Long> userIdPair = weekCpValueCountService.parseUserIdPair(topId);

            if (userIdPair.getLeft() == null || userIdPair.getRight() == null) {
                log.warn("CP排行榜第一名ID解析失败: {}", topId);
                return;
            }

            Long userIdOne = userIdPair.getLeft();
            Long userIdTwo = userIdPair.getRight();
            Timestamp expireTime = calculateExpireTime();

            updateCpStartPageUser(sysOrigin, 1, userIdOne, expireTime);
            updateCpStartPageUser(sysOrigin, 2, userIdTwo, expireTime);

            log.warn("========== 更新CP启动页用户定时任务完成，耗时：{} ms，userId1：{}，userId2：{} ==========",
                System.currentTimeMillis() - startTime, userIdOne, userIdTwo);

        } catch (Exception e) {
            log.error("========== 更新CP启动页用户定时任务异常 ==========", e);
            throw e;
        }
    }

    private void updateCpStartPageUser(String sysOrigin, Integer sort, Long userId, Timestamp expireTime) {
        StartPageUser record = startPageUserService.query()
            .eq(StartPageUser::getSysOrigin, sysOrigin)
            .eq(StartPageUser::getType, CP_START_PAGE_TYPE)
            .eq(StartPageUser::getSort, sort)
            .last("LIMIT 1")
            .getOne();

        if (record == null) {
            log.warn("未找到CP启动页用户记录，sysOrigin={}，sort={}", sysOrigin, sort);
            return;
        }

        record.setUserId(userId);
        record.setExpireTime(expireTime);
        startPageUserService.updateSelectiveById(record);
        log.info("更新CP启动页用户成功，id={}，sort={}，userId={}，expireTime={}", record.getId(), sort, userId, expireTime);
    }

    /**
     * 获取上周排名第一的用户
     */
    private Long getLastWeekTopUser(String sysOrigin, String lastWeekDate) {
        List<RankingActivityRecord> records = rankingActivityGateway.getRankingList(
                sysOrigin,
                RankingActivityType.KING_GAMES,
                RankingCycleType.WEEKLY,
                lastWeekDate,
                null,
                1
        );

        if (CollectionUtils.isEmpty(records)) {
            log.warn("上周排行榜为空，日期：{}", lastWeekDate);
            return null;
        }

        RankingActivityRecord topRecord = records.get(0);
        log.info("上周排名第一用户ID：{}，数量：{}", topRecord.getUserId(), topRecord.getQuantity());

        return topRecord.getUserId();
    }

    /**
     * 更新或创建启动页用户记录
     */
    private void updateOrCreateStartPageUser(String sysOrigin, Long userId) {
        StartPageUser existingUser = startPageUserService.query()
                .eq(StartPageUser::getSysOrigin, sysOrigin)
                .eq(StartPageUser::getType, START_PAGE_TYPE)
                .last("LIMIT 1")
                .getOne();

        Timestamp expireTime = calculateExpireTime();

        if (existingUser != null) {
            existingUser.setUserId(userId);
            existingUser.setExpireTime(expireTime);
            startPageUserService.updateSelectiveById(existingUser);
            log.info("更新启动页用户成功，ID：{}，用户ID：{}，过期时间：{}", 
                    existingUser.getId(), userId, expireTime);
        } else {
            StartPageUser newUser = new StartPageUser();
            newUser.setSysOrigin(sysOrigin);
            newUser.setType(START_PAGE_TYPE);
            newUser.setUserId(userId);
            newUser.setSort(1);
            newUser.setExpireTime(expireTime);
            startPageUserService.save(newUser);
            log.info("创建启动页用户成功，用户ID：{}，过期时间：{}", userId, expireTime);
        }
    }

    /**
     * 计算过期时间（当前时间 + 7天）
     */
    private Timestamp calculateExpireTime() {
        ZonedDateTime now = ZonedDateTimeAsiaRiyadhUtils.now();
        ZonedDateTime expireDateTime = now.plusDays(EXPIRE_DAYS);
        return Timestamp.from(expireDateTime.toInstant());
    }

    /**
     * 获取上周一的日期（格式：yyyyMMdd）
     */
    private String getLastWeekDate() {
        return ZonedDateTimeUtils.format(
                ZonedDateTimeAsiaRiyadhUtils.getLastWeekMonday(),
                DateFormatConstant.yyyyMMdd
        );
    }
}
