package com.red.circle.other.app.listener.task;

import com.alibaba.nacos.client.naming.utils.CollectionUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.google.common.base.Throwables;
import com.red.circle.common.business.core.enums.SysOriginPlatformEnum;
import com.red.circle.common.business.enums.SendPropsOrigin;
import com.red.circle.component.mq.MessageEventProcess;
import com.red.circle.component.mq.MessageEventProcessDescribe;
import com.red.circle.component.mq.config.RocketMqMessageListener;
import com.red.circle.component.mq.service.Action;
import com.red.circle.component.mq.service.ConsumerMessage;
import com.red.circle.component.mq.service.MessageListener;
import com.red.circle.component.redis.service.RedisService;
import com.red.circle.mq.business.model.event.task.TaskApprovalEvent;
import com.red.circle.mq.rocket.business.streams.TaskSink;
import com.red.circle.other.app.dto.cmd.AdminTaskProgressUpdateCmd;
import com.red.circle.other.app.dto.cmd.SpinsTaskProgressUpdateCmd;
import com.red.circle.other.app.service.AdminTaskService;
import com.red.circle.other.app.service.SpinsUserTaskProgressService;
import com.red.circle.other.app.service.task.TaskService;
import com.red.circle.other.app.util.DateTimeAsiaRiyadhUtils;
import com.red.circle.other.domain.admintask.AdminTaskType;
import com.red.circle.other.domain.gateway.user.ability.InviteUserGateway;
import com.red.circle.other.domain.ranking.RankingActivityType;
import com.red.circle.other.domain.ranking.RankingCycleType;
import com.red.circle.other.domain.ranking.RankingDimension;
import com.red.circle.other.infra.database.mongo.entity.activity.RankingActivityRecord;
import com.red.circle.other.infra.database.rds.dao.task.UserTaskProgressDAO;
import com.red.circle.other.infra.database.rds.dao.user.user.UserInviteUserDAO;
import com.red.circle.other.infra.database.rds.entity.task.UserTaskProgress;
import com.red.circle.other.infra.database.rds.entity.user.user.UserInviteUser;
import com.red.circle.other.infra.database.rds.service.user.user.InviteUserRechargeCommissionService;
import com.red.circle.other.infra.database.rds.service.user.user.InviteUserSummaryService;
import com.red.circle.other.infra.database.rds.service.user.user.RelationshipFriendService;
import com.red.circle.other.infra.gateway.RankingActivityGateway;
import com.red.circle.other.inner.endpoint.activity.PropsActivityClient;
import com.red.circle.other.inner.model.cmd.activity.SendActivityRewardCmd;
import com.red.circle.tool.core.date.TimestampUtils;
import com.red.circle.tool.core.date.ZonedDateTimeAsiaRiyadhUtils;
import com.red.circle.tool.core.sequence.IdWorkerUtils;
import com.red.circle.wallet.inner.endpoint.wallet.WalletGoldClient;
import com.red.circle.wallet.inner.model.cmd.GoldReceiptCmd;
import com.red.circle.wallet.inner.model.enums.GoldOrigin;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.math.BigDecimal;
import java.sql.Timestamp;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Slf4j
@RocketMqMessageListener(groupId = TaskSink.INPUT, tag = TaskSink.TAG)
@RequiredArgsConstructor
public class TaskListener implements MessageListener {
    private final MessageEventProcess messageEventProcess;
    private final TaskService taskService;
    private final RedisService redisService;
    private final RelationshipFriendService relationshipFriendService;
    private final InviteUserGateway inviteUserGateway;
    private final SpinsUserTaskProgressService spinsUserTaskProgressService;
    private final AdminTaskService adminTaskService;
    private final UserTaskProgressDAO  userTaskProgressDAO;
    private final PropsActivityClient propsActivityCnfClient;
    private final UserInviteUserDAO userInviteUserDAO;
    private final WalletGoldClient walletGoldClient;
    private final InviteUserRechargeCommissionService inviteUserRechargeCommissionService;
    private final InviteUserSummaryService inviteUserSummaryService;
    private final RankingActivityGateway rankingActivityGateway;

