package com.xiaopin.v2.mq.goods.listener;

import com.xiaopin.util.DateUtils;
import com.xiaopin.v2.dto.goods.es.GoodsEsDetailEntity.HuNan;
import com.xiaopin.v2.dto.goods.es.GoodsEsDetailEntity.HeBei;
import com.xiaopin.v2.dto.goods.es.GoodsEsDetailEntity.XinJiang;
import com.xiaopin.v2.dto.goods.es.GoodsEsDetailEntity.ChongQing;
import com.xiaopin.v2.dto.goods.es.GoodsEsDetailEntity.ShangHai;
import com.xiaopin.v2.dto.goods.es.GoodsEsDetailEntity.HaiNan;
import com.xiaopin.v2.dto.goods.es.GoodsEsDetailEntity.TaiWan;
import com.xiaopin.v2.dto.goods.es.GoodsEsDetailEntity.XiangGang;

import java.math.BigDecimal;

import com.xiaopin.v2.dto.goods.es.GoodsEsDetailEntity.NeiMengGu;
import com.xiaopin.v2.dto.goods.es.GoodsEsDetailEntity.JiangXi;
import com.xiaopin.v2.dto.goods.es.GoodsEsDetailEntity.FuJian;
import com.xiaopin.v2.dto.goods.es.GoodsEsDetailEntity.HeNan;
import com.xiaopin.v2.dto.goods.es.GoodsEsDetailEntity.ShanXi;
import com.xiaopin.v2.dto.goods.es.GoodsEsDetailEntity.GuangXi;
import com.xiaopin.v2.dto.goods.es.GoodsEsDetailEntity.NingXia;
import com.xiaopin.v2.dto.goods.es.GoodsEsDetailEntity.TianJin;
import com.xiaopin.v2.dto.goods.es.GoodsEsDetailEntity.ZheJiang;
import com.xiaopin.v2.dto.goods.es.GoodsEsDetailEntity.AoMen;
import com.xiaopin.v2.dto.goods.es.GoodsEsDetailEntity.GanSu;
import com.xiaopin.v2.dto.goods.es.GoodsEsDetailEntity.JiangSu;
import com.xiaopin.v2.dto.goods.es.GoodsEsDetailEntity.QingHai;
import com.xiaopin.v2.dto.goods.es.GoodsEsDetailEntity.GuiZhou;
import com.xiaopin.v2.dto.goods.es.GoodsEsDetailEntity.LiaoNing;
import com.xiaopin.v2.dto.goods.es.GoodsEsDetailEntity.BeiJing;
import com.xiaopin.v2.dto.goods.es.GoodsEsDetailEntity.AnHui;
import com.xiaopin.v2.dto.goods.es.GoodsEsDetailEntity.XiZang;
import com.xiaopin.v2.dto.goods.es.GoodsEsDetailEntity.SiChuan;
import com.xiaopin.v2.dto.goods.es.GoodsEsDetailEntity.YunNan;
import com.xiaopin.v2.dto.goods.es.GoodsEsDetailEntity.JiLin;
import com.xiaopin.v2.dto.goods.es.GoodsEsDetailEntity.HeiLongJiang;
import com.xiaopin.v2.dto.goods.es.GoodsEsDetailEntity.GuangDong;
import com.xiaopin.v2.dto.goods.es.GoodsEsDetailEntity.HuBei;
import com.xiaopin.v2.dto.goods.es.GoodsEsDetailEntity.ShanDong;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.xiaopin.entity.Goods;
import com.xiaopin.entity.GoodsCommon;
import com.xiaopin.feignclient.invoke.MemberCenterFeign;
import com.xiaopin.serviceinterface.GoodsCommonService;
import com.xiaopin.serviceinterface.GoodsService;
import com.xiaopin.util.HighLevelClientUtils;
import com.xiaopin.v2.constant.EsGoodsSearchConstant;
import com.xiaopin.v2.dto.goods.es.GoodsEsDetailEntity;
import com.xiaopin.v2.mq.goods.entity.GoodsEsMessageEntity;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
import org.apache.rocketmq.common.consumer.ConsumeFromWhere;
import org.apache.rocketmq.spring.core.RocketMQListener;
import org.apache.rocketmq.spring.core.RocketMQPushConsumerLifecycleListener;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;

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

/**
 * @Author fanzhenxi
 * @Date 2024/6/27 上午11:12
 * @Version 2.0
 * @Description <p>备注:v2-商品ES更新消息处理</p>
 */
@Slf4j
@Component
//@RocketMQMessageListener(consumerGroup = "${rocketmq.namespace}%${rocketmq.consumer.GoodsEsUpdateGroup}",
//        topic = "${rocketmq.namespace}%${rocketmq.consumer.GoodsEsUpdateTopic}",
//        consumeMode = ConsumeMode.ORDERLY,
//        messageModel = MessageModel.BROADCASTING)
public class GoodsEsUpdateMessageListener implements RocketMQListener<GoodsEsMessageEntity>, RocketMQPushConsumerLifecycleListener {

