package com.iformall.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
import com.iformall.common.ErrorCode;
import com.iformall.common.IdWorker;
import com.iformall.domain.po.*;
import com.iformall.domain.po.base.BaseEntity;
import com.iformall.domain.po.msg.AppUniformMsg;
import com.iformall.domain.po.msg.MpAppMsg;
import com.iformall.domain.po.msg.WxMsgRecord;
import com.iformall.domain.vo.WxCouponSendVo;
import com.iformall.enums.*;
import com.iformall.exception.MallinkException;
import com.iformall.mapper.*;
import com.iformall.mq.MqBaseProducer;
import com.iformall.service.*;
import com.iformall.utils.DateUtils;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.util.*;

@Service
public class WxCouponSendServiceImpl implements WxCouponSendService {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    WxCouponSendMapper wxCouponSendMapper;
    @Autowired
    WxCouponOrderService wxCouponOrderService;
    @Autowired
    WxCouponService wxCouponService;
    @Autowired
    WxCouponActionLogService wxCouponActionLogService;
    @Autowired
    WxCouponSendConfigMapper wxCouponSendConfigMapper;
    @Autowired
    WxOrderService wxOrderService;
    @Autowired
    WxCouponOrderMapper wxCouponOrderMapper;
    @Autowired
    WxMerchantBUserMapper wxMerchantBUserMapper;
    @Autowired
    PushLimitService pushLimitService;
    @Autowired
    private MqBaseProducer mqBaseProducer;
    @Autowired
    WxCUserMapper wxCUserMapper;
    @Autowired
    WxCUserBasicInfoMapper wxCUserBasicInfoMapper;
    @Autowired
    WxAppinfoService wxAppinfoService;
    @Autowired
    WxAuthorizerInfoMapper authorizerInfoMapper;
    @Autowired
    WxMsgLimitService wxMsgLimitService;
    @Autowired
    WxCouponMerchantMapper wxCouponMerchantMapper;

    @Override
    public PageInfo<WxCouponSendVo> listAsPage(WxCouponSend record, Integer pageIndex, Integer pageSize) {
        PageInfo<WxCouponSendVo> pageInfo;
	    /**
	     * 设置商户购买券数
	     * 前端排序：时间、商户总库存、商户已发数、商户剩余
	     */
        if (Objects.equals(EnumCouponSendSendType.MERCHANT.getCode(), record.getSendType())) {
            String sortStr = null;
	        if (Objects.equals(record.getSortColumn(), WxCouponSend.SORT_MERCHANT_LNVENTORY) ||
			        Objects.equals(record.getSortColumn(), WxCouponSend.SORT_MERCHANT_SEND) ||
                    Objects.equals(record.getSortColumn(), WxCouponSend.SORT_REMAIN)) {
                sortStr = record.getSortColumn() + " " + record.getSortOrder();
            } else if (Objects.equals(record.getSortColumn(), "createDate")) {
                sortStr = "create_date" + " " + record.getSortOrder();
            }
		        record.setSortColumn(null);
	        record.setSortCol(sortStr);
            pageInfo = PageHelper.startPage(pageIndex, pageSize).doSelectPageInfo(() -> wxCouponSendMapper.findListVoByValidType(record));
            for (WxCouponSendVo cs : pageInfo.getList()) {
                JSONObject jo = JSONObject.parseObject(cs.getConditions());
                int inventory = jo.getIntValue(WxCouponSend.KEY_MERCHANT_LNVENTORY);
                cs.setInventory(inventory);
                int expired = 0;
                if (!DateUtils.isDateBefore(cs.getValidEndDate())) {
                    expired = 1;
                }
                cs.setExpired(expired);
            }
        } else {
            record.setStatus(EnumCouponSendStatus.VALID.getCode());
            record.setSortColumns(BaseEntity.SortField.CreateDate_DESC);
            pageInfo = PageHelper.startPage(pageIndex, pageSize).doSelectPageInfo(() -> wxCouponSendMapper.findListVo(record));
            for (WxCouponSendVo cs:pageInfo.getList())
                cs.setSendCount(wxCouponActionLogService.getCountByChannelId(record.getTenantId(), cs.getSendType(), cs.getId()));
        }
        return pageInfo;
    }

