package com.slodon.b2b2c.job;

import com.slodon.b2b2c.business.example.OrderAfterServiceExample;
import com.slodon.b2b2c.business.pojo.OrderAfterService;
import com.slodon.b2b2c.business.pojo.OrderReturn;
import com.slodon.b2b2c.core.config.DomainUrlUtil;
import com.slodon.b2b2c.core.constant.MemberTplConst;
import com.slodon.b2b2c.core.constant.StoreTplConst;
import com.slodon.b2b2c.core.util.AssertUtil;
import com.slodon.b2b2c.model.business.OrderAfterServiceModel;
import com.slodon.b2b2c.model.business.OrderModel;
import com.slodon.b2b2c.starter.mq.entity.MessageSendProperty;
import com.slodon.b2b2c.starter.mq.entity.MessageSendVO;
import lombok.extern.slf4j.Slf4j;
import net.javacrumbs.shedlock.spring.annotation.SchedulerLock;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

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

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

@Slf4j
@Component
@Configuration      //1.主要用于标记配置类，兼备Component的效果。
//@EnableScheduling   //2.开启定时任务
public class BusinessJob {

    @Resource
    private OrderModel orderModel;
    @Resource
    private OrderAfterServiceModel orderAfterServiceModel;
    @Resource
    private RabbitTemplate rabbitTemplate;

    /**
     * 系统自动完成订单
     * 对已发货状态的订单发货时间超过10个自然日(取setting表配置)的订单进行自动完成处理
     */
//    @Scheduled(cron = "0 0/10 * * * ?")
//    @SchedulerLock(name = "jobSystemFinishOrder", lockAtMostFor = "600000", lockAtLeastFor = "540000")
    public void jobSystemFinishOrder() {
        log.info("jobSystemFinishOrder() start");
        try {
            boolean jobResult = orderModel.jobSystemFinishOrder();
            AssertUtil.isTrue(!jobResult, "[jobSystemFinishOrder] 系统自动完成订单时失败");
        } catch (Exception e) {
            log.error("jobSystemFinishOrder()", e);
        }
        log.info("jobSystemFinishOrder() end");
    }

    /**
     * 系统自动取消24小时没有付款订单
     * 每隔十分钟执行一次
     */
//    @Scheduled(cron = "0 5/10 * * * ?")
//    @SchedulerLock(name = "jobSystemCancelOrder", lockAtMostFor = "600000", lockAtLeastFor = "540000")
    public void jobSystemCancelOrder() {
        log.info("jobSystemCancelOrder() start");
        try {
            boolean jobResult = orderModel.jobSystemCancelOrder();
            AssertUtil.isTrue(!jobResult, "[jobSystemCancelOrder] 定时任务系统自动取消24小时没有付款订单时失败");
        } catch (Exception e) {
            log.error("jobSystemCancelOrder()", e);
        }
        log.info("jobSystemCancelOrder() end");
    }

    /**
     * 系统自动取消没有付款的秒杀订单
     * 每隔一分钟执行一次
     */
//    @Scheduled(cron = "0 0/1 * * * ?")
//    @SchedulerLock(name = "jobSystemCancelSeckillOrder", lockAtMostFor = "60000", lockAtLeastFor = "50000")
    public void jobSystemCancelSeckillOrder() {
        log.info("jobSystemCancelSeckillOrder() start");
        try {
            boolean jobResult = orderModel.jobSystemCancelSeckillOrder();
            AssertUtil.isTrue(!jobResult, "[jobSystemCancelSeckillOrder] 定时任务系统自动取消没有付款秒杀订单时失败");
        } catch (Exception e) {
            log.error("jobSystemCancelSeckillOrder()", e);
        }
        log.info("jobSystemCancelSeckillOrder() end");
    }

    /**
     * 系统自动取消没有付款的阶梯团订单
     * 每隔五分钟执行一次
     */
//    @Scheduled(cron = "0 0/5 * * * ?")
//    @SchedulerLock(name = "jobSystemCancelLadderGroupOrder", lockAtMostFor = "300000", lockAtLeastFor = "240000")
    public void jobSystemCancelLadderGroupOrder() {
        log.info("jobSystemCancelLadderGroupOrder() start");
        try {
            boolean jobResult = orderModel.jobSystemCancelLadderGroupOrder();
            AssertUtil.isTrue(!jobResult, "[jobSystemCancelLadderGroupOrder] 定时任务系统自动取消没有付款阶梯团订单时失败");
        } catch (Exception e) {
            log.error("jobSystemCancelLadderGroupOrder()", e);
        }
        log.info("jobSystemCancelLadderGroupOrder() end");
    }

