package com.qs.mp.user.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.qs.mp.admin.domain.Goods;
import com.qs.mp.admin.domain.GoodsSku;
import com.qs.mp.admin.domain.vo.UserExchangeOrderVO;
import com.qs.mp.admin.service.IGoodsService;
import com.qs.mp.admin.service.IGoodsSkuService;
import com.qs.mp.common.enums.ErrorCodeEnum;
import com.qs.mp.common.enums.GoodsStatusEnum;
import com.qs.mp.common.enums.PrizeStorageInTypeEnum;
import com.qs.mp.common.enums.PrizeStorageStatusEnum;
import com.qs.mp.common.exception.ServiceException;
import com.qs.mp.system.service.id.BizIdGenerator;
import com.qs.mp.user.domain.UserCoin;
import com.qs.mp.user.domain.UserExchangeOrder;
import com.qs.mp.user.domain.UserPrizeStorage;
import com.qs.mp.user.domain.vo.TicketHitPrizeBarrageVO;
import com.qs.mp.user.mapper.UserExchangeOrderMapper;
import com.qs.mp.user.service.IUserCoinService;
import com.qs.mp.user.service.IUserExchangeOrderService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qs.mp.user.service.IUserPrizeStorageService;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;

/**
 * <p>
 * 用户盲豆兑换订单 服务实现类
 * </p>
 *
 * @author quanshu
 * @since 2022-03-07
 */
@Service
public class UserExchangeOrderServiceImpl extends ServiceImpl<UserExchangeOrderMapper, UserExchangeOrder> implements IUserExchangeOrderService {

  @Autowired
  private IGoodsService goodsService;

  @Autowired
  private IGoodsSkuService goodsSkuService;

  @Autowired
  private IUserCoinService userCoinService;

  @Autowired
  private IUserPrizeStorageService userPrizeStorageService;

  @Autowired
  private BizIdGenerator bizIdGenerator;

  @Override
  public int countUserExchangeOrderByWrapper(QueryWrapper<UserExchangeOrder> queryWrapper) {
    return getBaseMapper().countUserExchangeOrderByWrapper(queryWrapper);
  }

  @Override
  public List<UserExchangeOrderVO> listUserExchangeOrderByWrapper(QueryWrapper<UserExchangeOrder> queryWrapper) {
    return getBaseMapper().listUserExchangeOrderByWrapper(queryWrapper);
  }

  @Override
  public List<TicketHitPrizeBarrageVO> listByWrapper(QueryWrapper<TicketHitPrizeBarrageVO> queryWrapper) {
    return getBaseMapper().listByWrapper(queryWrapper);
  }

  @Override
  @Transactional(rollbackFor = Exception.class)
  public boolean exchange(Long userId, Long goodsId, Long skuId, int orderNum) {
    int orderAmt = 0;
    Goods goods = goodsService.getById(goodsId);
    GoodsSku goodsSku = new GoodsSku();
    // 商品库存校验
    // 计算兑换盲豆数
    if (null != skuId && 0 != skuId) {
      goodsSku = goodsSkuService.getById(skuId);
      if (goodsSku.getQuantity() < orderNum) {
        throw new ServiceException(ErrorCodeEnum.ERROR_CODE_1020);
      }
      orderAmt = goodsSku.getExchangePrice() * orderNum;
    } else {
      if (goods.getQuantity() < orderNum) {
        throw new ServiceException(ErrorCodeEnum.ERROR_CODE_1020);
      }
      orderAmt = goods.getExchangePrice() * orderNum;
    }
    // 盲豆余额校验
    UserCoin userCoin = userCoinService.getById(userId);
    if (null == userCoin || null == userCoin.getCoin() || userCoin.getCoin() < orderAmt) {
      return false;
    }

    // 生成兑换订单
    UserExchangeOrder exchangeOrder = new UserExchangeOrder();
    exchangeOrder.setOrderId(bizIdGenerator.newIdWithUidSharding(String.valueOf(userId)));
    exchangeOrder.setUserId(userId);
    exchangeOrder.setGoodsId(goodsId);
    exchangeOrder.setSkuId(skuId);
    exchangeOrder.setNum(orderNum);
    exchangeOrder.setOrderCoin(orderAmt);
    save(exchangeOrder);

    // 扣除盲豆数
    userCoinService.consume(userId, orderAmt, exchangeOrder.getOrderId());

    // 放入奖品库
    UserPrizeStorage userPrizeStorage = new UserPrizeStorage();
    userPrizeStorage.setStorageId(bizIdGenerator.newIdWithUidSharding(String.valueOf(userId)));
    userPrizeStorage.setUserId(userId);
    userPrizeStorage.setGoodsId(goodsId);
    userPrizeStorage.setSkuId(skuId);
    userPrizeStorage.setProperties(goodsSku.getProperties());
    userPrizeStorage.setTitle(goods.getTitle());
    userPrizeStorage.setPicUrl(goods.getPicUrl());
    userPrizeStorage.setGoodsNum(orderNum);
    userPrizeStorage.setInType(PrizeStorageInTypeEnum.COIN_EXCHANGE);
    userPrizeStorage.setRefId(exchangeOrder.getOrderId());
    userPrizeStorage.setStatus(PrizeStorageStatusEnum.NOT_DISTRIBUTED);
    userPrizeStorageService.save(userPrizeStorage);

    // 修改商品库存
    if (null != skuId && 0 != skuId) {
      boolean updateSku = goodsSkuService.update(new LambdaUpdateWrapper<GoodsSku>()
          .set(GoodsSku::getQuantity, goodsSku.getQuantity() - orderNum)
          .set(GoodsSku::getSoldQty, goodsSku.getSoldQty() + orderNum)
          .eq(GoodsSku::getSkuId, skuId).eq(GoodsSku::getQuantity, goodsSku.getQuantity()).eq(GoodsSku::getSoldQty, goodsSku.getSoldQty()));
      Assert.isTrue(updateSku, "兑换商品更新SKU库存失败。goodsId:" + goodsId + ",skuId:" + skuId);
    }
    boolean updateGoods = goodsService.update(new LambdaUpdateWrapper<Goods>()
            .set(goods.getQuantity() - orderNum == 0, Goods::getStatus, GoodsStatusEnum.PUT_OFF)
        .set(Goods::getQuantity, goods.getQuantity() - orderNum)
        .set(Goods::getExchangedQty, goods.getExchangedQty() + orderNum)
        .eq(Goods::getGoodsId, goodsId).eq(Goods::getQuantity, goods.getQuantity()).eq(Goods::getExchangedQty, goods.getExchangedQty()));
    Assert.isTrue(updateGoods, "兑换商品更新GOODS库存失败。goodsId:" + goodsId );

    return true;
  }
}