    @Override
    public Action consume(ConsumerMessage message) {
        return messageEventProcess.consume(
                MessageEventProcessDescribe.builder()
                        .logTag("任务审核")
                        .consumeMsgTimeoutMinute(1)
                        .repeatConsumeMinute(1)
                        .repeatConsumeTag("task_approval")
                        .checkConsumeTag(TaskSink.TAG)
                        .message(message)
                        .build(),
                TaskApprovalEvent.class,
                eventBody -> {
                    log.warn("任务审核 event {}", eventBody);
                    Integer taskId = eventBody.getTaskId();
                    switch (taskId) {
                        case 1:
                            // 处理任务-1 的逻辑 上麦10分钟
                            handleTask1(eventBody);
                            break;
                        case 2:
                            // 处理任务-2 的逻辑 在房间内赠送礼物
                            handleTask2(eventBody);
                            break;
                        case 3:
                            // 处理任务-3 的逻辑 在商店购买任意商品
                            handleTask3(eventBody);
                            break;
                        case 4:
                            // 处理任务-4 的逻辑 玩一局游戏
                            handleTask4(eventBody);
                            break;
                        case 5:
                            // 处理任务-5 的逻辑 创建我的房间
                            handleTask5(eventBody);
                            break;
                        case 6:
                            // 处理任务-6 的逻辑 添加10个好友
                            handleTask6(eventBody);
                            break;
                        case 7:
                            // 处理任务-7 的逻辑 加入3个房间
                            handleTask7(eventBody);
                            break;
                        case 8:
                            // 处理任务-8 的逻辑 发送10个幸运礼物
                            handleTask8(eventBody);
                            break;
                        case 9:
                            // 处理任务-9 的逻辑 关注一个用户
                            handleTask9(eventBody);
                            break;
                        case 10:
                            // 处理任务-10 的逻辑 关注一个房间
                            handleTask10(eventBody);
                            break;
                        case 11:
                            // 处理任务-11 的逻辑 填写其他人的邀请码
                            handleTask11(eventBody);
                          break;
                        case 12:
                            // 处理任务-12 的逻辑 管理员任务 - 麦克风使用时长
                            handleAdminMicUsageTask(eventBody);
                            break;
                        case 13:
                            // 处理任务-13 的逻辑 管理员任务 - 新绑定 BD Leader
                            handleAdminNewBdLeaderTask(eventBody.getUserId());
                            break;
                        case 14:
                            // 处理任务-14 的逻辑 管理员任务 - 新绑定 BD
                            handleAdminNewBdTask(eventBody.getUserId());
                            break;
                        case 15:
                            // 处理任务-15 的逻辑 管理员任务 - 新绑定代理
                            handleAdminNewAgencyTask(eventBody.getUserId());
                            break;
                        default:
                            // 处理未知任务 ID 的情况
                            handleUnknownTask(taskId);
                    }
                }
        );
    }

  private void handleTask1(TaskApprovalEvent eventBody) {
        //    // 增加心跳次数 放一天
        String redisKey = "mic:heartbeat:" + eventBody.getUserId();
        String inc = redisService.getString(redisKey);
        if (StringUtils.isEmpty(inc)) {
            // 计算到凌晨的过期时间（秒）
            long expireSeconds = DateTimeAsiaRiyadhUtils.getSecondsUntilMidnight();
            redisService.increment(redisKey, 1, expireSeconds, TimeUnit.SECONDS);
        } else {
            int result = Integer.parseInt(inc) + 1;
            eventBody.setTargetValue(10);
            eventBody.setCompleteValue(Math.min(result, 10));
            updateTaskStatus(eventBody);

            redisService.increment(redisKey, 1);
        }

        // 处理 Spins 上麦任务进度
        handleSpinsMicTask(eventBody.getUserId(), inc);
    }

    /**
     * 处理 Spins 上麦任务进度
     * @param userId 用户ID
     * @param micTimeStr 上麦时长（分钟）字符串
     */
    private void handleSpinsMicTask(Long userId, String micTimeStr) {
        if (StringUtils.isEmpty(micTimeStr)) {
            return;
        }
        
        try {
            int micTime = Integer.parseInt(micTimeStr);

            if (micTime > 90) {
                return;
            }

            // 处理上麦30分钟任务
            spinsUserTaskProgressService.updateTaskProgress(
                    new SpinsTaskProgressUpdateCmd()
                            .setUserId(userId)
                            .setTaskCode("SP_MIC_30_MIN")
                            .setProgressValue(micTime)
            );

            // 处理上麦1小时任务
            spinsUserTaskProgressService.updateTaskProgress(
                    new SpinsTaskProgressUpdateCmd()
                            .setUserId(userId)
                            .setTaskCode("SP_MIC_90_MIN")
                            .setProgressValue(micTime)
            );


            log.info("Spins上麦任务进度更新成功, userId={}, micTime={}", userId, micTime);
        } catch (Exception e) {
            log.error("处理Spins上麦任务进度失败, userId={}, micTimeStr={}", userId, micTimeStr, e);
        }
    }

