package com.gic.haoban.manage.service.service.out.impl.content;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.gic.api.base.commons.Page;
import com.gic.api.base.commons.ServiceResponse;
import com.gic.business.order.dto.ordermanage.OrderOutInfoDTO;
import com.gic.business.order.enums.OrderEnum;
import com.gic.business.order.qdto.ordermanage.OrderInfoQDTO;
import com.gic.business.order.service.ordermanage.OrderInfoOutApiService;
import com.gic.commons.util.GICMQClientUtil;
import com.gic.content.api.dto.analysis.GoodsAnalysisMemberBuryPointDTO;
import com.gic.content.api.dto.burypoint.ContentMemberBuryPointDTO;
import com.gic.content.api.dto.setting.ContentSettingDTO;
import com.gic.content.api.enums.ContentMallShopType;
import com.gic.content.api.qdto.analysis.GoodsAnalysisMemberBuryPointQDTO;
import com.gic.content.api.qdto.analysis.GoodsAnalysisRecommendBuryPointQDTO;
import com.gic.content.api.qdto.burypoint.MemberBuryPointOrderQDTO;
import com.gic.content.api.service.ContentMemberBuryPointApiService;
import com.gic.content.api.service.ContentSettingApiService;
import com.gic.content.api.service.analysis.GoodsAnalysisMemberBuryPointApiService;
import com.gic.enterprise.api.constant.EnterpriseServiceEnum;
import com.gic.enterprise.api.dto.EnterpriseUsingPermissionDto;
import com.gic.enterprise.api.dto.enterprise.EnterpriseUsingStatusDTO;
import com.gic.enterprise.api.service.EnterpriseUseForbidService;
import com.gic.haoban.manage.api.enums.content.MaterialInteractRecordEventType;
import com.gic.haoban.manage.api.enums.content.ShareBizType;
import com.gic.haoban.manage.api.service.content.MallOrderStatusChangeApiService;
import com.gic.haoban.manage.service.pojo.bo.content.InteractRecordBO;
import com.gic.haoban.manage.service.pojo.bo.content.OrderEventMqBO;
import com.gic.haoban.manage.service.pojo.bo.content.binlog.MemberOrderBo;
import com.gic.haoban.manage.service.pojo.bo.content.message.InteractRecordMessageBO;
import com.gic.haoban.manage.service.service.content.adaptor.EnterpriseAdaptor;
import com.gic.haoban.manage.service.service.content.adaptor.InteractRecordBuilder;
import com.gic.haoban.manage.service.service.content.adaptor.WeekMonthDataAdaptor;
import com.gic.haoban.manage.service.service.content.message.InteractRecordMessageService;
import com.gic.haoban.manage.service.task.KafkaMessageServiceImpl;
import com.gic.order.api.constant.OrderChannelEnum;
import com.gic.redis.data.util.RedisUtil;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @Author MUSI
 * @Date 2023/4/6 5:28 PM
 * @Description
 * @Version
 **/
@Slf4j
@Component("mallOrderStatusChangeApiService")
public class MallOrderStatusChangeApiServiceImpl implements MallOrderStatusChangeApiService {


    @Autowired
    OrderInfoOutApiService orderInfoOutApiService;
    @Autowired
    InteractRecordMessageService interactRecordMessageService;
    @Autowired
    private EnterpriseAdaptor enterpriseAdaptor;
    @Autowired
    private EnterpriseUseForbidService enterpriseUseForbidService;
    @Autowired
    private ContentSettingApiService contentSettingApiService;
    @Autowired
    private ContentMemberBuryPointApiService contentMemberBuryPointApiService;
    @Autowired
    private InteractRecordBuilder interactRecordBuilder;
    @Autowired
    private GoodsAnalysisMemberBuryPointApiService goodsAnalysisMemberBuryPointApiService;

    private static final String ORDER_EVENT_RETRY = "orderEventRetryMQ";

    private static final Long cache_hour_sec = 300L;