    /**
     * ES查询链接客户端
     */
    @Autowired
    private RestHighLevelClient restHighLevelClient;
    /**
     * 为微服务内部调用发布到注册中心的方法
     */
    @Autowired
    private MemberCenterFeign memberCenterFeign;
    /**
     * 线程池注入
     */
    @Resource
    @Qualifier("publicThreadPool")
    private ThreadPoolTaskExecutor publicThreadPool;
    /**
     * 商品goodsCommon服务
     */
    @Autowired
    private GoodsCommonService goodsCommonService;
    /**
     * 商品goods服务
     */
    @Autowired
    private GoodsService goodsService;

    /**
     * 当接收到敏感词消息时的处理逻辑。
     *
     * @param message 敏感词MQ实体,包含敏感词相关信息和操作类型。
     *                该实体用于后续敏感词树的重置或更新。
     */
    @Override
    public void onMessage(GoodsEsMessageEntity message) {
        try {
            if (message == null) {
                log.error("###GoodsEsUpdateMessageListener##onMessage#ES同步消息文本对象为空!");
                return;
            }
            if (StrUtil.isBlank(message.getGoodsId())) {
                log.error("###GoodsEsUpdateMessageListener##onMessage#ES同步消息商品ID对象为空!messageExt: {}", JSONUtil.toJsonStr(message));
                return;
            }
            // 处理消息逻辑
            log.info("###GoodsEsUpdateMessageListener##onMessage#ThreadName: {},message: {}", Thread.currentThread().getName(), JSONUtil.toJsonStr(message));
            // 封装商品消息实体类
            GoodsEsDetailEntity goodsEsDetailEntity = encapsulationGoodsEntity(message);
            // 插入数据到ES中
            Boolean esExecuteResult = insertDataToES(message.getGoodsId(), goodsEsDetailEntity);
            // ES结果插入完成后调用消息中心 记录执行内容MessageCenterController
            log.info("###GoodsEsUpdateMessageListener##onMessage#message: {},esExecuteResult: {}", JSONUtil.toJsonStr(message), esExecuteResult);
        } catch (Exception e) {
            // 消费失败,稍后重试
            log.error("###GoodsEsUpdateMessageListener##onMessage#Message consumption failed!errorMessage: {},e:", e.getMessage(), e);
        }
    }

    /**
     * 根据消息实体 查询数据库 封装商品消息实体类
     * <ul>
     *   <li>查询goods_common表</li>
     *   <li>查询goods表</li>
     *   <li >查询goods_common_undelivery_area表 </li>
     *   <li>查询活动表</li>
     *   <li>查询优惠表</li>
     *   <li>查询直播表</li>
     *   <li>手动计算部分字段</li>
     *   <li>构建省字段【不可配送范围】</li>
     * </ul>
     *
     * @param message 商品ES更新消息入参实体
     * @return ES商品实体
     */
    private GoodsEsDetailEntity encapsulationGoodsEntity(GoodsEsMessageEntity message) {
        GoodsEsDetailEntity goodsEsDetailEntity = null;
        try {


            // 将查询出来的内容封装成为ES实体类
            goodsEsDetailEntity = encapsulationEntity(searchGoodsCommon, searchGoods, searchGoodsCommonUndeliveryArea, searchGoodsActivity, searchGoodsPreferential, searchGoodsLive);

        } catch (Exception e) {
            log.error("###GoodsEsUpdateMessageListener##encapsulationGoodsEntity#errorMessage: {},e:", e.getMessage(), e);
        }
        return goodsEsDetailEntity;
    }



  
    /**
     * 插入数据到ES中
     *
     * @param goodsId             商品ID
     * @param goodsEsDetailEntity 构建出来的商品ES实体
     * @return true成功 false失败
     */
    private Boolean insertDataToES(String goodsId, GoodsEsDetailEntity goodsEsDetailEntity) {
        boolean esExecuteResult = Boolean.FALSE;
            esExecuteResult = HighLevelClientUtils.insert(restHighLevelClient, EsGoodsSearchConstant.GOODS_INDEX_DETAIL, goodsEsDetailEntity, goodsId);
        return esExecuteResult;
    }

    /**
     * 在消费者启动前设置从最新的位置开始消费
     * <p>每个消费者实例的配置是独立的,即每个消费者类实现的 RocketMQPushConsumerLifecycleListener 接口中的 prepareStart 方法
     * 只会影响该消费者类对应的 DefaultMQPushConsumer 实例,不会影响其他消费者实例。</p>
     *
     * @param consumer 消费实体
     */
    @Override
    public void prepareStart(DefaultMQPushConsumer consumer) {
        consumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_LAST_OFFSET);
    }
}