    private void handleTask2(TaskApprovalEvent eventBody) {
        log.warn("处理任务-2 在房间内赠送礼物: {}", eventBody);
        eventBody.setTargetValue(1);
        eventBody.setCompleteValue(1);
        updateTaskStatus(eventBody);
    }

    private void handleTask6(TaskApprovalEvent eventBody) {
        log.warn("处理任务-6 添加10个好友: {}", eventBody);
        Long friendsCount = relationshipFriendService.selectMyFriendsCount(eventBody.getUserId());

        eventBody.setTargetValue(10);
        eventBody.setCompleteValue(Math.min(friendsCount.intValue(), 10));
        updateTaskStatus(eventBody);

    }


    private void handleTask4(TaskApprovalEvent eventBody) {
        // 具体的任务 4 处理逻辑
        log.warn("处理任务-4 玩一局游戏: {}", eventBody);
        eventBody.setTargetValue(1);
        eventBody.setCompleteValue(1);
        updateTaskStatus(eventBody);
    }

    private void handleUnknownTask(Integer taskId) {
        log.warn("未知任务Id {}", taskId);
    }

    // 日常任务 更新任务状态的方法示例
    private boolean updateTaskStatus(TaskApprovalEvent event) {
        if (taskService.checkTaskStatus(event.getUserId(), Long.valueOf(event.getTaskId()), event.getDay())) {
            // 如果有目标值和完成值，使用带进度的方法
            if (event.getTargetValue() != null && event.getCompleteValue() != null) {
                taskService.updateTaskStatus(
                    0, // status传 0，具体状态由方法内部根据 targetValue 和 completeValue 判断
                    event.getUserId(), 
                    Long.valueOf(event.getTaskId()), 
                    event.getDay(),
                    event.getTargetValue(),
                    event.getCompleteValue()
                );
            } else {
                // 没有进度值，直接设置为已完成
                taskService.updateTaskStatus(1, event.getUserId(), Long.valueOf(event.getTaskId()), event.getDay());
            }
            return true;
        }
        log.warn("任务已完成 {}", event);
        return false;
    }

    private void handleTask3(TaskApprovalEvent eventBody) {
        log.warn("处理任务-3: {}", eventBody);
        eventBody.setTargetValue(1);
        eventBody.setCompleteValue(1);
        updateTaskStatus(eventBody);
    }

    private void handleTask8(TaskApprovalEvent eventBody) {
        log.warn("处理任务-8 发送10个幸运礼物: {}", eventBody);

        String redisKey = "task:lucky-gift:count:" + eventBody.getUserId();
        int num = eventBody.getQuantity() == null ? 1 : eventBody.getQuantity();

        // 获取当前计数
        String countStr = redisService.getString(redisKey);
        int currentCount = StringUtils.isEmpty(countStr) ? 0 : Integer.parseInt(countStr);

        // 计算新的计数值
        int newCount = currentCount + num;

        // 更新任务进度
        eventBody.setTargetValue(10);
        eventBody.setCompleteValue(Math.min(newCount, 10));
        boolean updated = updateTaskStatus(eventBody);

        // 只有任务状态更新成功才更新 Redis
        if (updated) {
            redisService.increment(redisKey, num);
        }
    }

    private void handleTask9(TaskApprovalEvent eventBody) {
        log.warn("处理任务-9 关注一个用户: {}", eventBody);
        // 关注用户计数，每日过期
        String redisKey = "task:follow-user:" + eventBody.getUserId();
        String countStr = redisService.getString(redisKey);

        if (StringUtils.isBlank(countStr)) {
            // 计算到凌晨的过期时间（秒）
            long expireSeconds = DateTimeAsiaRiyadhUtils.getSecondsUntilMidnight();
            redisService.increment(redisKey, 1, expireSeconds, TimeUnit.SECONDS);
            // 第一次关注就完成任务
            eventBody.setTargetValue(1);
            eventBody.setCompleteValue(1);
            boolean updated = updateTaskStatus(eventBody);
            if (updated) {
              redisService.increment(redisKey, 1);
            }
        }
    }