    @Override
    public WxCouponSend getById(Long id) {
        return wxCouponSendMapper.selectById(id);
    }

    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
    @Override
    public void saveOrUpdate(WxCouponSend record) {
        //会员生日券配置
        if (Objects.equals(record.getSendType(), EnumCouponSendSendType.BIRTHDAY.getCode())) {
            WxCouponSend config = getConfig(record.getSendType(), record.getTenantId());
            if (Objects.nonNull(config)) {
                record.setConditions(config.getConditions());
            }
        }
        if (Objects.equals(record.getSendType(), EnumCouponSendSendType.MERCHANT.getCode())) {
            addForMerchant(record);
        }
        if (record.getId() == null) {
            //record.setId(UUID.randomUUID().toString().replaceAll("-", ""));
            final IdWorker idWorker = IdWorker.get();
            record.setId(idWorker.nextId());
            wxCouponSendMapper.insert(record);
        } else {
            wxCouponSendMapper.updateById(record);
        }
    }

    private void addForMerchant(WxCouponSend record) {
        //商户注券 参数校验
        int merchantLnventory = 0;
        String merchantIdStr = null;
        JSONObject jo;
        try {
            jo = JSONObject.parseObject(record.getConditions());
            merchantLnventory = jo.getIntValue(WxCouponSend.KEY_MERCHANT_LNVENTORY);
            merchantIdStr = jo.getString("id");
            jo.put(WxCouponSend.KEY_MERCHANT_SEND,0) ;
            jo.put(WxCouponSend.KEY_MERCHANT_REMAIN,merchantLnventory) ;
            record.setConditions(jo.toJSONString());
        } catch (Exception e) {
            logger.error(" updateInvalid 解析异常：{}", e.getMessage());
        }
        if (Objects.isNull(merchantIdStr)) {
            throw new MallinkException(ErrorCode.MERCHANT_INFO_NOT_FOUND);
        }
        if (0 >= merchantLnventory) {
            throw new MallinkException(ErrorCode.COUPON_SEND_LIMIT_VERIFY);
        }
        //查询总库存
        WxCoupon queryById = new WxCoupon();
        queryById.setId(record.getCouponId());
        WxCoupon wxCouponOfDb = wxCouponService.findById(queryById);
        if (Objects.isNull(wxCouponOfDb)) {
            throw new MallinkException(ErrorCode.COUPON_IS_EMPTY);
        }
        //产品需求，暂时不约束发券商户和券所属商户
        //WxCouponMerchant couponMerchantQ = new WxCouponMerchant();
        //couponMerchantQ.setTenantId(record.getTenantId());
        //couponMerchantQ.setProductId(record.getCouponId());
        //couponMerchantQ.setMerchantId(Long.parseLong(merchantIdStr));
        //couponMerchantQ.setStatus(EnumCouponMerchantStatus.COUPON_MERCHANT_STATUS_VALID.getCode());
        //WxCouponMerchant couponMerchant = wxCouponMerchantMapper.selectOne(new QueryWrapper(couponMerchantQ);
        //if (Objects.isNull(couponMerchant)) {
        //    throw new MallinkException(ErrorCode.COUPON_MERCHANT_NOT_FOUND);
        //}

        //商家购券数不能大于总库存
        if (merchantLnventory > wxCouponOfDb.getRemainInventory()) {
            throw new MallinkException(ErrorCode.REMAIN_IS_EMPTY);
        }

        //更新库存
        wxCouponService.reduceRemainInventory(wxCouponOfDb.getId(), merchantLnventory, wxCouponOfDb.getRemainInventory());
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
    public void updateInvalid(WxCouponSend record) {
        if (Objects.equals(record.getStatus(), EnumCouponSendStatus.INVALID.getCode())) {
            return;
        }
        record.setStatus(EnumCouponSendStatus.INVALID.getCode());
        record.setUpdateDate(new Date());
        if (Objects.equals(record.getSendType(), EnumCouponSendSendType.MERCHANT.getCode())) {
            //查询总库存
            WxCoupon queryById = new WxCoupon();
            queryById.setId(record.getCouponId());
            WxCoupon wxCouponOfDb = wxCouponService.findById(queryById);
            if (Objects.isNull(wxCouponOfDb)) {
                throw new MallinkException(ErrorCode.COUPON_IS_EMPTY);
            }
            //查询商家库存和
            int merchantRemain = 0;
            try {
                JSONObject jo = JSONObject.parseObject(record.getConditions());
                merchantRemain = jo.getIntValue(WxCouponSend.KEY_MERCHANT_REMAIN);
            } catch (Exception e) {
                logger.error(" updateInvalid 解析异常：{}", e.getMessage());
            }
            //退回coupon库存
            if(merchantRemain!=0) {
                wxCouponService.backRemainInventory(queryById.getId(), merchantRemain, wxCouponOfDb.getRemainInventory());
            }
        }
        wxCouponSendMapper.updateById(record);
    }

    @Override
    public void deleteById(Long id) {
        wxCouponSendMapper.deleteById(id);
    }

    private boolean isConditionAllowed(WxCouponSend wxCouponSend, Object param) {

        if (wxCouponSend.getSendType().equals(EnumCouponSendSendType.C_ORDER.getCode())) {
            WxOrder wxOrder = (WxOrder) param;

            try {
                JSONObject jo = JSONObject.parseObject(wxCouponSend.getConditions());
                if (wxOrder.getProductId().equals(jo.getLong("id")))
                    return true;
            } catch (Exception e) {
                logger.error("交易发券条件判断错误:ID=" + wxCouponSend.getId() + e.getMessage());
            }
            return false;

        } else if (wxCouponSend.getSendType().equals(EnumCouponSendSendType.CAR_STOP.getCode())) {

            try {
                JSONObject jo = JSONObject.parseObject(wxCouponSend.getConditions());

                if (DateUtils.isInDate(new Date(), jo.getString("startTime"), jo.getString("endTime"))) {
                    return true;
                }

            } catch (Exception e) {
                logger.error("停车发券条件判断错误:ID=" + wxCouponSend.getId() + e.getMessage());
            }

            return false;
        } else if (wxCouponSend.getSendType().equals(EnumCouponSendSendType.B_MICROPAY.getCode())) {

            WxOrder wxOrder = (WxOrder) param;

            try {
                JSONObject jo = JSONObject.parseObject(wxCouponSend.getConditions());
                WxMerchantBUser wxMerchantBUser = wxMerchantBUserMapper.selectById(wxOrder.getProductId());

                if (wxMerchantBUser.getMerchantId() != null
                        && wxMerchantBUser.getMerchantId().equals(jo.getLong("id"))) {
                    return true;
                }
            } catch (Exception e) {
                logger.error("收银发券条件判断错误:ID=" + wxCouponSend.getId() + e.getMessage());
            }
            return false;

        } else if (wxCouponSend.getSendType().equals(EnumCouponSendSendType.COUPON_VERIFY.getCode())) {
            WxOrder wxOrder = (WxOrder) param;

            try {
                JSONObject jo = JSONObject.parseObject(wxCouponSend.getConditions());
                if (wxOrder.getProductId().equals(jo.getLong("id"))) {
                    return true;
                }
            } catch (Exception e) {
                logger.error("核销发券条件判断错误:ID=" + wxCouponSend.getId() + e.getMessage());
            }
            return false;

        } else {
            return false;
        }

    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, readOnly = false, rollbackFor = {Exception.class})
    public boolean sendCouponToUser(EnumCouponSendSendType type, Object param) {

        String tenantId;
        Long cUserId;
        switch (type) {
            case CAR_STOP:
                if (!param.getClass().equals(WxCUserCar.class))
                    return false;
                WxCUserCar wxCUserCar = (WxCUserCar) param;
                cUserId = wxCUserCar.getCUserId();
                tenantId = wxCUserCar.getTenantId();
                break;
            case COUPON_VERIFY:
            case B_MICROPAY:
            case C_ORDER:
                if (!param.getClass().equals(WxOrder.class))
                    return false;
                WxOrder order = (WxOrder) param;
                cUserId = order.getCUserId();
                tenantId = order.getTenantId();
                break;
            default:
                return false;
        }

        WxCUserBasicInfo wxCUserBasicInfo = wxCUserBasicInfoMapper.selectById(cUserId);
        if (wxCUserBasicInfo != null && wxCUserBasicInfo.getStatus().equals(EnumCUserBasicInfoStatus.LOCKED.getCode())) {
            logger.info("会员权益被锁定:cUserId:" + cUserId);
            return false;
        }

        //查询开关是否打开
        WxCouponSendConfig wxCouponSendConfig = new WxCouponSendConfig();
        wxCouponSendConfig.setSendType(type.getCode());
        wxCouponSendConfig.setTenantId(tenantId);
        List<WxCouponSendConfig> configList = wxCouponSendConfigMapper.findList(wxCouponSendConfig);
        if (configList.size() > 0) {
            WxCouponSendConfig config = configList.get(0);
            if (config.getValue() == EnumEnableType.Disable.getCode()) {
                logger.info(config.getSendType() + ": disabled ");
                return false;
            }
        }

        boolean checkTime = false;
        try {
            checkTime = pushLimitService.checkSendTime(tenantId);
            if (!checkTime)
                return false;
        } catch (MallinkException e) {
            logger.error("push limit check time :" + e.getMessage());
            return false;
        }

        boolean bRet = false;

        WxCouponSend wxCouponSendQuery = new WxCouponSend();
        wxCouponSendQuery.setTenantId(tenantId);
        wxCouponSendQuery.setSendType(type.getCode());
        wxCouponSendQuery.setStatus(EnumCouponSendStatus.VALID.getCode());

        List<WxCouponSendVo> wxCouponSends = wxCouponSendMapper.findListVo(wxCouponSendQuery);
        for (WxCouponSend send : wxCouponSends) {
            boolean checkLimit = false;
            // 检查疲劳度
            try {
                checkLimit = pushLimitService.checkCoupon(tenantId, cUserId, send.getCouponId());
            } catch (MallinkException e) {
                logger.error("券达到limit: " + e.getMessage());
            }
            if (!checkLimit) {
                continue;
            }

            //检查条件
            if (!isConditionAllowed(send, param))
                continue;

            // 发放免费券
            WxCouponOrder couponOrder = null;
            try {
                couponOrder = wxOrderService.sendFreeCouponToUser(cUserId, send.getCouponId(), null);
                if (couponOrder != null) {
                    bRet = true;

                    wxCouponActionLogService.addOne(tenantId, send.getCouponId(), couponOrder.getId(), type.getCode(), send.getId());

                    // 查找cUser
                    WxCUser user = wxCUserMapper.selectById(cUserId);
                    if (user == null) {
                        continue;
                    }

                    // 发送消息
                    if (couponOrder != null) {
                        sendMsgForSendCoupon(tenantId, send, couponOrder, user);
                    }

                    bRet = true;
                }
            } catch (Exception e) {
                logger.error(e.getMessage());
            }


        }

        return bRet;
    }

    private void sendMsgForSendCoupon(String tenantId, WxCouponSend send, WxCouponOrder couponOrder, WxCUser user) {
        // 发送微信模板消息(公众号模板消息/小程序统一消息/小程序模板消息)
        sendMpMsgForSendCoupon(send, couponOrder, user);

        // 发送短信
        if (send.getSendSms().equals(EnumCouponSendSms.YES.getCode())) {
            logger.info("》》》》》》》》》》》");
            logger.info("场景投放发送短信开始");
            logger.info("》》》》》》》》》》》");
            //券名
            String title = send.getTitle();
            //找出用户手机号
            String phone = user.getPhone();

            //小程序名称
            WxAppinfo appInfo = wxAppinfoService.getCAppInfo(tenantId);
            String appName = appInfo.getName();
            Map<String, String> msgReplaceMap = new HashMap();
            msgReplaceMap.put("title", title);
            msgReplaceMap.put("app", appName);

            WxMsgRecord wxMsgRecord = new WxMsgRecord();
            wxMsgRecord.setMsgType(EnumMsgRecordType.SMS.getCode());
            wxMsgRecord.setModelType(EnumMsgModel.COUPON_SEND.getCode());
            wxMsgRecord.setReceiver(phone);
            wxMsgRecord.setTenantId(tenantId);
            wxMsgRecord.setDynamicContentMap(msgReplaceMap);
            mqBaseProducer.sendMessage(wxMsgRecord, EnumMsgMqTopic.DEFAULT.getCode(), EnumMsgMqTag.DEFAULT.getCode(), EnumMsgMqKey.DEFAULT.getCode());
            logger.info("》》》》》》》》》》》");
            logger.info("场景投放发送短信结束");
            logger.info("》》》》》》》》》》》");
        }
    }

    private boolean sendMpMsgForSendCoupon(WxCouponSend send, WxCouponOrder couponOrder, WxCUser user) {
        // 发送 公众号 模板消息
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
        String gotopage = "pages/index/index?type=mc";
        // 7. 公众号消息
        if (StringUtils.isNotBlank(user.getMpAppId()) &&
                StringUtils.isNotBlank(user.getMpOpenId()) &&
                user.getMpSubscribe().equals(EnumUserIsSubscribe.YES.getCode())) {
            // 检查是否超限
            WxMsgLimit msgLimit = new WxMsgLimit();
            msgLimit.setTenantId(user.getTenantId());
            msgLimit.setType(EnumMsgLimitType.WXCHAT_OPENID_SEND.getCode());
            msgLimit.setLimitId(user.getMpOpenId());
            if (wxMsgLimitService.checkIsLimit(msgLimit)) {
                logger.error("用户公众号模板消息超限" + user.getId());
                return true;
            }

            // 已关注公众号
            /**
             * 购票成功通知
             * {first.DATA}}
             * 订单号：{{keyword1.DATA}}
             * 兑换券：{{keyword2.DATA}}
             * 订单详情：{{keyword3.DATA}}
             * 有效期至：{{keyword4.DATA}}
             * 购买数量：{{keyword5.DATA}}
             * {{remark.DATA}}
             */
            MpAppMsg mpAppMsg = new MpAppMsg();
            mpAppMsg.setMsgType(EnumMsgRecordType.PUBLIC.getCode());
            mpAppMsg.setAppId(user.getMpAppId());
            mpAppMsg.setTo(user.getMpOpenId());
            mpAppMsg.setMiniAppId(user.getAppId());
            mpAppMsg.setMiniPagePath(gotopage);
            mpAppMsg.setTenantId(couponOrder.getTenantId());
            mpAppMsg.setTemplateType(EnumTemplateType.GIFT_MESSAGE.getCode());
            mpAppMsg.setDataList(Lists.newArrayList(
                    user.getNickName(),
                    String.valueOf(couponOrder.getOrderId()),
                    couponOrder.getId().toString(),
                    send.getTitle(),
                    dateFormat.format(couponOrder.getExpiredTime()),
                    "1",
                    user.getNickName()

            ));

            try {
                mqBaseProducer.sendMessage(mpAppMsg, EnumMsgMqTopic.DEFAULT.getCode(), EnumMsgMqTag.DEFAULT.getCode(), EnumMsgMqKey.DEFAULT.getCode());
            } catch (Exception e) {
                logger.error("购票成功-公众号-模板消息发送失败: " + e.getMessage());
                //throw new MallinkException(ErrorCode.MP_TEMPLATE_SEND_FAILED);
            }
        } else {
            // 可能未关注公众号, 用户可能收不到
            // 8. 微信小程序-统一消息
            // 检查是否超限
            WxMsgLimit msgLimit = new WxMsgLimit();
            msgLimit.setTenantId(user.getTenantId());
            msgLimit.setType(EnumMsgLimitType.WEAPP_OPENID_SEND.getCode());
            msgLimit.setLimitId(user.getOpenId());
            if (wxMsgLimitService.checkIsLimit(msgLimit)) {
                logger.error("用户小程序统一模板消息超限：" + user.getId());
                return true;
            }
            //  获取小程序关联的服务号
            WxAuthorizerInfo authQ = new WxAuthorizerInfo();
            authQ.setAuthorizerAppid(user.getAppId());
            authQ.setTenantId(user.getTenantId());
            WxAuthorizerInfo weappInfo = authorizerInfoMapper.findMp(authQ);
            if (weappInfo != null) {
                AppUniformMsg appUniformMsg = new AppUniformMsg();
                appUniformMsg.setMsgType(EnumMsgRecordType.SMART_APP_UNIFORM.getCode());
                appUniformMsg.setAppId(user.getAppId());
                appUniformMsg.setTo(user.getOpenId());
                appUniformMsg.setTemplateType(EnumTemplateType.GIFT_MESSAGE.getCode());
                appUniformMsg.setPagePath(gotopage);
                appUniformMsg.setMpAppId(weappInfo.getAuthorizerAppid());
                appUniformMsg.setDataList(Lists.newArrayList(
                        user.getNickName(),
                        String.valueOf(couponOrder.getOrderId()),
                        couponOrder.getId().toString(),
                        send.getTitle(),
                        dateFormat.format(couponOrder.getExpiredTime()),
                        "1",
                        user.getNickName()
                ));
                try {
                    mqBaseProducer.sendMessage(appUniformMsg, EnumMsgMqTopic.DEFAULT.getCode(), EnumMsgMqTag.DEFAULT.getCode(), EnumMsgMqKey.DEFAULT.getCode());
                } catch (Exception e) {
                    logger.error("核销-公众号-模板消息发送失败: " + e.getMessage());
                    //throw new MallinkException(ErrorCode.UNIFORM_SEND_FAILED);
                }
            }
        }
        return false;
    }

    @Override
    public void updateStatusByCouponId(Long couponId, String tenantId, int status) {
        WxCouponSend wxCouponSend = new WxCouponSend();
        wxCouponSend.setTenantId(tenantId);
        wxCouponSend.setCouponId(couponId);
        wxCouponSend.setStatus(status);
        wxCouponSend.setUpdateDate(new Date());
        wxCouponSendMapper.updateStatusByCouponId(wxCouponSend);
    }

    @Override
    public void saveOrUpdateConfig(Integer beforeDays, Integer sendType, String tenantId) {
        WxCouponSend config = getConfig(sendType, tenantId);
        if (Objects.isNull(config)) {
            WxCouponSend couponSendQuery = createCouponSendQuery(sendType, tenantId) ;
            insertCouponSend(beforeDays, couponSendQuery);
        } else {
            JSONObject couponSendJo = JSONObject.parseObject(config.getConditions());
            if (Objects.isNull(couponSendJo)) {
                couponSendJo = new JSONObject();
            }
            couponSendJo.put(WxCouponSend.KEY_BEFOREDAYS, beforeDays);
            config.setConditions(couponSendJo.toJSONString());
            config.setUpdateDate(new Date());
            wxCouponSendMapper.updateBirthdayConfig(config);
        }
    }

    private void insertCouponSend(Integer beforeDays, WxCouponSend couponSendQuery) {
        couponSendQuery.setTitle(EnumCouponSendSendType.BIRTHDAY.getMessage() + "配置信息 ");
        final IdWorker idWorker = IdWorker.get();
        couponSendQuery.setId(idWorker.nextId());
        couponSendQuery.setCreateDate(new Date());
        JSONObject couponSendJo = new JSONObject();
        couponSendJo.put(WxCouponSend.KEY_BEFOREDAYS, beforeDays);
        couponSendQuery.setConditions(couponSendJo.toJSONString());
        wxCouponSendMapper.insert(couponSendQuery);
    }

    @Override
    public WxCouponSend getConfig(Integer sendType, String tenantId) {
        WxCouponSend couponSendQuery = createCouponSendQuery(sendType, tenantId) ;
        //读取会员生日券配置信息
        List<WxCouponSend> wxCouponSendList = wxCouponSendMapper.selectList(new QueryWrapper(couponSendQuery));
        if (CollectionUtils.isEmpty(wxCouponSendList)) {
            //配置不存在，添加默认配置
            insertCouponSend(0, couponSendQuery);
            return couponSendQuery;
        }
        return wxCouponSendList.get(0);
    }

    private WxCouponSend createCouponSendQuery(Integer sendType, String tenantId) {
        WxCouponSend couponSendQuery = new WxCouponSend();
        couponSendQuery.setSendType(sendType);
        couponSendQuery.setTenantId(tenantId);
        couponSendQuery.setCouponId(0L);
        couponSendQuery.setStatus(EnumCouponSendStatus.INVALID.getCode());
        return couponSendQuery ;
    }

    @Override
    public void reduceMerchantSend(Long id, Integer merchantRemain, Integer merchantSend ,Integer number) {
        int num = wxCouponSendMapper.reduceMerchantSend(id, merchantRemain, merchantSend,number);
        if (num == 0) {
            throw new MallinkException(ErrorCode.ORDER_IS_FAIL);
        }
    }

    @Override
    public void backMerchantRemainInventory(Long id, Integer merchantRemain, Integer merchantSend, Integer number) {
        int num = wxCouponSendMapper.backMerchantSend(id, merchantRemain, merchantSend,number);
        if (num == 0) {
            throw new MallinkException(ErrorCode.ORDER_IS_FAIL);
        }
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, readOnly = false, rollbackFor = {Exception.class})
    public void handSel(WxCouponSend wxCouponSend, Long cUserId) {
        WxCUser cu = wxCUserMapper.selectById(cUserId);
        if (Objects.isNull(cu)) {
            throw new MallinkException(ErrorCode.USER_NOT_AUTH_PHONE);
        }

        if(StringUtils.isEmpty(cu.getPhone())) {
            throw new MallinkException(ErrorCode.USER_NOT_AUTH_PHONE);
        }

        WxCUserBasicInfo wxCUserBasicInfo = wxCUserBasicInfoMapper.selectById(cu.getId());
        if (Objects.isNull(wxCUserBasicInfo)) {
            throw new MallinkException(ErrorCode.USER_NOT_AUTH_PHONE);
        }

        List<WxCouponSendVo> couponSendList = wxCouponSendMapper.findListVo(wxCouponSend);
        if (CollectionUtils.isEmpty(couponSendList)) {
            throw new MallinkException(ErrorCode.COUPON_IS_EMPTY);
        }
        couponSendList.forEach(cs -> {
            // 发放免费券
            WxCouponOrder couponOrder = wxOrderService.sendFreeCouponToUser(cu.getId(), cs.getCouponId(), cs);
            if (couponOrder != null) {
                wxCouponActionLogService.addOne(cu.getTenantId(), cs.getCouponId(), couponOrder.getId(), cs.getSendType(), cs.getId());
                sendMsgForSendCoupon(cs.getTenantId(), cs, couponOrder, cu);
            } else {
                logger.warn("handSel couponOrder is null");
            }
        });
    }
}
