package com.pcloud.book.giftcoupon.biz.impl;

import com.pcloud.book.base.exception.BookBizException;
import com.pcloud.book.book.constant.BookConstant;
import com.pcloud.book.giftcoupon.biz.GiftCouponPackageBiz;
import com.pcloud.book.giftcoupon.check.GiftParamCheck;
import com.pcloud.book.giftcoupon.dao.GiftCouponPackageDao;
import com.pcloud.book.giftcoupon.dao.GiftReceiveDao;
import com.pcloud.book.giftcoupon.dto.BatchReceiveDTO;
import com.pcloud.book.giftcoupon.dto.GiftPackageDTO;
import com.pcloud.book.giftcoupon.dto.GiftReceiveDTO;
import com.pcloud.book.giftcoupon.dto.MyGiftPackageDTO;
import com.pcloud.book.giftcoupon.entity.GiftCouponPackage;
import com.pcloud.book.giftcoupon.entity.GiftReceive;
import com.pcloud.common.core.aspect.ParamLog;
import com.pcloud.common.page.PageBeanNew;
import com.pcloud.common.page.PageParam;
import com.pcloud.common.utils.ListUtils;
import com.pcloud.common.utils.string.StringUtil;
import org.apache.commons.collections.MapUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Component("giftCouponPackageBiz")
public class GiftCouponPackageBizImpl implements GiftCouponPackageBiz {

    @Autowired
    private GiftCouponPackageDao giftCouponPackageDao;
    @Autowired
    private GiftReceiveDao giftReceiveDao;
    @Autowired
    private GiftParamCheck giftParamCheck;

    @Transactional(rollbackFor = Exception.class)
    @ParamLog(value = "新增专享礼包", isAfterReturn = false)
    @Override
    public void createGiftPackage(GiftCouponPackage giftCouponPackage) {
        giftParamCheck.checkGiftAddParam(giftCouponPackage);
        if(StringUtil.isBlank(giftCouponPackage.getCoverPic())){
            giftCouponPackage.setCoverPic(BookConstant.DEFAULT_COVER_PIC);
        }
        giftCouponPackageDao.insert(giftCouponPackage);
    }

    @Transactional(rollbackFor = Exception.class)
    @ParamLog(value = "修改专享礼包", isAfterReturn = false)
    @Override
    public void updateGiftPackage(GiftCouponPackage giftCouponPackage) {
        giftParamCheck.checkGiftAddParam(giftCouponPackage);
        if(StringUtil.isBlank(giftCouponPackage.getCoverPic())){
            giftCouponPackage.setCoverPic(BookConstant.DEFAULT_COVER_PIC);
        }
        giftCouponPackageDao.update(giftCouponPackage);
    }

    @Override
    public GiftCouponPackage getGiftPackage(Long id) {
        return giftCouponPackageDao.getById(id);
    }

    @Override
    public void deleteGiftPackage(Long id) {
        //todo 删除应该有限制
        giftCouponPackageDao.deleteById(id);
    }

    @Override
    public PageBeanNew<GiftPackageDTO> list4GiftPackage(String title, Integer state, Integer couponType,Integer currentPage, Integer numPerPage) {
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("title", title);
        paramMap.put("state", state);
        paramMap.put("couponType", couponType);
        PageBeanNew<GiftPackageDTO> pageBeanNew=giftCouponPackageDao.listPageNew(new PageParam(currentPage, numPerPage), paramMap, "list4GiftPackage");
        if (pageBeanNew == null || ListUtils.isEmpty(pageBeanNew.getRecordList())) {
            return new PageBeanNew<>(currentPage, numPerPage, new ArrayList<>());
        }
        buildReceiveNum(pageBeanNew.getRecordList());
        return pageBeanNew;
    }

