package com.xxfc.platform.activity.handler;

import com.rabbitmq.client.Channel;
import com.xxfc.platform.activity.biz.ActivityAttendanceRecordBiz;
import com.xxfc.platform.activity.biz.ActivityPrizeBiz;
import com.xxfc.platform.activity.biz.ActivityWinningRecordBiz;
import com.xxfc.platform.activity.biz.UserCouponBiz;
import com.xxfc.platform.activity.config.RabbitActivityConfig;
import com.xxfc.platform.activity.constant.PrizeGoodsTypeEnum;
import com.xxfc.platform.activity.dto.ActivityLotteryDTO;
import com.xxfc.platform.activity.dto.UserCouponSendDTO;
import com.xxfc.platform.activity.entity.ActivityWinningRecord;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.Date;
import java.util.concurrent.TimeUnit;

/**
 * @author libin
 * @version 1.0
 * @description
 * @data 2019/12/13 11:22
 */
@Component
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
@Slf4j
public class ActivityPrizeMqHandler {
    private final ActivityPrizeBiz activityPrizeBiz;
    private final ActivityAttendanceRecordBiz activityAttendanceRecordBiz;
    private final ActivityWinningRecordBiz activityWinningRecordBiz;
    private final UserCouponBiz userCouponBiz;
    private final RedisTemplate<String, Object> redisTemplate;
    @Resource(name = "redisTemplate")
    private ValueOperations valueOperations;
    private final String R_CONSUME = "lottery:reconsume";
    private final int R_CONSUME_MAX_NUM = 3;

    @RabbitListener(queues = RabbitActivityConfig.PRIZE_RECORD_QUEUE)
    public void processActivityPrizeMsg(ActivityLotteryDTO activityLotteryDTO, Channel channel) {
        log.info("抽奖消息的数据【{}】", activityLotteryDTO);
        try {
            if (activityLotteryDTO.getHasWinning() == 1) {
                //更新库存
                log.info("更新库存:参数【prizeType:{}==serialNumber:{}】", activityLotteryDTO.getPrizeType(), activityLotteryDTO.getSerialNumber());
                activityPrizeBiz.updatePrizeStock(activityLotteryDTO.getPrizeType(), activityLotteryDTO.getSerialNumber());
                //发放优惠券
                if (activityLotteryDTO.getPrizeGoodsType() == PrizeGoodsTypeEnum.COUPON.getCode()) {
                    UserCouponSendDTO userCouponSendDTO = new UserCouponSendDTO();
                    userCouponSendDTO.setCouponId(activityLotteryDTO.getGoodsId());
                    userCouponSendDTO.setCouponNum(1);
                    userCouponSendDTO.setPhone(activityLotteryDTO.getPhone());
                    log.info("抽中优惠券发送：【参数：{}】", userCouponSendDTO);
                    userCouponBiz.sendCoupon(userCouponSendDTO);
                }
            }
            ActivityWinningRecord activityWinningRecord = new ActivityWinningRecord();
            BeanUtils.copyProperties(activityLotteryDTO, activityWinningRecord);
            activityWinningRecord.setCrtTime(new Date());
            log.info("抽奖记录【{}】", activityWinningRecord);
            activityWinningRecordBiz.saveRecord(activityWinningRecord);
            //更改对应抽奖类型的抽奖次数
            log.info("更改对应抽奖类型的抽奖次数【activityId:{}==userId:{}==prizeType:{}】", activityLotteryDTO.getActivityId(), activityLotteryDTO.getUserId(), activityLotteryDTO.getPrizeType());
            activityAttendanceRecordBiz.updateLotteryNumByActivityIdAndUserIdAndPrizeType(activityLotteryDTO.getActivityId(), activityLotteryDTO.getUserId(), activityLotteryDTO.getPrizeType());
        } catch (Exception ex) {
            log.error("抽奖消息消费失败【{}】", ex);
            try {
                Long reConsumeCounter = valueOperations.increment(R_CONSUME);
                if (reConsumeCounter <= R_CONSUME_MAX_NUM) {
                    channel.basicRecover(false);
                    log.info("抽奖消息重回队列成功");
                }
                if (reConsumeCounter == 1) {
                    redisTemplate.expire(R_CONSUME, 1, TimeUnit.DAYS);
                }
            } catch (IOException e) {
                log.error("消费抽奖消息重回队列失败【{}】", e);
            }

        }
    }
}
