package com.seamew.lottery.application.mq.consumer;

import com.alibaba.fastjson2.JSON;
import com.seamew.lottery.application.mq.producer.KafkaProducer;
import com.seamew.lottery.domain.activity.model.vo.ActivityPartakeRecordVO;
import com.seamew.lottery.domain.strategy.model.vo.AwardDeductStockVO;
import com.seamew.lottery.domain.strategy.service.draw.IDrawExec;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.springframework.kafka.annotation.KafkaListener;
import org.springframework.kafka.support.Acknowledgment;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

/**
 * @Author: seamew
 * @Title: LotteryAwardDeductStockListener
 * @CreateTime: 2023年03月03日 22:48:00
 * @Description: 削减奖品库存监听消息
 * @Version: 1.0
 */
@Component
@Slf4j
public class LotteryAwardDeductStockListener {
    @Resource
    IDrawExec drawExec;

    @KafkaListener(topics = KafkaProducer.TOPIC_AWARD_SURPLUS_COUNT, groupId = KafkaProducer.GROUP_NAME)
    public void onMessage(ConsumerRecord<?, ?> record, Acknowledgment ack) {
        // 1. 判断消息是否存在
        if (ObjectUtils.isEmpty(record.value())) {
            return;
        }

        try {
            // 2. 转化对象
            AwardDeductStockVO awardDeductStockVO = JSON.parseObject((String) record.value(), AwardDeductStockVO.class);
            log.info("消费MQ消息，异步扣减奖品库存 message：{}", awardDeductStockVO);

            // 3. 更新数据库库存【实际场景业务体量较大，可能也会由于MQ消费引起并发，对数据库产生压力，所以如果并发量较大，可以把库存记录缓存中，并使用定时任务进行处理缓存和数据库库存同步，减少对数据库的操作次数】
            drawExec.updateAwardStock(awardDeductStockVO);
            ack.acknowledge();
        } catch (Exception e) {
            // 削减库存失败
            log.error("削减库存失败--消费MQ消息，失败 topic：{} message：{}", record.topic(), record.value());
            throw e;
        }

    }
}
