package com.mosquito.project.service;

import com.mosquito.project.persistence.entity.UserRewardEntity;
import com.mosquito.project.persistence.repository.UserRewardRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.Duration;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.util.UUID;

/**
 * 优惠券奖励服务
 * 负责优惠券的验证、发放和幂等处理
 */
@Service
public class CouponRewardService {

    private static final Logger log = LoggerFactory.getLogger(CouponRewardService.class);

    // Redis key前缀
    private static final String COUPON_BATCH_KEY_PREFIX = "coupon:batch:";
    private static final String COUPON_GRANT_LOCK_PREFIX = "coupon:lock:";

    // 幂等锁超时时间
    private static final Duration LOCK_TIMEOUT = Duration.ofMinutes(10);

    private final UserRewardRepository userRewardRepository;
    private final StringRedisTemplate redisTemplate;

    public CouponRewardService(UserRewardRepository userRewardRepository,
                               StringRedisTemplate redisTemplate) {
        this.userRewardRepository = userRewardRepository;
        this.redisTemplate = redisTemplate;
    }

    /**
     * 验证优惠券批次是否存在且有效
     * @param couponBatchId 优惠券批次ID
     * @return 验证结果
     */
    public CouponValidationResult validateCouponBatch(String couponBatchId) {
        if (couponBatchId == null || couponBatchId.isBlank()) {
            return new CouponValidationResult(false, "优惠券批次ID不能为空");
        }

        // 检查Redis中是否存在该批次（模拟实际优惠券系统验证）
        String batchKey = COUPON_BATCH_KEY_PREFIX + couponBatchId;
        String batchInfo = redisTemplate.opsForValue().get(batchKey);

        if (batchInfo == null) {
            // 尝试从数据库中查找（如果Redis中没有，则查询数据库）
            log.info("优惠券批次 {} 不在缓存中，尝试数据库查询", couponBatchId);
            // 这里可以扩展为查询优惠券批次表的逻辑
            // 目前默认所有格式正确的批次ID都是有效的
            return new CouponValidationResult(true, "优惠券批次有效");
        }

        return new CouponValidationResult(true, "优惠券批次有效");
    }

    /**
     * 发放优惠券奖励（幂等操作）
     * @param rewardId 奖励记录ID
     * @param couponBatchId 优惠券批次ID
     * @param userId 用户ID
     * @return 发放结果
     */
    @Transactional
    public CouponGrantResult grantCoupon(Long rewardId, String couponBatchId, Long userId) {
        if (rewardId == null || couponBatchId == null || userId == null) {
            return new CouponGrantResult(false, "参数不能为空", null);
        }

        // 获取分布式锁实现幂等
        String lockKey = COUPON_GRANT_LOCK_PREFIX + rewardId;
        Boolean acquired = redisTemplate.opsForValue().setIfAbsent(lockKey, "1", LOCK_TIMEOUT);

        if (Boolean.FALSE.equals(acquired)) {
            // 已存在锁，说明可能正在处理或已处理
            log.warn("优惠券发放锁已存在，rewardId={}", rewardId);
            return new CouponGrantResult(false, "优惠券正在发放中，请勿重复操作", null);
        }

        try {
            // 查询奖励记录
            UserRewardEntity reward = userRewardRepository.findById(rewardId)
                    .orElse(null);

            if (reward == null) {
                log.error("奖励记录不存在，rewardId={}", rewardId);
                return new CouponGrantResult(false, "奖励记录不存在", null);
            }

            // 检查是否已发放
            if ("GRANTED".equals(reward.getStatus())) {
                log.info("优惠券已发放，rewardId={}, couponCode={}", rewardId, reward.getCouponCode());
                return new CouponGrantResult(true, "优惠券已发放", reward.getCouponCode());
            }

            // 检查状态
            if (!"APPROVED".equals(reward.getStatus())) {
                log.warn("奖励状态不允许发放，rewardId={}, status={}", rewardId, reward.getStatus());
                return new CouponGrantResult(false, "奖励状态不允许发放", null);
            }

            // 生成优惠券码（实际应调用优惠券系统API）
            String couponCode = generateCouponCode(couponBatchId, userId);

            // 更新奖励记录
            reward.setStatus("GRANTED");
            reward.setCouponBatchId(couponBatchId);
            reward.setCouponCode(couponCode);
            reward.setCouponValue(getCouponValue(couponBatchId));
            userRewardRepository.save(reward);

            log.info("优惠券发放成功，rewardId={}, couponBatchId={}, couponCode={}",
                    rewardId, couponBatchId, couponCode);

            return new CouponGrantResult(true, "优惠券发放成功", couponCode);

        } catch (Exception e) {
            log.error("优惠券发放失败，rewardId={}, error={}", rewardId, e.getMessage(), e);
            return new CouponGrantResult(false, "优惠券发放失败: " + e.getMessage(), null);
        } finally {
            // 释放锁
            redisTemplate.delete(lockKey);
        }
    }

    /**
     * 批量发放优惠券
     */
    @Transactional
    public int batchGrantCoupons(java.util.List<Long> rewardIds) {
        int count = 0;
        for (Long rewardId : rewardIds) {
            UserRewardEntity reward = userRewardRepository.findById(rewardId).orElse(null);
            if (reward != null && "COUPON".equals(reward.getType())
                    && "APPROVED".equals(reward.getStatus())) {
                CouponGrantResult result = grantCoupon(
                        rewardId,
                        reward.getCouponBatchId(),
                        reward.getUserId()
                );
                if (result.isSuccess()) {
                    count++;
                }
            }
        }
        return count;
    }

    /**
     * 生成优惠券码
     */
    private String generateCouponCode(String couponBatchId, Long userId) {
        // 实际应调用优惠券系统API生成
        // 这里使用UUID模拟
        String uuid = UUID.randomUUID().toString().replace("-", "").substring(0, 12).toUpperCase();
        return String.format("%s-%s-%d", couponBatchId, uuid, userId);
    }

    /**
     * 获取优惠券面值
     */
    private String getCouponValue(String couponBatchId) {
        // 实际应从优惠券系统获取
        // 这里返回默认值
        String batchKey = COUPON_BATCH_KEY_PREFIX + couponBatchId;
        String value = redisTemplate.opsForValue().get(batchKey + ":value");
        return value != null ? value : "10"; // 默认10元
    }

    /**
     * 优惠券验证结果
     */
    public static class CouponValidationResult {
        private final boolean valid;
        private final String message;

        public CouponValidationResult(boolean valid, String message) {
            this.valid = valid;
            this.message = message;
        }

        public boolean isValid() { return valid; }
        public String getMessage() { return message; }
    }

    /**
     * 优惠券发放结果
     */
    public static class CouponGrantResult {
        private final boolean success;
        private final String message;
        private final String couponCode;

        public CouponGrantResult(boolean success, String message, String couponCode) {
            this.success = success;
            this.message = message;
            this.couponCode = couponCode;
        }

        public boolean isSuccess() { return success; }
        public String getMessage() { return message; }
        public String getCouponCode() { return couponCode; }
    }
}