    private void buildReceiveNum(List<GiftPackageDTO> recordList) {
        List<Long> giftIds = recordList.stream().filter(a -> null != a.getId()).map(a -> a.getId()).distinct().collect(Collectors.toList());
        List<GiftReceiveDTO> giftReceiveNumList = ListUtils.isEmpty(giftIds)?new ArrayList<>():giftReceiveDao.getGiftReceiveNumList(giftIds);
        Map<Long, Integer> receiveNumMap = new HashMap<>();
        if(!ListUtils.isEmpty(giftReceiveNumList)){
           receiveNumMap= giftReceiveNumList.stream().collect(Collectors.toMap(a -> a.getGiftPackageId(), a -> a.getReceiveNum(), (k1, k2) -> k2));
        }
        for (GiftPackageDTO giftPackageDTO : recordList) {
            giftPackageDTO.setReceiveNum(0);
            if(MapUtils.isNotEmpty(receiveNumMap) && receiveNumMap.containsKey(giftPackageDTO.getId())){
                giftPackageDTO.setReceiveNum(receiveNumMap.get(giftPackageDTO.getId()));
            }
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @ParamLog(value = "新增专享礼包", isAfterReturn = false)
    @Override
    public void createGiftReceive(GiftReceive giftReceive) {
        giftParamCheck.checkGiftReceiveAddParam(giftReceive);
        GiftCouponPackage giftCouponPackage = giftCouponPackageDao.getById(giftReceive.getGiftPackageId());
        if(null==giftCouponPackage){
            throw new BookBizException(BookBizException.PARAM_IS_NULL, "当前奖券包不存在");
        }
        Integer giftReceiveCount = giftReceiveDao.getGiftReceiveCount(giftReceive.getWechatUserId(), giftReceive.getGiftPackageId());
        //库存减一
        if(giftCouponPackage.getStock()<1){
            throw new BookBizException(BookBizException.PARAM_IS_NULL, "库存不够");
        }
        giftCouponPackageDao.reduceStock(giftReceive.getGiftPackageId());
        if(giftReceiveCount>=giftCouponPackage.getReceiveLimit()){
            throw new BookBizException(BookBizException.PARAM_IS_NULL, "该类型的兑换券您已经领取过，请前往“我的券库”使用吧");
        }else{
            giftReceiveDao.insert(giftReceive);
        }
    }

    @Override
    public PageBeanNew<MyGiftPackageDTO> list4MyGiftPackage(Integer state,Long wechatUserId,Integer currentPage, Integer numPerPage) {
        //state=1 已领取  state=2 已失效
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("wechatUserId", wechatUserId);
        paramMap.put("state", state);
        PageBeanNew<MyGiftPackageDTO> pageBeanNew=giftReceiveDao.listPageNew(new PageParam(currentPage, numPerPage), paramMap, "list4MyGiftPackage");
        if (pageBeanNew == null || ListUtils.isEmpty(pageBeanNew.getRecordList())) {
            return new PageBeanNew<>(currentPage, numPerPage, new ArrayList<>());
        }
        return pageBeanNew;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void useGiftCoupon(Long wechatUserId, Long receiveId) {
        GiftReceive giftReceive = giftReceiveDao.getById(receiveId);
        if(null==giftReceive){
            throw new BookBizException(BookBizException.PARAM_IS_NULL, "你还未领取该奖券包");
        }
        GiftCouponPackage giftCouponPackage = giftCouponPackageDao.getById(giftReceive.getGiftPackageId());
        if(null==giftCouponPackage){
            throw new BookBizException(BookBizException.PARAM_IS_NULL, "当前奖券包不存在");
        }
        //todo 可能有其他操作,如果点击不跳转页面，需要控制重复点击
        giftReceiveDao.useGiftCoupon(receiveId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @ParamLog(value = "礼券包一键领取", isAfterReturn = false)
    public void createGiftReceiveBatch(BatchReceiveDTO batchReceiveDTO, Long wechatUserId) {
        if (null==batchReceiveDTO || null==batchReceiveDTO.getRightsSettingId() || ListUtils.isEmpty(batchReceiveDTO.getGiftPackageIds())) {
            return;
        }
        Long rightsSettingId = batchReceiveDTO.getRightsSettingId();
        List<Long> giftPackageIds = batchReceiveDTO.getGiftPackageIds();
        List<Long> packageIdsBy = giftCouponPackageDao.getPackageIdsBy(giftPackageIds);
        if (ListUtils.isEmpty(packageIdsBy) || packageIdsBy.size() != giftPackageIds.size()) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL, "有奖券包不存在，不能一键领取");
        }
        Integer noStockCount = giftCouponPackageDao.getNoStockCount(giftPackageIds);
        if (noStockCount > 0) {
            throw new BookBizException(BookBizException.PARAM_IS_NULL, "有奖券包无库存，不能一键领取");
        }
        //判断是否有超过上限的
        List<GiftCouponPackage> overLimitCoupon = giftReceiveDao.getOverLimitCoupon(giftPackageIds, wechatUserId);
        if(!ListUtils.isEmpty(overLimitCoupon)){
            String titles = overLimitCoupon.stream().map(a -> a.getTitle()).collect(Collectors.joining(","));
            throw new BookBizException(BookBizException.PARAM_IS_NULL, titles+"兑换券您已经领取过，请前往”我的券库”使用吧");
        }
        //批量减库存
        giftCouponPackageDao.reduceStockBatch(giftPackageIds);
        //批量插入
        List<GiftReceive> list = new ArrayList<>();
        GiftReceive receive = null;
        for (Long giftPackageId : giftPackageIds) {
            receive = new GiftReceive();
            receive.setRightsSettingId(rightsSettingId);
            receive.setGiftPackageId(giftPackageId);
            receive.setWechatUserId(wechatUserId);
            list.add(receive);
        }
        giftReceiveDao.insert(list);
    }

}