    private void handleTask10(TaskApprovalEvent eventBody) {
        log.warn("处理任务-10 关注一个房间: {}", eventBody);
        // 关注房间计数，每日过期
        String redisKey = "task:follow-room:" + eventBody.getUserId();
        String countStr = redisService.getString(redisKey);
        
        if (StringUtils.isEmpty(countStr)) {
            // 计算到凌晨的过期时间（秒）
            long expireSeconds = DateTimeAsiaRiyadhUtils.getSecondsUntilMidnight();
            redisService.increment(redisKey, 1, expireSeconds, TimeUnit.SECONDS);
            eventBody.setTargetValue(1);
            eventBody.setCompleteValue(1);
            // 第一次关注就完成任务
            updateTaskStatus(eventBody);
        } else {
            // 已经完成过了
            if (Integer.parseInt(countStr) >= 1) {
                updateTaskStatus(eventBody);
            } else {
                redisService.increment(redisKey, 1);
                updateTaskStatus(eventBody);
            }
        }
    }

    private void handleTask11(TaskApprovalEvent eventBody) {
      log.warn("处理任务-11: {}", eventBody);
      eventBody.setTargetValue(1);
      eventBody.setCompleteValue(1);
      updateTaskStatus(eventBody);

      // 处理成已领取
        LambdaQueryWrapper<UserTaskProgress> eq = new LambdaQueryWrapper<UserTaskProgress>()
                .eq(UserTaskProgress::getUserId, eventBody.getUserId())
                .eq(UserTaskProgress::getTaskStatus, 1)
                .eq(UserTaskProgress::getTaskId, eventBody.getTaskId())
                .eq(UserTaskProgress::getIsRewardCollected, 0);
        List<UserTaskProgress> userTaskProgresses = userTaskProgressDAO.selectList(eq);
        if (userTaskProgresses == null || userTaskProgresses.isEmpty()) {
            return;
        }
        UserTaskProgress userTaskProgress = userTaskProgresses.get(0);
        userTaskProgress.setIsRewardCollected(1);
        userTaskProgress.setCompletedTime(TimestampUtils.now());
        userTaskProgressDAO.updateById(userTaskProgress);

        // 发送道具
        /*propsActivityCnfClient.sendActivityReward(new SendActivityRewardCmd()
                .setTrackId(IdWorkerUtils.getId())
                .setSysOrigin(SysOriginPlatformEnum.LIKEI)
                .setAcceptUserId(eventBody.getUserId())
                .setSourceGroupId(userTaskProgress.getRewardId())
                .setOrigin(SendPropsOrigin.DAILY_TASK_REWARD)
        );
*/
        // 给邀请人和被邀请人发送金币奖励
        handleInviteUserGold(eventBody.getUserId());

    }

    private void handleInviteUserGold(Long userId) {
        List<UserInviteUser> allInvites = userInviteUserDAO.selectList(
                new LambdaQueryWrapper<UserInviteUser>()
                        .eq(UserInviteUser::getInviteUserId, userId)
                        .orderByDesc(UserInviteUser::getCreateTime)
        );

        if (CollectionUtils.isEmpty(allInvites)) {
            return;
        }
        UserInviteUser userInviteUser = allInvites.get(0);

        if (!isNewUserWithinDays(userInviteUser, 7)) {
            return;
        }

        // 金币奖励发给邀请人A 500
        long gold = 500;
        walletGoldClient.changeBalance(GoldReceiptCmd.builder()
                .appIncome()
                .userId(userInviteUser.getUserId())
                .eventId(userInviteUser.getUserId())
                .sysOrigin(userInviteUser.getSysOrigin())
                .origin(GoldOrigin.INVITE_USER_REWARDS)
                .originDescribe(GoldOrigin.INVITE_USER_REWARDS.getDesc())
                .amount(BigDecimal.valueOf(gold))
                .build());

        // 金币奖励发给邀请人B 450
        walletGoldClient.changeBalance(GoldReceiptCmd.builder()
                .appIncome()
                .userId(userInviteUser.getInviteUserId())
                .eventId(userInviteUser.getInviteUserId())
                .sysOrigin(userInviteUser.getSysOrigin())
                .origin(GoldOrigin.INVITE_USER_REWARDS)
                .originDescribe(GoldOrigin.INVITE_USER_REWARDS.getDesc())
                .amount(BigDecimal.valueOf(450))
                .build());

        inviteUserSummaryService.incrCommission(userInviteUser.getUserId(), BigDecimal.valueOf(gold));
        inviteUserRechargeCommissionService.add(SysOriginPlatformEnum.LIKEI.name(), userInviteUser.getUserId(),
                userInviteUser.getInviteUserId(), BigDecimal.valueOf(gold));

        recordRanking(userInviteUser.getUserId(), gold);

    }