    /**
     * 系统自动取消没有付款的阶梯团尾款订单
     * 每隔五分钟执行一次
     */
//    @Scheduled(cron = "0 0/5 * * * ?")
//    @SchedulerLock(name = "jobSystemCancelLadderGroupBalanceOrder", lockAtMostFor = "300000", lockAtLeastFor = "240000")
    public void jobSystemCancelLadderGroupBalanceOrder() {
        log.info("jobSystemCancelLadderGroupBalanceOrder() start");
        try {
            boolean jobResult = orderModel.jobSystemCancelLadderGroupBalanceOrder();
            AssertUtil.isTrue(!jobResult, "[jobSystemCancelLadderGroupBalanceOrder] 定时任务系统自动取消没有付尾款阶梯团尾款订单时失败");
        } catch (Exception e) {
            log.error("jobSystemCancelLadderGroupBalanceOrder()", e);
        }
        log.info("jobSystemCancelLadderGroupBalanceOrder() end");
    }

    /**
     * 系统自动取消没有付款的预售订单
     * 每隔五分钟执行一次
     */
//    @Scheduled(cron = "0 0/5 * * * ?")
//    @SchedulerLock(name = "jobSystemCancelPreSellOrder", lockAtMostFor = "300000", lockAtLeastFor = "240000")
    public void jobSystemCancelPreSellOrder() {
        log.info("jobSystemCancelPreSellOrder() start");
        try {
            boolean jobResult = orderModel.jobSystemCancelPreSellOrder();
            AssertUtil.isTrue(!jobResult, "[jobSystemCancelPreSellOrder] 定时任务系统自动取消没有付款预售订单时失败");
        } catch (Exception e) {
            log.error("jobSystemCancelPreSellOrder()", e);
        }
        log.info("jobSystemCancelPreSellOrder() end");
    }

    /**
     * 系统自动取消没有付款的预售尾款订单
     * 每隔五分钟执行一次
     */
//    @Scheduled(cron = "0 0/5 * * * ?")
//    @SchedulerLock(name = "jobSystemCancelPreSellBalanceOrder", lockAtMostFor = "300000", lockAtLeastFor = "240000")
    public void jobSystemCancelPreSellBalanceOrder() {
        log.info("jobSystemCancelPreSellBalanceOrder() start");
        try {
            boolean jobResult = orderModel.jobSystemCancelPreSellBalanceOrder();
            AssertUtil.isTrue(!jobResult, "[jobSystemCancelPreSellBalanceOrder] 定时任务系统自动取消没有付尾款预售订单时失败");
        } catch (Exception e) {
            log.error("jobSystemCancelPreSellBalanceOrder()", e);
        }
        log.info("jobSystemCancelPreSellBalanceOrder() end");
    }

    /**
     * 系统自动取消没有付款的拼团订单
     * 每隔五分钟执行一次
     */
//    @Scheduled(cron = "0 0/5 * * * ?")
//    @SchedulerLock(name = "jobSystemCancelSpellOrder", lockAtMostFor = "300000", lockAtLeastFor = "240000")
    public void jobSystemCancelSpellOrder() {
        log.info("jobSystemCancelSpellOrder() start");
        try {
            boolean jobResult = orderModel.jobSystemCancelSpellOrder();
            AssertUtil.isTrue(!jobResult, "[jobSystemCancelSpellOrder] 定时任务系统自动取消没有付款拼团订单时失败");
        } catch (Exception e) {
            log.error("jobSystemCancelSpellOrder()", e);
        }
        log.info("jobSystemCancelSpellOrder() end");
    }

    /**
     * 系统自动发起对拼团失败的退款
     * 对拼团活动成团后在截团期间对未完成拼团的的订单进行自动发起退款处理
     */
//    @Scheduled(cron = "0 0/15 * * * ?")
//    @SchedulerLock(name = "jobSystemLaunchSpellRefund", lockAtMostFor = "900000", lockAtLeastFor = "840000")
    public void jobSystemLaunchSpellRefund() {
        log.info("jobSystemLaunchSpellRefund() start");
        try {
            boolean jobResult = orderModel.jobSystemLaunchSpellRefund();
            AssertUtil.isTrue(!jobResult, "[jobSystemLaunchSpellRefund] 定时任务自动发起拼团失败的退款时失败");
        } catch (Exception e) {
            log.error("jobSystemLaunchSpellRefund()", e);
        }
        log.info("jobSystemLaunchSpellRefund() end");
    }

