package com.slodon.b2b2c.model.promotion;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateUtil;
import com.slodon.b2b2c.core.config.DomainUrlUtil;
import com.slodon.b2b2c.core.constant.MemberTplConst;
import com.slodon.b2b2c.core.constant.OrderConst;
import com.slodon.b2b2c.core.constant.PreSellConst;
import com.slodon.b2b2c.core.constant.StoreTplConst;
import com.slodon.b2b2c.core.exception.MallException;
import com.slodon.b2b2c.core.response.PagerInfo;
import com.slodon.b2b2c.core.util.AssertUtil;
import com.slodon.b2b2c.core.util.StringUtil;
import com.slodon.b2b2c.dao.read.promotion.PresellGoodsReadMapper;
import com.slodon.b2b2c.dao.read.promotion.PresellOrderExtendReadMapper;
import com.slodon.b2b2c.dao.read.promotion.PresellReadMapper;
import com.slodon.b2b2c.dao.write.promotion.PresellOrderExtendWriteMapper;
import com.slodon.b2b2c.promotion.example.PresellGoodsExample;
import com.slodon.b2b2c.promotion.example.PresellOrderExtendExample;
import com.slodon.b2b2c.promotion.pojo.Presell;
import com.slodon.b2b2c.promotion.pojo.PresellGoods;
import com.slodon.b2b2c.promotion.pojo.PresellOrderExtend;
import com.slodon.b2b2c.starter.mq.entity.MessageSendProperty;
import com.slodon.b2b2c.starter.mq.entity.MessageSendVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

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

import static com.slodon.b2b2c.core.constant.StarterConfigConst.*;

/**
 * 预售订单扩展信息表model
 */
@Component
@Slf4j
public class PresellOrderExtendModel {

    @Resource
    private PresellOrderExtendReadMapper presellOrderExtendReadMapper;
    @Resource
    private PresellOrderExtendWriteMapper presellOrderExtendWriteMapper;
    @Resource
    private PresellReadMapper presellReadMapper;
    @Resource
    private PresellGoodsReadMapper presellGoodsReadMapper;
    @Resource
    private StringRedisTemplate stringRedisTemplate;
    @Resource
    private RabbitTemplate rabbitTemplate;

    /**
     * 新增预售订单扩展信息表
     *
     * @param presellOrderExtend
     * @return
     */
    public Integer savePresellOrderExtend(PresellOrderExtend presellOrderExtend) {
        int count = presellOrderExtendWriteMapper.insert(presellOrderExtend);
        if (count == 0) {
            throw new MallException("添加预售订单扩展信息表失败，请重试");
        }
        return count;
    }

    /**
     * 根据extendId删除预售订单扩展信息表
     *
     * @param extendId extendId
     * @return
     */
    public Integer deletePresellOrderExtend(Integer extendId) {
        if (StringUtils.isEmpty(extendId)) {
            throw new MallException("请选择要删除的数据");
        }
        int count = presellOrderExtendWriteMapper.deleteByPrimaryKey(extendId);
        if (count == 0) {
            log.error("根据extendId：" + extendId + "删除预售订单扩展信息表失败");
            throw new MallException("删除预售订单扩展信息表失败,请重试");
        }
        return count;
    }

    /**
     * 根据extendId更新预售订单扩展信息表
     *
     * @param presellOrderExtend
     * @return
     */
    public Integer updatePresellOrderExtend(PresellOrderExtend presellOrderExtend) {
        if (StringUtils.isEmpty(presellOrderExtend.getExtendId())) {
            throw new MallException("请选择要修改的数据");
        }
        int count = presellOrderExtendWriteMapper.updateByPrimaryKeySelective(presellOrderExtend);
        if (count == 0) {
            log.error("根据extendId：" + presellOrderExtend.getExtendId() + "更新预售订单扩展信息表失败");
            throw new MallException("更新预售订单扩展信息表失败,请重试");
        }
        return count;
    }

    /**
     * 根据extendId更新预售订单扩展信息表
     *
     * @param presellOrderExtend
     * @return
     */
    public Integer updatePresellOrderExtendByOrderSn(PresellOrderExtend presellOrderExtend, String orderSnIn) {
        if (StringUtils.isEmpty(orderSnIn)) {
            throw new MallException("请选择要修改的数据");
        }
        PresellOrderExtendExample example = new PresellOrderExtendExample();
        example.setOrderSnIn("'" + orderSnIn.replace(",", "','") + "'");
        int count = presellOrderExtendWriteMapper.updateByExampleSelective(presellOrderExtend, example);
        if (count == 0) {
            throw new MallException("更新预售订单扩展信息表失败,请重试");
        }
        return count;
    }