    /***
     * 订单状态变更事件
     * @param params
     * @return
     */
    @Override
    public ServiceResponse<Void> mallOrderStatusChange(String params) {

        log.info("【MallOrderStatusChangeApiService】处理微商城订单状态变更事件 {}", params);
        OrderEventMqBO orderEventMqBO = JSON.parseObject(params, OrderEventMqBO.class);
        if (orderEventMqBO == null) {
            log.info("订单状态变更事件参数异常 {}", params);
            return ServiceResponse.success();
        }

        Integer toStatus = orderEventMqBO.getToStatus();
        if (!OrderEnum.OrderNodeEnum.PAY_ORDER.getOrderStep().equals(toStatus)) {
            log.info("订单事件不是支付事件 {}", toStatus);
            return ServiceResponse.success();
        }

        String enterpriseId = orderEventMqBO.getEnterpriseId();

        ServiceResponse<ContentSettingDTO> response = contentSettingApiService.queryContentSettingInfo(enterpriseId);
        if (!response.isSuccess() || response.getResult() == null) {
            log.info("查询企业内容配置异常 {}", enterpriseId);
            return ServiceResponse.success();
        }

        if (!ContentMallShopType.GIC_MALL.getCode().equals(response.getResult().getMallShopType())) {
            log.info("当前企业内容配置非微商城 {}", JSON.toJSONString(response));
            return ServiceResponse.success();
        }

        OrderInfoQDTO orderInfoQDTO = new OrderInfoQDTO();
        orderInfoQDTO.setEnterpriseId(orderEventMqBO.getEnterpriseId());
        orderInfoQDTO.setOrderNumber(orderEventMqBO.getOrderNumber());
        ServiceResponse<OrderOutInfoDTO> serviceResponse = orderInfoOutApiService.queryOrderInfo(orderInfoQDTO);
        if (!serviceResponse.isSuccess()) {
            log.info("查询订单信息异常 {}", JSON.toJSONString(serviceResponse));
            return ServiceResponse.success();
        }
        OrderOutInfoDTO orderInfo = serviceResponse.getResult();
        String extendJson = orderInfo.getExtendJson();
        if (StringUtils.isBlank(extendJson)) {
            log.info("订单扩展字段为空,不处理 params: {}", params);
            return ServiceResponse.success();
        }

        JSONObject jsonObject = JSON.parseObject(extendJson, JSONObject.class);
        String clerkId = jsonObject.getString("clerkId");
        String contentMaterialId = jsonObject.getString("contentMaterialId");
        String goodsId = jsonObject.getString("proId");
        String wxaLinkId = jsonObject.getString("wxaLinkId");
        String memberId = orderEventMqBO.getMemberId();
        log.info("wxaLinkId:{}",wxaLinkId);

        InteractRecordMessageBO interactRecordMessageBO = new InteractRecordMessageBO();
        interactRecordMessageBO.setWxaLinkId(wxaLinkId);
        // 查询多商品页面数据
        if (StringUtils.isNotBlank(wxaLinkId)) {
            Map<String, List<List<String>>> multipleMap = interactRecordBuilder.getGroupGoodsIdByWxaLinkIds(Lists.newArrayList(wxaLinkId));
            Integer goodsCount = interactRecordBuilder.getGoodsCount(interactRecordMessageBO, multipleMap);
            interactRecordMessageBO.setGoodsCount(goodsCount);
        }
        String bizId = contentMaterialId;
        interactRecordMessageBO.setEnterpriseId(orderEventMqBO.getEnterpriseId());
        interactRecordMessageBO.setMemberId(memberId);
        interactRecordMessageBO.setClerkId(clerkId);
        if (StringUtils.isNotBlank(contentMaterialId) && StringUtils.isNumeric(contentMaterialId)) {
            interactRecordMessageBO.setMaterialId(contentMaterialId);
        }else if (interactRecordMessageBO.getGoodsCount() > 1) {
            interactRecordMessageBO.setWxaLinkId(wxaLinkId);
            bizId = wxaLinkId;
        }else if (StringUtils.isNotBlank(goodsId) && !StringUtils.isNumeric(goodsId)) {
            interactRecordMessageBO.setGoodsId(goodsId);
            bizId = goodsId;
        }else {
            log.info("订单扩展信息中无要处理的数据 {}", extendJson);
            return ServiceResponse.success();
        }
        interactRecordMessageBO.setEventType(MaterialInteractRecordEventType.ORDER.getCode());
        interactRecordMessageBO.setDurationTime(0);
        interactRecordMessageBO.setLastAccessTime(orderInfo.getCreateTime().getTime());
        interactRecordMessageBO.setOrderNumber(orderEventMqBO.getOrderNumber());
        interactRecordMessageBO.setTimes(orderEventMqBO.getTimes());
        interactRecordMessageBO.setOrderType(1);
        InteractRecordBO interactRecordBO = interactRecordMessageService.getInteractRecordBOWithOrderType(interactRecordMessageBO,bizId);
        if (interactRecordBO == null) {
            log.info("订单事件先到达,埋点事件延迟  >>> {}", JSON.toJSONString(interactRecordMessageBO));
            if (orderEventMqBO.getTimes() != null && orderEventMqBO.getTimes() > 60) {
                log.info("订单事件延迟60分钟仍未被消费,忽略 {}", params);
                return ServiceResponse.success();
            }
            if (orderEventMqBO.getTimes() == null) {
                orderEventMqBO.setTimes(0);
            }
            orderEventMqBO.setTimes(orderEventMqBO.getTimes() + 1);
            this.sendDelayMessage(orderEventMqBO);
            return ServiceResponse.success();
        }

        interactRecordMessageService.dealRecord(interactRecordMessageBO);
        return ServiceResponse.success();
    }