    /** 判断绑定时间是否为N天内 */
    private boolean isNewUserWithinDays(UserInviteUser userInviteUser, int days) {
        Duration duration = Duration.between(userInviteUser.getCreateTime().toLocalDateTime(), LocalDateTime.now());
        return duration.toDays() < days;
    }

    private void recordRanking(Long userId, Long quantity) {
        RankingActivityRecord record = new RankingActivityRecord();
        record.setSysOrigin(SysOriginPlatformEnum.LIKEI.name());
        record.setUserId(userId);
        record.setUserSex(1);
        record.setActivityType(RankingActivityType.INVITE);
        record.setCycleType(RankingCycleType.WEEKLY);
        record.setCycleKey(ZonedDateTimeAsiaRiyadhUtils.nowWeekMondayToInt().toString());
        record.setDimension(RankingDimension.CONSUME_AMOUNT);
        record.setExpiredTime(new Timestamp(System.currentTimeMillis() + 30L * 24 * 60 * 60 * 1000));
        rankingActivityGateway.accumulateRankingData(record, quantity);
    }


    private void handleTask7(TaskApprovalEvent eventBody) {
        log.warn("处理任务-10 加入3个房间: {}", eventBody);
        //    // 进入一次 +1
        String redisKey = "task:add-room::" + eventBody.getUserId();
        String inc = redisService.getString(redisKey);
        if (StringUtils.isEmpty(inc)) {
            redisService.increment(redisKey, 1);
        } else {
            int result = Integer.parseInt(inc) + 1;
            eventBody.setTargetValue(3);
            eventBody.setCompleteValue(Math.min(result, 3));
            boolean updated = updateTaskStatus(eventBody);
            if (updated) {
              redisService.increment(redisKey, 1);
            }
        }
    }

    private void handleTask5(TaskApprovalEvent eventBody) {
        log.warn("处理任务-5 创建我的房间: {}", eventBody);
        eventBody.setTargetValue(1);
        eventBody.setCompleteValue(1);
        updateTaskStatus(eventBody);

    }

    // ==================== 管理员任务处理 ====================

    /**
     * 处理管理员任务 - 麦克风使用时长
     */
    private void handleAdminMicUsageTask(TaskApprovalEvent eventBody) {
        Long userId = eventBody.getUserId();

        // Redis key：用于记录心跳次数
        String redisKey = "admin:heartbeat:" + userId;
        String incValue = redisService.getString(redisKey);

        // 计算到第二天0点的过期时间
        long expireSeconds = calculateDailyExpireSeconds();

        // 心跳计数：每次心跳+1
        if (StringUtils.isEmpty(incValue)) {
            // 首次心跳，初始化为1，并设置过期时间
            redisService.increment(redisKey, 1, expireSeconds, TimeUnit.SECONDS);
            return;
        } else {
            // 递增心跳计数
            long currentCount = redisService.increment(redisKey, 1, expireSeconds, TimeUnit.SECONDS);

            // 每天最多2小时 = 120次心跳
            if (currentCount > 120) {
                log.info("管理员麦克风使用时长已达今日上限(2小时)，跳过记录, userId={}, currentCount={}", userId, currentCount);
                return;
            }

            if (currentCount % 60 != 0) {
                return;
            }
        }

        // 满1小时，任务进度+1
        int micHours = 1;

        try {
            String MIC_TYPE = AdminTaskType.MIC_USAGE.name();
            if (adminTaskService.isTaskCompleted(userId, MIC_TYPE, null)) {
                log.info("管理员麦克风使用时长任务已完成，跳过更新, userId={}", userId);
                return;
            }

            // 更新任务进度
            AdminTaskProgressUpdateCmd updateCmd = new AdminTaskProgressUpdateCmd();
            updateCmd.setUserId(userId);
            updateCmd.setTaskType(MIC_TYPE);
            updateCmd.setIncrementValue(micHours);
            adminTaskService.updateTaskProgress(updateCmd);
            log.info("管理员麦克风使用时长任务进度更新成功, userId={}, micHours={}", userId, micHours);
        } catch (Exception e) {
            log.error("处理管理员麦克风使用时长任务失败, userId={}, micHours={}", userId, micHours, e);
        }
    }

