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

import com.pcloud.book.applet.dao.AppletLinkClickDao;
import com.pcloud.book.applet.dto.PvuvDTO;
import com.pcloud.book.applet.enums.DataRecordTypeEnum;
import com.pcloud.book.applet.enums.DataTypeEnum;
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.book.giftcoupon.enums.CouponTypeEnum;
import com.pcloud.book.giftcoupon.enums.CouponUseTypeEnum;
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;
    @Autowired
    private AppletLinkClickDao appletLinkClickDao;

    @Transactional(rollbackFor = Exception.class)
    @ParamLog(value = "新增专享礼包", isAfterReturn = false)
    @Override
    public void createGiftPackage(GiftCouponPackage giftCouponPackage) {
        giftParamCheck.checkGiftAddParam(giftCouponPackage);
        if (null == giftCouponPackage.getAgentId()){
            giftCouponPackage.setAgentId(0L);
        }
        if (urlNumberExist(giftCouponPackage)){
            throw new BookBizException(BookBizException.ERROR,"链接编号重复");
        }
        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 (null == giftCouponPackage.getId()){
            throw new BookBizException(BookBizException.ERROR,"id为空");
        }
        GiftCouponPackage couponPackage = giftCouponPackageDao.getById(giftCouponPackage.getId());
        giftCouponPackage.setAgentId(couponPackage.getAgentId());
        if (urlNumberExist(giftCouponPackage)){
            throw new BookBizException(BookBizException.ERROR,"链接编号重复");
        }
        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, Long agentId) {
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("title", title);
        paramMap.put("state", state);
        paramMap.put("couponType", couponType);
        paramMap.put("agentId", agentId);
        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);
    }

    @Override
    public String getUrlNumberByUrl(String url, Long agentId) {
        if (StringUtil.isEmpty(url)){
            return "";
        }
        return giftCouponPackageDao.getUrlNumberByAddress(url, agentId);
    }

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

    /**
     * 填充使用分析
     * @author：zhuyajie
     * @date：2020/5/11 19:43
     *  * @param null
     */
    private void fillUseAnalysis(List<GiftPackageDTO> recordList,Integer clickQty) {
        if (ListUtils.isEmpty(recordList)){
            return;
        }
        if (null != clickQty && clickQty.intValue() >1){
            clickQty += 1;
        }
        List<Long> ids = recordList.stream().filter(s -> s != null).map(GiftPackageDTO::getId).distinct().collect(Collectors.toList());
        Map<Long, PvuvDTO> clickMap = appletLinkClickDao.mapPVUV(DataTypeEnum.gift_coupon.code, DataRecordTypeEnum.click.code, ids,clickQty);
        Map<Long, PvuvDTO> useMap = appletLinkClickDao.mapCouponUseCount(ids);
        for (GiftPackageDTO giftPackageDTO : recordList) {
            Long id = giftPackageDTO.getId();
            if (!MapUtils.isEmpty(clickMap) && clickMap.containsKey(id)) {
                PvuvDTO pvuvDTO = clickMap.get(id);
                giftPackageDTO.setClickPVUV(pvuvDTO.getPv() + "/" + pvuvDTO.getUv());
            } else {
                giftPackageDTO.setClickPVUV("0/0");
            }
            if (!MapUtils.isEmpty(useMap) && useMap.containsKey(id)) {
                PvuvDTO pvuvDTO = useMap.get(id);
                giftPackageDTO.setUseNum(pvuvDTO.getCount());
            } else {
                giftPackageDTO.setUseNum(0);
            }
        }
    }

    /**
     * 链接编号是否重复
     * @author：zhuyajie
     * @date：2020/5/11 18:50
     *  * @param null
     */
    public Boolean urlNumberExist(GiftCouponPackage giftCouponPackage) {
        Boolean exist = false;
        if (!CouponTypeEnum.COURSE_COUPON.value.equals(giftCouponPackage.getCouponType()) && !CouponUseTypeEnum.LINK.value.equals(giftCouponPackage.getUseType())) {//非外部链接
            return exist;
        }
        if (!StringUtil.isEmpty(giftCouponPackage.getExchangeAddress()) && !StringUtil.isEmpty(giftCouponPackage.getUrlNumber())) {
            exist = giftCouponPackageDao.urlNumberExist(giftCouponPackage.getExchangeAddress(), giftCouponPackage.getUrlNumber(), giftCouponPackage.getId(), giftCouponPackage.getAgentId());
        }
        return exist;
    }

}