    /**
     * 根据extendId获取预售订单扩展信息表详情
     *
     * @param extendId extendId
     * @return
     */
    public PresellOrderExtend getPresellOrderExtendByExtendId(Integer extendId) {
        return presellOrderExtendReadMapper.getByPrimaryKey(extendId);
    }

    /**
     * 根据条件获取预售订单扩展信息表列表
     *
     * @param example 查询条件信息
     * @param pager   分页信息
     * @return
     */
    public List<PresellOrderExtend> getPresellOrderExtendList(PresellOrderExtendExample example, PagerInfo pager) {
        List<PresellOrderExtend> presellOrderExtendList;
        if (pager != null) {
            pager.setRowsCount(presellOrderExtendReadMapper.countByExample(example));
            presellOrderExtendList = presellOrderExtendReadMapper.listPageByExample(example, pager.getStart(), pager.getPageSize());
        } else {
            presellOrderExtendList = presellOrderExtendReadMapper.listByExample(example);
        }
        return presellOrderExtendList;
    }

    /**
     * 保存订单预售信息
     *
     * @param orderSn
     * @param paySn
     * @param promotionId
     * @param productId
     * @return
     */
    public Integer insertOrderPreSale(String orderSn, String paySn, Integer promotionId, Long productId, Integer productNum, Integer memberId) {
        //查询预售活动信息
        Presell presell = presellReadMapper.getByPrimaryKey(promotionId);
        AssertUtil.notNull(presell, "获取预售活动信息为空");
        //查询预售商品信息
        PresellGoodsExample example = new PresellGoodsExample();
        example.setPresellId(promotionId);
        example.setProductId(productId);
        List<PresellGoods> presellGoodsList = presellGoodsReadMapper.listByExample(example);
        AssertUtil.notEmpty(presellGoodsList, "获取预售商品信息信息为空");
        PresellGoods presellGoods = presellGoodsList.get(0);
        //构造预售订单扩展信息
        PresellOrderExtend presellOrderExtend = new PresellOrderExtend();
        presellOrderExtend.setPresellId(promotionId);
        presellOrderExtend.setOrderSn(orderSn);
        presellOrderExtend.setDepositPaySn(paySn);
        presellOrderExtend.setGoodsId(presellGoods.getGoodsId());
        presellOrderExtend.setProductId(productId);
        presellOrderExtend.setProductNum(productNum);
        presellOrderExtend.setPresellPrice(presellGoods.getPresellPrice());
        //待付款状态
        presellOrderExtend.setOrderSubState(OrderConst.ORDER_SUB_STATE_101);
        if (presell.getType() == PreSellConst.PRE_SELL_TYPE_1) {
            if (!StringUtil.isNullOrZero(presellGoods.getFirstExpand())) {
                presellOrderExtend.setFirstExpand(presellGoods.getFirstExpand());
            }
            presellOrderExtend.setDepositAmount(presellGoods.getFirstMoney());
            presellOrderExtend.setIsAllPay(OrderConst.IS_ALL_PAY_0);
        } else {
            presellOrderExtend.setDepositAmount(presellGoods.getPresellPrice());
            presellOrderExtend.setIsAllPay(OrderConst.IS_ALL_PAY_1);
        }
        presellOrderExtend.setRemainAmount(presellGoods.getSecondMoney());
        presellOrderExtend.setDepositEndTime(presell.getEndTime());
        presellOrderExtend.setRemainStartTime(presell.getRemainStartTime());
        presellOrderExtend.setRemainEndTime(presell.getRemainEndTime());
        presellOrderExtend.setDeliverTime(presell.getDeliverTime());
        presellOrderExtend.setStoreId(presell.getStoreId());
        presellOrderExtend.setMemberId(memberId);
        presellOrderExtend.setCreateTime(new Date());
        return this.savePresellOrderExtend(presellOrderExtend);
    }