    /**
     * 系统自动处理售后单
     * 1.商户未审核的退货退款申请
     * 2.商户未审核的换货
     * 3.商户未审核的仅退款申请
     * 4.用户退货发货但是到时间限制商户还未收货
     * 5.用户发货超过自动取消售后单
     */
//    @Scheduled(cron = "0 0/10 * * * ?")
//    @SchedulerLock(name = "jobSystemDealAfterService", lockAtMostFor = "600000", lockAtLeastFor = "540000")
    public void jobSystemDealAfterService() {
        log.info("jobSystemDealAfterService() start");
        try {
            Map<String, List<OrderReturn>> resultMap = orderAfterServiceModel.jobSystemDealAfterService();

            List<OrderReturn> returnsReceiveList = resultMap.get("returnsReceiveList");
            List<OrderReturn> returnsApplyList = resultMap.get("returnsApplyList");
            List<OrderReturn> refundApplyList = resultMap.get("refundApplyList");

            //处理退货自动处理消息通知
            if (!CollectionUtils.isEmpty(returnsReceiveList)) {
                for (OrderReturn orderReturn : returnsReceiveList) {
                    OrderAfterServiceExample afterServiceExample = new OrderAfterServiceExample();
                    afterServiceExample.setAfsSn(orderReturn.getAfsSn());
                    List<OrderAfterService> orderAfterServiceList = orderAfterServiceModel.getOrderAfterServiceList(afterServiceExample, null);
                    if (CollectionUtils.isEmpty(orderAfterServiceList)) {
                        continue;
                    }
                    OrderAfterService orderAfterService = orderAfterServiceList.get(0);
                    //添加消息通知
                    String msgLinkInfo = "{\"type\":\"return_news\",\"afsSn\":\"" + orderReturn.getAfsSn() + "\"}";
                    String[] templateParam = {orderReturn.getAfsSn()};
                    MessageSendVO messageSendVO = new MessageSendVO(orderReturn.getStoreId(), StoreTplConst.MEMBER_RETURN_AUTO_RECEIVE_REMINDER, msgLinkInfo, templateParam);

                    //发送到mq
                    rabbitTemplate.convertAndSend(MQ_EXCHANGE_NAME, MQ_QUEUE_NAME_SELLER_MSG, messageSendVO);
                    //发送会员售后提醒到mq
                    //微信消息通知
                    List<MessageSendProperty> messageSendPropertyList = new ArrayList<>();
                    messageSendPropertyList.add(new MessageSendProperty("first", "您的售后单有新的变化。"));
                    messageSendPropertyList.add(new MessageSendProperty("keyword1", orderReturn.getAfsSn()));
                    messageSendPropertyList.add(new MessageSendProperty("keyword2", orderReturn.getReturnMoneyAmount().add(orderReturn.getReturnExpressAmount()) + "元"));
                    messageSendPropertyList.add(new MessageSendProperty("keyword3", orderReturn.getReturnNum() + "件"));
                    messageSendPropertyList.add(new MessageSendProperty("keyword4", orderAfterService.getApplyReasonContent()));
                    messageSendPropertyList.add(new MessageSendProperty("remark", "点击【详情】查看售后详情"));
                    messageSendPropertyList.add(new MessageSendProperty("url", DomainUrlUtil.SLD_H5_URL + "/pages/order/refundDetail?afsSn=" + orderAfterService.getAfsSn()));
                    MessageSendVO sendVO = new MessageSendVO(messageSendPropertyList, orderReturn.getMemberId(),
                            MemberTplConst.AFTER_SALE_REMINDER, msgLinkInfo, templateParam);
                    rabbitTemplate.convertAndSend(MQ_EXCHANGE_NAME, MQ_QUEUE_NAME_MEMBER_MSG, sendVO);
                }
            }
            //处理退货未收货自动处理消息通知
            if (!CollectionUtils.isEmpty(returnsApplyList)) {
                for (OrderReturn orderReturn : returnsApplyList) {
                    OrderAfterServiceExample afterServiceExample = new OrderAfterServiceExample();
                    afterServiceExample.setAfsSn(orderReturn.getAfsSn());
                    List<OrderAfterService> orderAfterServiceList = orderAfterServiceModel.getOrderAfterServiceList(afterServiceExample, null);
                    if (CollectionUtils.isEmpty(orderAfterServiceList)) {
                        continue;
                    }
                    OrderAfterService orderAfterService = orderAfterServiceList.get(0);

                    //添加消息通知
                    String msgLinkInfo = "{\"type\":\"return_news\",\"afsSn\":\"" + orderReturn.getAfsSn() + "\"}";
                    String[] templateParam = {orderReturn.getAfsSn()};
                    MessageSendVO messageSendVO = new MessageSendVO(orderReturn.getStoreId(), StoreTplConst.MEMBER_AUTO_RETURN_REMINDER, msgLinkInfo, templateParam);

                    //发送到mq
                    rabbitTemplate.convertAndSend(MQ_EXCHANGE_NAME, MQ_QUEUE_NAME_SELLER_MSG, messageSendVO);
                    //发送会员售后提醒到mq
                    //微信消息通知
                    List<MessageSendProperty> messageSendPropertyList = new ArrayList<>();
                    messageSendPropertyList.add(new MessageSendProperty("first", "您的售后单有新的变化。"));
                    messageSendPropertyList.add(new MessageSendProperty("keyword1", orderReturn.getAfsSn()));
                    messageSendPropertyList.add(new MessageSendProperty("keyword2", orderReturn.getReturnMoneyAmount().add(orderReturn.getReturnExpressAmount()) + "元"));
                    messageSendPropertyList.add(new MessageSendProperty("keyword3", orderReturn.getReturnNum() + "件"));
                    messageSendPropertyList.add(new MessageSendProperty("keyword4", orderAfterService.getApplyReasonContent()));
                    messageSendPropertyList.add(new MessageSendProperty("remark", "点击【详情】查看售后详情"));
                    messageSendPropertyList.add(new MessageSendProperty("url", DomainUrlUtil.SLD_H5_URL + "/pages/order/refundDetail?afsSn=" + orderAfterService.getAfsSn()));
                    MessageSendVO sendVO = new MessageSendVO(messageSendPropertyList, orderReturn.getMemberId(),
                            MemberTplConst.AFTER_SALE_REMINDER, msgLinkInfo, templateParam);
                    rabbitTemplate.convertAndSend(MQ_EXCHANGE_NAME, MQ_QUEUE_NAME_MEMBER_MSG, sendVO);
                }
            }
            //处理退款自动处理消息通知
            if (!CollectionUtils.isEmpty(refundApplyList)) {
                for (OrderReturn orderReturn : refundApplyList) {
                    OrderAfterServiceExample afterServiceExample = new OrderAfterServiceExample();
                    afterServiceExample.setAfsSn(orderReturn.getAfsSn());
                    List<OrderAfterService> orderAfterServiceList = orderAfterServiceModel.getOrderAfterServiceList(afterServiceExample, null);
                    if (CollectionUtils.isEmpty(orderAfterServiceList)) {
                        continue;
                    }
                    OrderAfterService orderAfterService = orderAfterServiceList.get(0);

                    //添加消息通知
                    String msgLinkInfo = "{\"type\":\"refund_news\",\"afsSn\":\"" + orderReturn.getAfsSn() + "\"}";
                    String[] templateParam = {orderReturn.getAfsSn()};
                    MessageSendVO messageSendVO = new MessageSendVO(orderReturn.getStoreId(), StoreTplConst.MEMBER_AUTO_REFUND_REMINDER, msgLinkInfo, templateParam);

                    //发送到mq
                    rabbitTemplate.convertAndSend(MQ_EXCHANGE_NAME, MQ_QUEUE_NAME_SELLER_MSG, messageSendVO);
                    //发送会员售后提醒到mq
                    //微信消息通知
                    List<MessageSendProperty> messageSendPropertyList = new ArrayList<>();
                    messageSendPropertyList.add(new MessageSendProperty("first", "您的售后单有新的变化。"));
                    messageSendPropertyList.add(new MessageSendProperty("keyword1", orderReturn.getAfsSn()));
                    messageSendPropertyList.add(new MessageSendProperty("keyword2", orderReturn.getReturnMoneyAmount().add(orderReturn.getReturnExpressAmount()) + "元"));
                    messageSendPropertyList.add(new MessageSendProperty("keyword3", orderReturn.getReturnNum() + "件"));
                    messageSendPropertyList.add(new MessageSendProperty("keyword4", orderAfterService.getApplyReasonContent()));
                    messageSendPropertyList.add(new MessageSendProperty("remark", "点击【详情】查看售后详情"));
                    messageSendPropertyList.add(new MessageSendProperty("url", DomainUrlUtil.SLD_H5_URL + "/pages/order/refundDetail?afsSn=" + orderAfterService.getAfsSn()));
                    MessageSendVO sendVO = new MessageSendVO(messageSendPropertyList, orderReturn.getMemberId(),
                            MemberTplConst.AFTER_SALE_REMINDER, msgLinkInfo, templateParam);
                    rabbitTemplate.convertAndSend(MQ_EXCHANGE_NAME, MQ_QUEUE_NAME_MEMBER_MSG, sendVO);
                }
            }
        } catch (Exception e) {
            log.error("jobSystemDealAfterService()", e);
        }
        log.info("jobSystemDealAfterService() end");
    }
}
