package com.hai.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.hai.common.exception.ErrorCode;
import com.hai.common.exception.ErrorHelp;
import com.hai.common.exception.SysCode;
import com.hai.dao.HighActivityUserLotteryNumMapper;
import com.hai.entity.*;
import com.hai.enum_type.ActivityInfoStatus;
import com.hai.service.*;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;

@Service("highActivityUserLotteryNumService")
public class HighActivityUserLotteryNumServiceImpl implements HighActivityUserLotteryNumService {

    @Resource
    private HighActivityInfoService highActivityInfoService;

    @Resource
    private HighActivityAwardSerialNumService highActivityAwardSerialNumService;

    @Resource
    private HighActivityAwardActualPrizeService highActivityAwardActualPrizeService;

    @Resource
    private HighActivityAwardUserService highActivityAwardUserService;

    @Resource
    private HighActivityPrizeService highActivityPrizeService;

    @Resource
    private HighActivityUserLotteryNumMapper highActivityUserLotteryNumMapper;

    @Resource
    private HighDiscountUserRelService highDiscountUserRelService;

    @Override
    @Transactional(rollbackFor = Exception.class,
            propagation= Propagation.REQUIRES_NEW,
            isolation= Isolation.SERIALIZABLE,
            timeout = 30)
    public Object userLottery(Long activityId, Long userId) {
        // 查询活动未中奖的号码
        List<HighActivityAwardSerialNum> serialNumList = highActivityAwardSerialNumService.getNoGainListByActivity(activityId);
        if (serialNumList.size() == 0) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "奖励已经被抽完了");
        }
        // 减去用户抽奖次数
        minusLotteryNum(activityId,userId);

        // 抽中的号码
        int index = (int) (Math.random() * serialNumList.size());
        HighActivityAwardSerialNum serialNum = serialNumList.get(index);
        serialNum.setStatus(2);
        highActivityAwardSerialNumService.update(serialNum);

        // 增加中奖记录
        highActivityAwardUserService.insertAwardUser(serialNum.getId(),userId);

        // 异步领取奖品，减少接口响应时间
        new Thread(() -> {
            // 领取奖品
            receivePrize(serialNum,userId);
        }).start();

        JSONObject jsonObject = new JSONObject();
        jsonObject.put("activityAwardId", serialNum.getActivityAwardId());
        jsonObject.put("serialNum", serialNum.getSerialNum());
        return jsonObject;
    }

    /**
     * 领取奖品
     */
    private void receivePrize(HighActivityAwardSerialNum serialNum, Long userId) {
        // 查询中奖的奖品
        List<HighActivityAwardActualPrize> prizeList = highActivityAwardActualPrizeService.getActualPrizeBySerialNumId(serialNum.getId());
        for (HighActivityAwardActualPrize actualPrize : prizeList) {

            // 实际奖品类型   1：卡券   2：优惠券
            if (actualPrize.getActualPrizeType() == 2) {
                highDiscountUserRelService.receiveDiscount(userId,actualPrize.getActualPrizeId());
            }
        }
    }

    @Override
    public void addLotteryNum(Long activityId, Long userId, Integer num) {
        HighActivityUserLotteryNum detail = getDetail(activityId, userId);
        if (detail == null) {
            detail = new HighActivityUserLotteryNum();
            detail.setActivityInfoId(activityId);
            detail.setUserId(userId);
            detail.setLotteryNum(num);
            detail.setCreateTime(new Date());
            detail.setUpdateTime(new Date());
            highActivityUserLotteryNumMapper.insert(detail);
        } else {
            detail.setLotteryNum(detail.getLotteryNum() + num);
            detail.setUpdateTime(new Date());
            highActivityUserLotteryNumMapper.updateByPrimaryKey(detail);
        }
    }

    @Override
    public void minusLotteryNum(Long activityId, Long userId) {
        HighActivityUserLotteryNum detail = getDetail(activityId, userId);
        if (detail != null) {
            detail.setLotteryNum(detail.getLotteryNum() - 1);
            highActivityUserLotteryNumMapper.updateByPrimaryKeySelective(detail);
        }
    }

    @Override
    public HighActivityUserLotteryNum getDetail(Long activityId, Long userId) {
        HighActivityUserLotteryNumExample example = new HighActivityUserLotteryNumExample();
        example.createCriteria().andUserIdEqualTo(userId).andActivityInfoIdEqualTo(activityId);
        List<HighActivityUserLotteryNum> list = highActivityUserLotteryNumMapper.selectByExample(example);
        if (list.size() > 0) {
            return list.get(0);
        }
        return null;
    }

    @Override
    public Integer getLotteryNum(Long activityId, Long userId) {
        HighActivityUserLotteryNum detail = getDetail(activityId, userId);
        if (detail == null) {
            return 0;
        }
        return detail.getLotteryNum();
    }

}