    /**
     * 兼容订单事件先到达 埋点数据未到的情况
     *
     * @param params
     * @return
     */
    @Override
    public ServiceResponse<Void> orderEventDelay(String params) {
        // 处理埋点数据延迟的问题
        log.info("处理埋点数据延迟 订单事件先到的场景 >>>> {}", params);
        return this.mallOrderStatusChange(params);
    }


    public boolean sendDelayMessage(OrderEventMqBO orderEventMqBO) {
        log.info("[MallOrderStatusChangeApiService] 发送订单支付事件延迟处理消息 {}", JSON.toJSONString(orderEventMqBO));
        try {
            GICMQClientUtil.getClientInstance().sendMessage(ORDER_EVENT_RETRY, JSON.toJSONString(orderEventMqBO), 60);
        } catch (Exception e) {
            log.info("发送消息异常 {}", JSON.toJSONString(orderEventMqBO), e);
            return false;
        }
        return true;
    }

    /**
     * 处理微盟/自研订单
     * MQ： dealWeimoOrder
     * @param params
     * @return
     */
    @Override
    public ServiceResponse<Void> dealWeimoOrder(String params) {

        log.info("处理微盟/自研订单 {}", params);

        //订单分为tab_gic_eorder 和 tab_gic_ordeer
        MemberOrderBo memberOrderBo = JSON.parseObject(params, MemberOrderBo.class);
        if (memberOrderBo == null) {
            log.info("dealWeimoOrder 数据为空 {}", params);
            return ServiceResponse.success();
        }
        String enterpriseId = memberOrderBo.getEnterpriseId();
        boolean check = enterpriseAdaptor.checkEnterpriseHasRights(enterpriseId, EnterpriseAdaptor.rightCodeList);
        if (!check) {
            log.info("企业 {} 没有权限", enterpriseId);
            return ServiceResponse.success();
        }

        ServiceResponse<ContentSettingDTO> response = contentSettingApiService.queryContentSettingInfo(enterpriseId);
        if (!response.isSuccess() || response.getResult() == null) {
            log.info("查询企业内容配置异常 {}", enterpriseId);
            return ServiceResponse.success();
        }

        if (!ContentMallShopType.WEIMO_MALL.getCode().equals(response.getResult().getMallShopType())
                && !ContentMallShopType.THIRD_MALL.getCode().equals(response.getResult().getMallShopType())) {
            log.info("当前企业内容配置非微盟/自研商城 {}", JSON.toJSONString(response));
            return ServiceResponse.success();
        }
        Date materialTime = null;
        Date goodsTime = null;
        String goodsId = null;
        String wxaLinkId = null;


        String memberId = memberOrderBo.getMemberId();
        String orderId = memberOrderBo.getOrderId();
        String orderNumber = memberOrderBo.getOrderNumber();
        Date orderTime = memberOrderBo.getOrderTime();
        Integer orderType = memberOrderBo.getOrderType();
        InteractRecordMessageBO interactRecordMessageBO = new InteractRecordMessageBO();
        interactRecordMessageBO.setEnterpriseId(enterpriseId);
        interactRecordMessageBO.setMemberId(memberId);
        WeekMonthDataAdaptor.MaterialBizInfo materialBizInfo = null;
        MemberBuryPointOrderQDTO memberBuryPointOrderQDTO = new MemberBuryPointOrderQDTO();
        memberBuryPointOrderQDTO.setEnterpriseId(enterpriseId);
        memberBuryPointOrderQDTO.setOrderCreateTime(orderTime);
        memberBuryPointOrderQDTO.setMemberId(memberId);
        memberBuryPointOrderQDTO.setConvFlag(1);
        memberBuryPointOrderQDTO.setMallType(2);
        memberBuryPointOrderQDTO.setOrderType(orderType);
        ServiceResponse<ContentMemberBuryPointDTO> buryPointResponse = contentMemberBuryPointApiService.queryMemberBuryPoint(memberBuryPointOrderQDTO);
        if (buryPointResponse.isSuccess() && buryPointResponse.getResult() != null) {
            ContentMemberBuryPointDTO result = buryPointResponse.getResult();
            materialTime = result.getLocalTimestamp();
            materialBizInfo = new WeekMonthDataAdaptor.MaterialBizInfo(result.getClerkId(), String.valueOf(result.getContentMaterialId()), result.getStoreId(), ShareBizType.MATERIAL.getCode());
        }

        // 商品分享逻辑
        GoodsAnalysisRecommendBuryPointQDTO goodsAnalysisMemberBuryPointQDTO = new GoodsAnalysisRecommendBuryPointQDTO();
        goodsAnalysisMemberBuryPointQDTO.setEnterpriseId(enterpriseId);
        goodsAnalysisMemberBuryPointQDTO.setMemberId(memberId);
        goodsAnalysisMemberBuryPointQDTO.setOrderType(orderType);
        goodsAnalysisMemberBuryPointQDTO.setOrderCreateTime(orderTime);
        ServiceResponse<GoodsAnalysisMemberBuryPointDTO> goodsResponse = goodsAnalysisMemberBuryPointApiService.queryLastRecommendBuryPoint(goodsAnalysisMemberBuryPointQDTO);
        if (goodsResponse.isSuccess() && goodsResponse.getResult() != null) {
            GoodsAnalysisMemberBuryPointDTO goodsResult = goodsResponse.getResult();
            goodsTime = goodsResult.getLocalTimestamp();
            if (goodsTime == null && materialTime == null) {
                return ServiceResponse.success();
            }
            goodsId = goodsResult.getGoodsId();
            wxaLinkId = goodsResult.getWxaLinkId();
            if (DateUtil.compare(goodsTime, materialTime) > 0) {
                materialBizInfo = new WeekMonthDataAdaptor.MaterialBizInfo(goodsResult.getClerkId(), goodsResult.getWxaLinkId(), goodsResult.getStoreId(), goodsResult.getBizType());
            }
        }


//        MaterialDataAdaptor.MaterialBizInfo materialBizInfo = materialDataAdaptor.queryMaterialBizInfo(enterpriseId, memberId, orderTime, null);
        if (materialBizInfo == null) {
            if (memberOrderBo.getTimes() == null) {
                memberOrderBo.setTimes(1);
            }
            if (memberOrderBo.getTimes() > 5) {
                log.info("订单消费次数已经超出5次, 不再处理 {}", params);
                return ServiceResponse.success();
            }
            memberOrderBo.setTimes(memberOrderBo.getTimes() + 1);
            try {
                log.info("发送微盟订单处理消息 {}", params);
                /**
                 * @see com.gic.haoban.manage.api.service.content.MallOrderStatusChangeApiService#dealWeimoOrder(String)
                 */
                GICMQClientUtil.getClientInstance().sendMessage("dealWeimoOrderForInteractRecord", JSON.toJSONString(memberOrderBo), 120);
            }catch (Exception ex) {
                log.info("处理会员订单异常 ", ex);
            }
            return ServiceResponse.success();
        }
        interactRecordMessageBO.setClerkId(materialBizInfo.getClerkId());
        interactRecordMessageBO.setMaterialId(materialBizInfo.getBizId());
        interactRecordMessageBO.setBizType(materialBizInfo.getBizType());
        interactRecordMessageBO.setEventType(MaterialInteractRecordEventType.ORDER.getCode());
        interactRecordMessageBO.setDurationTime(0);
        interactRecordMessageBO.setLastAccessTime(System.currentTimeMillis());
        interactRecordMessageBO.setOrderNumber(orderNumber);
        interactRecordMessageBO.setOrderId(orderId);
        interactRecordMessageBO.setGoodsId(goodsId);
        interactRecordMessageBO.setWxaLinkId(wxaLinkId);
        if (StringUtils.equalsIgnoreCase(memberOrderBo.getTableName(), KafkaMessageServiceImpl.tab_gic_eorder)) {
            interactRecordMessageBO.setOrderType(2);
        }else {
            interactRecordMessageBO.setOrderType(3);
        }
        interactRecordMessageService.dealRecord(interactRecordMessageBO);

        return ServiceResponse.success();
    }
}