    /**
     * 系统定时发送待支付尾款提醒
     *
     * @return boolean
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean jobSystemSendBalancePaymentRemind() {
        //设置尾款订单支付结束前多少小时为支付提醒时间，默认24小时，“0”代表不设置提醒
        String value = stringRedisTemplate.opsForValue().get("tail_money_order_payment_reminder");
        if ("0".equals(value)) {
            return true;
        }
        int limitMinute = value == null ? 24 : Integer.parseInt(value);

        Date date = DateUtil.date();
        //查询还未提醒会员支付订单尾款的数据
        PresellOrderExtendExample example = new PresellOrderExtendExample();
        example.setRemainEndTimeAfter(date);
        example.setRemainEndTimeBefore(DateUtil.offset(date, DateField.HOUR, limitMinute));
        example.setOrderSubState(OrderConst.ORDER_SUB_STATE_102);
        example.setIsRemindMember(PreSellConst.IS_REMIND_MEMBER_0);
        List<PresellOrderExtend> list = presellOrderExtendReadMapper.listByExample(example);
        if (CollectionUtils.isEmpty(list)) {
            return true;
        }
        list.forEach(presellOrderExtend -> {
            //订单号
            String orderSn = presellOrderExtend.getOrderSn();
            //会员消息通知
            //微信通知
            List<MessageSendProperty> messageSendPropertyList = new ArrayList<>();
            messageSendPropertyList.add(new MessageSendProperty("first", "您有一笔订单尾款未支付，请及时支付。"));
            messageSendPropertyList.add(new MessageSendProperty("keyword1", orderSn));
            messageSendPropertyList.add(new MessageSendProperty("remark", "点击查看订单详情。"));
            messageSendPropertyList.add(new MessageSendProperty("url", DomainUrlUtil.SLD_H5_URL + "/pages/order/detail?orderSn=" + orderSn));
            String msgLinkInfo = "{\"type\":\"order_news\",\"orderSn\":\"" + orderSn + "\"}";
            String[] templateParam = {orderSn};
            MessageSendVO messageSendVO = new MessageSendVO(messageSendPropertyList, presellOrderExtend.getMemberId(),
                    MemberTplConst.BALANCE_PAYMENT_REMINDER, msgLinkInfo, templateParam);
            //发送到mq
            rabbitTemplate.convertAndSend(MQ_EXCHANGE_NAME, MQ_QUEUE_NAME_MEMBER_MSG, messageSendVO);
        });
        //修改提醒状态
        PresellOrderExtend orderExtend = new PresellOrderExtend();
        orderExtend.setIsRemindMember(PreSellConst.IS_REMIND_MEMBER_1);
        presellOrderExtendWriteMapper.updateByExampleSelective(orderExtend, example);
        return true;
    }

    /**
     * 系统定时发送预售商品待发货提醒
     *
     * @return boolean
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean jobSystemSendDeliverRemind() {
        //设置预售订单发货结束前多少小时为发货提醒时间，默认24小时，“0”代表不设置提醒
        String value = stringRedisTemplate.opsForValue().get("presale_order_delivery_reminder");
        if ("0".equals(value)) {
            return true;
        }
        int limitMinute = value == null ? 24 : Integer.parseInt(value);

        Date date = DateUtil.date();
        //查询还未提醒商家预售商品待发货的数据
        PresellOrderExtendExample example = new PresellOrderExtendExample();
        example.setDeliverTimeAfter(date);
        example.setDeliverTimeBefore(DateUtil.offset(date, DateField.HOUR, limitMinute));
        example.setOrderSubState(OrderConst.ORDER_SUB_STATE_103);
        example.setIsRemindStore(PreSellConst.IS_REMIND_STORE_0);
        List<PresellOrderExtend> list = presellOrderExtendReadMapper.listByExample(example);
        if (CollectionUtils.isEmpty(list)) {
            return true;
        }
        list.forEach(presellOrderExtend -> {
            //订单号
            String orderSn = presellOrderExtend.getOrderSn();
            String msgLinkInfo = "{\"orderSn\":\"" + orderSn + "\",\"type\":\"order_news\"}";
            String[] templateParam = {orderSn};
            MessageSendVO messageSendVO = new MessageSendVO(presellOrderExtend.getStoreId(), StoreTplConst.PRE_SALE_GOODS_DELIVER_REMINDER, msgLinkInfo, templateParam);
            //发送到mq
            rabbitTemplate.convertAndSend(MQ_EXCHANGE_NAME, MQ_QUEUE_NAME_SELLER_MSG, messageSendVO);
        });
        //修改提醒状态
        PresellOrderExtend orderExtend = new PresellOrderExtend();
        orderExtend.setIsRemindStore(PreSellConst.IS_REMIND_STORE_1);
        presellOrderExtendWriteMapper.updateByExampleSelective(orderExtend, example);
        return true;
    }
}