package com.slodon.b2b2c.job;

import com.slodon.b2b2c.core.config.DomainUrlUtil;
import com.slodon.b2b2c.core.constant.StoreTplConst;
import com.slodon.b2b2c.core.util.AssertUtil;
import com.slodon.b2b2c.goods.pojo.Product;
import com.slodon.b2b2c.model.goods.ESGoodsModel;
import com.slodon.b2b2c.model.goods.GoodsPromotionModel;
import com.slodon.b2b2c.model.goods.GoodsRankModel;
import com.slodon.b2b2c.model.goods.ProductModel;
import com.slodon.b2b2c.model.system.SettingModel;
import com.slodon.b2b2c.starter.mq.entity.MessageSendVO;
import com.slodon.b2b2c.system.pojo.Setting;
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.List;

import static com.slodon.b2b2c.core.constant.StarterConfigConst.MQ_EXCHANGE_NAME;
import static com.slodon.b2b2c.core.constant.StarterConfigConst.MQ_QUEUE_NAME_SELLER_MSG;

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

    @Resource
    private ESGoodsModel esGoodsModel;
    @Resource
    private ProductModel productModel;
    @Resource
    private GoodsPromotionModel goodsPromotionModel;
    @Resource
    private GoodsRankModel goodsRankModel;
    @Resource
    private RabbitTemplate rabbitTemplate;
    @Resource
    private SettingModel settingModel;

    /**
     * 系统定时更新es索引
     * 每隔十分钟执行一次
     */
    @Scheduled(cron = "0 0/10 * * * ?")
    @SchedulerLock(name = "jobSearchES", lockAtMostFor = "600000", lockAtLeastFor = "540000")
    public void jobSearchES() {
        log.info("jobSearchES() start");
        List<Setting> webSiteList = settingModel.getSiteSetting();
        if (!CollectionUtils.isEmpty(webSiteList)) {
            for (Setting setting : webSiteList) {
                log.info("jobSearchES() start");
                try {
                    boolean jobResult = esGoodsModel.jobCreateIndexesES(DomainUrlUtil.SLD_ES_URL, DomainUrlUtil.SLD_ES_PORT, "job", setting.getValue());
                    AssertUtil.isTrue(!jobResult, "[jobSearchES] 系统定时任务定时生成ES索引失败");
                } catch (Exception e) {
                    log.error("jobSearchES()", e);
                }
            }
        }
        log.info("jobSearchES() end");
    }

    /**
     * 系统定时对库存进行检查
     * 达到预警值的库存会给商家发送信息
     */
//    @Scheduled(cron = "0 0/15 * * * ?")
//    @SchedulerLock(name = "jobSystemSendStockWarnRemind", lockAtMostFor = "900000", lockAtLeastFor = "600000")
    public void jobSystemSendStockWarnRemind() {
        log.info("jobSystemSendStockWarnRemind() start");
        try {
            List<Product> productList = productModel.jobSystemCheckProductStock();
            if (!CollectionUtils.isEmpty(productList)) {
                for (Product product : productList) {
                    //消息通知对象
                    String msgLinkInfo = "{\"goodsId\":\"" + product.getGoodsId() + "\",\"type\":\"goods_news\"}";
                    String[] templateParam = {product.getGoodsName(), product.getSpecValues()};
                    MessageSendVO messageSendVO = new MessageSendVO(product.getStoreId(), StoreTplConst.GOODS_STOCK_WARNING, msgLinkInfo, templateParam);
                    //发送到mq
                    rabbitTemplate.convertAndSend(MQ_EXCHANGE_NAME, MQ_QUEUE_NAME_SELLER_MSG, messageSendVO);
                }
            }
        } catch (Exception e) {
            log.error("jobSystemSendStockWarnRemind()", e);
        }
        log.info("jobSystemSendStockWarnRemind() end");
    }

    /**
     * 定时清理已结束的商品活动
     * 每隔十分钟执行一次
     */
//    @Scheduled(cron = "0 5/10 * * * ?")
//    @SchedulerLock(name = "jobClearGoodsPromotion", lockAtMostFor = "600000", lockAtLeastFor = "540000")
    public void jobClearGoodsPromotion() {
        log.info("jobClearGoodsPromotion() start");
        try {
            boolean jobResult = goodsPromotionModel.jobClearGoodsPromotion();
            AssertUtil.isTrue(!jobResult, "[jobClearGoodsPromotion] 定时清理已结束的商品活动时失败");
        } catch (Exception e) {
            log.error("jobClearGoodsPromotion()", e);
        }
        log.info("jobClearGoodsPromotion() end");
    }

    /**
     * 定时更新商品时间
     * 每隔十分钟执行一次
     */
    @Scheduled(cron = "0 9/10 * * * ?")
    @SchedulerLock(name = "jobUpdateGoodsTime", lockAtMostFor = "600000", lockAtLeastFor = "540000")
    public void jobUpdateGoodsTime() {
        log.info("jobUpdateGoodsTime() start");
        try {
            boolean jobResult = goodsPromotionModel.jobUpdateGoodsTime();
            AssertUtil.isTrue(!jobResult, "[jobUpdateGoodsTime] 定时更新商品时间时失败");
        } catch (Exception e) {
            log.error("jobUpdateGoodsTime()", e);
        }
        log.info("jobUpdateGoodsTime() end");
    }

    /**
     * 定时更新排行榜商品数据
     * 每日1：00进行重新计算并更新
     */
    @Scheduled(cron = "10 0 1 * * ?")
    @SchedulerLock(name = "jobUpdateRankGoods", lockAtMostFor = "86400000", lockAtLeastFor = "82800000")
    public void jobUpdateRankGoods() {
        log.info("jobUpdateRankGoods() start");
        try {
            boolean jobResult = goodsRankModel.jobUpdateRankGoods();
            AssertUtil.isTrue(!jobResult, "[jobUpdateRankGoods] 定时更新排行榜商品数据时失败");
        } catch (Exception e) {
            log.error("jobUpdateRankGoods()", e);
        }
        log.info("jobUpdateRankGoods() end");
    }
}