    /**
     * 处理管理员任务 - 新绑定 BD Leader
     */
    private void handleAdminNewBdLeaderTask(Long userId) {
        try {
            String BD_LEADER_TYPE = AdminTaskType.NEW_BD_LEADERS.name();
            // 检查任务是否已完成
            if (adminTaskService.isTaskCompleted(userId, BD_LEADER_TYPE, null)) {
                log.info("管理员新绑定 BD Leader 任务已完成，跳过更新, userId={}", userId);
                return;
            }

            // 更新任务进度
            AdminTaskProgressUpdateCmd updateCmd = new AdminTaskProgressUpdateCmd();
            updateCmd.setUserId(userId);
            updateCmd.setTaskType(BD_LEADER_TYPE);
            updateCmd.setIncrementValue(1);
            adminTaskService.updateTaskProgress(updateCmd);
            log.info("管理员新绑定 BD Leader 任务进度更新成功, userId={}", userId);
        } catch (Exception e) {
            log.error("处理管理员新绑定 BD Leader 任务失败, userId={}", userId, e);
        }
    }

    /**
     * 处理管理员任务 - 新绑定 BD
     */
    private void handleAdminNewBdTask(Long userId) {
        try {
            String BD_TYPE = AdminTaskType.NEW_BDS.name();
            if (adminTaskService.isTaskCompleted(userId, BD_TYPE, null)) {
                log.info("管理员新绑定 BD 任务已完成，跳过更新, userId={}", userId);
                return;
            }

            // 更新任务进度
            AdminTaskProgressUpdateCmd updateCmd = new AdminTaskProgressUpdateCmd();
            updateCmd.setUserId(userId);
            updateCmd.setTaskType(BD_TYPE);
            updateCmd.setIncrementValue(1);
            adminTaskService.updateTaskProgress(updateCmd);
            log.info("管理员新绑定 BD 任务进度更新成功, userId={}", userId);
        } catch (Exception e) {
            log.error("处理管理员新绑定 BD 任务失败, userId={}", userId, e);
        }
    }

    /**
     * 处理管理员任务 - 新绑定代理
     */
    private void handleAdminNewAgencyTask(Long userId) {
        try {
            String AGENCY_TYPE = AdminTaskType.NEW_AGENCIES.name();
            if (adminTaskService.isTaskCompleted(userId, AGENCY_TYPE, null)) {
                log.info("管理员新绑定代理任务已完成，跳过更新, userId={}", userId);
                return;
            }

            // 更新任务进度
            AdminTaskProgressUpdateCmd updateCmd = new AdminTaskProgressUpdateCmd();
            updateCmd.setUserId(userId);
            updateCmd.setTaskType(AGENCY_TYPE);
            updateCmd.setIncrementValue(1);
            adminTaskService.updateTaskProgress(updateCmd);
            log.info("管理员新绑定代理任务进度更新成功, userId={}", userId);
        } catch (Exception e) {
            log.error("处理管理员新绑定代理任务失败, userId={}", userId, e);
        }
    }

    private long calculateDailyExpireSeconds() {
        // 使用沙特时区
        ZoneId riyadhZone = ZoneId.of("Asia/Riyadh");
        ZonedDateTime now = ZonedDateTime.now(riyadhZone);

        // 过期到第二天0点
        ZonedDateTime expireTime = now.plusDays(1)
                .withHour(0)
                .withMinute(0)
                .withSecond(0)
                .withNano(0);

        // 计算秒数差
        long expireSeconds = Duration.between(now, expireTime).getSeconds();

        log.debug("计算每日过期时间, currentTime={}, expireTime={}, expireSeconds={}",
                now, expireTime, expireSeconds);

        return expireSeconds;
    }

}
