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

import com.red.circle.component.redis.service.RedisService;
import com.red.circle.order.inner.model.enums.MonthlyRechargeType;
import com.red.circle.other.app.util.DistributedLockUtil;
import com.red.circle.other.infra.database.rds.dao.activity.UserActivityRechargeDAO;
import com.red.circle.other.inner.endpoint.activity.LotteryTicketClient;
import com.red.circle.tool.core.date.ZonedDateTimeAsiaRiyadhUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.concurrent.TimeUnit;

@Service
@RequiredArgsConstructor
@Slf4j
public class ActivityRechargeTicketService {

    private final UserActivityRechargeDAO userActivityRechargeDAO;
    private final RedisService redisService;
    private final LotteryTicketClient lotteryTicketClient;
    private final DistributedLockUtil distributedLockUtil;
    
    /**
     * 2026春节游戏礼物活动
     */
    private static final Long FIXED_ACTIVITY_ID = -1L;
    
    /**
     * 每100000金币发放1张抽奖券
     */
    private static final long TICKET_THRESHOLD = 100000L;

    public void accumulatedRechargeAndAddTicket(Long userId, Long rewardAmount, MonthlyRechargeType type) {
        // 1. 先累加金币到数据库
        LocalDate today = ZonedDateTimeAsiaRiyadhUtils.now().toLocalDate();
        String rechargeDate = today.toString();
        userActivityRechargeDAO.incrAmount(
                userId,
                FIXED_ACTIVITY_ID,
                rechargeDate,
                type.name(),
                BigDecimal.valueOf(rewardAmount)
        );

        String lockKey = String.format("lucky:draw:lock:%s:%s", userId, FIXED_ACTIVITY_ID);
        try {
            distributedLockUtil.executeWithLock(lockKey, () -> {
                // 在锁内执行抽奖券发放逻辑
                try {
                    processTicketDistribution(userId);
                } catch (Exception e) {
                    log.error("执行抽奖券发放失败：{}", e.getMessage());
                }
            });
        } catch (Exception ignored) {
        }

    }
    
    /**
     * 处理抽奖券发放（在分布式锁保护下执行）
     */
    private void processTicketDistribution(Long userId) {
        String thresholdKey = String.format("lucky:draw:threshold:%s:%s", userId, FIXED_ACTIVITY_ID);

        BigDecimal totalWinCoins = userActivityRechargeDAO.getUserTotalAmount(userId, FIXED_ACTIVITY_ID, null);
        if (totalWinCoins == null || totalWinCoins.longValue() == 0) {
            return;
        }

        // 获取上次发放时的总金额
        String lastTotalStr = redisService.getString(thresholdKey);
        long lastTotal = lastTotalStr != null ? Long.parseLong(lastTotalStr) : 0L;

        // 计算应发放的抽奖券数量
        long currentTotal = totalWinCoins.longValue();
        int currentTickets = (int) (currentTotal / TICKET_THRESHOLD);  // 当前应有的券数
        int lastTickets = (int) (lastTotal / TICKET_THRESHOLD);        // 上次已发的券数
        int ticketsToGive = currentTickets - lastTickets;              // 本次应发券数

        if (ticketsToGive > 0) {
            log.info("准备发放抽奖券, userId={}, ticketsToGive={}, currentTotal={}, lastTotal={}", 
                userId, ticketsToGive, currentTotal, lastTotal);
            
            // 逐张发放抽奖券
            int successCount = 0;
            for (int i = 0; i < ticketsToGive; i++) {
                try {
                    lotteryTicketClient.addTicket(
                            userId,
                            FIXED_ACTIVITY_ID,
                            1,
                            "LUCK_GIFT",
                            "LUCK_GIFT_" + currentTotal + "_" + i
                    );
                    successCount++;
                } catch (Exception e) {
                    log.error("发放第{}张抽奖券失败, userId={}, currentTotal={}", 
                        i + 1, userId, currentTotal, e);
                }
            }
            
            // 更新Redis记录（只有成功发放了至少1张才更新）
            if (successCount > 0) {
                long newThreshold = lastTotal + (successCount * TICKET_THRESHOLD);
                redisService.setString(thresholdKey, String.valueOf(newThreshold));
                log.info("抽奖券发放完成, userId={}, 成功发放={}/{}, 更新threshold={}", 
                    userId, successCount, ticketsToGive, newThreshold);
            }
        }
    }
}