package com.gic.haoban.manage.service.service.content.message;

import com.alibaba.fastjson.JSON;
import com.gic.api.base.commons.ServiceResponse;
import com.gic.content.api.dto.setting.ContentSettingDTO;
import com.gic.content.api.service.ContentSettingApiService;
import com.gic.haoban.manage.api.enums.content.MaterialInteractRecordEventType;
import com.gic.haoban.manage.service.pojo.bo.content.InteractRecordBO;
import com.gic.haoban.manage.service.pojo.bo.content.InteractRecordExtendInfoBO;
import com.gic.haoban.manage.service.pojo.bo.content.PotentialCustomerBO;
import com.gic.haoban.manage.service.pojo.bo.content.PotentialCustomerStaticsBO;
import com.gic.haoban.manage.service.pojo.bo.content.context.InteractRecordMessageContext;
import com.gic.haoban.manage.service.pojo.bo.content.context.PotentialCustomerNotifyContext;
import com.gic.haoban.manage.service.pojo.bo.content.message.InteractRecordMessageBO;
import com.gic.haoban.manage.service.service.content.InteractRecordService;
import com.gic.haoban.manage.service.service.content.PotentialCustomerService;
import com.gic.haoban.manage.service.service.content.adaptor.InteractRecordMessageBuilder;
import com.gic.redis.data.util.RedisUtil;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
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.Objects;
import java.util.Optional;
import java.util.concurrent.TimeUnit;

/**
 * @Author MUSI
 * @Date 2023/3/28 2:50 PM
 * @Description
 * @Version 互动记录消息处理器
 **/
@Slf4j
@Component
public class InteractRecordMessageService {

    @Autowired
    InteractRecordService interactRecordService;
    @Autowired
    InteractRecordMessageBuilder interactRecordMessageBuilder;
    @Autowired
    PotentialCustomerService potentialCustomerService;
    @Autowired
    ContentSettingApiService contentSettingApiService;

    /**
     * 处理互动记录
     *
     * @param interactRecordMessageBO
     */
    public void dealRecord(InteractRecordMessageBO interactRecordMessageBO) {
        log.info("【dealRecord】处理埋点事件 >> {}", JSON.toJSONString(interactRecordMessageBO));
        InteractRecordMessageContext context = InteractRecordMessageContext.create(interactRecordMessageBO);
        // 参数是否完整
        // 根据businessId clerkId memberId materialId 构建唯一标识key
        String recordKey = context.buildRecordKey();
        RedisUtil.lock(recordKey, 3L, TimeUnit.SECONDS, 2L);
        // 根据key 查询是否存在记录
        InteractRecordBO interactRecordBO = null;
        if (MaterialInteractRecordEventType.ORDER.getCode().equals(interactRecordMessageBO.getEventType())) {
            interactRecordBO = this.getInteractRecordBOWithOrderType(interactRecordMessageBO);
            if (interactRecordBO == null) {
                // 订单事件已过滤，理论上此处不会出现
                log.info("下单事件 互动记录为空 {}", JSON.toJSONString(interactRecordMessageBO));
                return;
            }
        } else {
            interactRecordBO = interactRecordService.queryWithInteractInfo(interactRecordMessageBO.getEnterpriseId(), recordKey);
            if (interactRecordBO == null && StringUtils.isNotBlank(context.getInteractRecordMessageBO().getMemberId())) {
                // 通过unionId 再获取一下
                interactRecordBO = interactRecordService.queryWithInteractInfo(interactRecordMessageBO.getEnterpriseId(), context.buildRecordKeyWithUnionId());
            }
        }
        try {
            if (interactRecordBO == null) {
                if (interactRecordMessageBO.getChannelSource() == null
                    || Objects.isNull(interactRecordMessageBO.getEventType())
                        || StringUtils.isBlank(interactRecordMessageBO.getClerkId())) {
                    log.error("互动记录参数异常: {}", JSON.toJSONString(interactRecordMessageBO));
                    return;
                }
                // 新增
                // 冗余会员信息
                interactRecordMessageBuilder.redundantMemberInfo(context);
                // 查询会员是否有过成交 （是否存在订单）
                interactRecordMessageBuilder.calcHaveOrderNum(context);
                // 计算访问次数
                interactRecordMessageBuilder.calcCustomerVisitTimes(context);
                interactRecordBO = context.build();
            } else {
                // 该key已存在 需要对之前的进行合并
                // 修改访问类型
                interactRecordBO.setUpdateTime(new Date());
                Integer durationTime = Optional.ofNullable(interactRecordBO.getDurationTime()).orElse(0);
                interactRecordBO.setDurationTime(durationTime + Optional.ofNullable(interactRecordMessageBO.getDurationTime()).map(item -> item / 1000).orElse(0));
                // 事件类型
                if (interactRecordBO.getEventType() < interactRecordMessageBO.getEventType()) {
                    interactRecordBO.setEventType(interactRecordMessageBO.getEventType());
                }
                if (MaterialInteractRecordEventType.ORDER.getCode().equals(interactRecordMessageBO.getEventType())) {
                    interactRecordBO.setEventType(interactRecordMessageBO.getEventType());
                }
            }
            // 更新互动记录的最新访问时间
            if (interactRecordBO.getLastAccessTime().before(new Date(interactRecordMessageBO.getLastAccessTime()))) {
                interactRecordBO.setLastAccessTime(new Date(interactRecordMessageBO.getLastAccessTime()));
            }

            if (!MaterialInteractRecordEventType.VISIT_MATERIAL.getCode().equals(interactRecordMessageBO.getEventType())
                    && null == interactRecordBO.getExtendInfo()) {
                log.info("非素材浏览事件,初始化扩展字段");
                interactRecordBO.setExtendInfo(InteractRecordExtendInfoBO.empty());
            }
            // 组装扩展信息
            if (MaterialInteractRecordEventType.VISIT_PRODUCT.getCode()
                    .equals(interactRecordMessageBO.getEventType())
                    || MaterialInteractRecordEventType.ADD_SHOPPING_CART.getCode().equals(interactRecordBO.getEventType())) {
                // 浏览商品
                if (StringUtils.isNotBlank(interactRecordMessageBO.getGoodsId())
                        && !interactRecordBO.getExtendInfo()
                        .getGoodsIds().contains(interactRecordMessageBO.getGoodsId())) {
                    interactRecordBO.getExtendInfo().getGoodsIds()
                            .add(interactRecordMessageBO.getGoodsId());
                }
            }

            if (MaterialInteractRecordEventType.ORDER.getCode().equals(interactRecordMessageBO.getEventType())) {
                // 下单
                // 查询订单信息
                String enterpriseId = context.getInteractRecordMessageBO().getEnterpriseId();
                String orderNumber = context.getInteractRecordMessageBO().getOrderNumber();
                String orderId = context.getInteractRecordMessageBO().getOrderId();
                String memberId = context.getInteractRecordMessageBO().getMemberId();
                InteractRecordExtendInfoBO.ExtendOrderInfo extendOrderInfo = interactRecordMessageBuilder.buildMaterialOrderItemInfo(enterpriseId, orderNumber,
                        memberId, orderId, interactRecordMessageBO.getOrderType());
                if (extendOrderInfo != null) {
                    interactRecordBO.getExtendInfo().getExtendOrderInfos().add(extendOrderInfo);
                }
            }
            interactRecordService.saveOrUpdateInteractRecord(interactRecordBO);
            // 更新销售线索
            if (StringUtils.isNotBlank(interactRecordMessageBO.getMemberId())) {

                // 查询销售线索
                PotentialCustomerBO potentialCustomerBO = potentialCustomerService.queryPotentialCustomerInfo(interactRecordMessageBO.getClerkId(), interactRecordMessageBO.getMemberId());
                if (potentialCustomerBO == null) {
                    potentialCustomerBO = context.buildPotentialCustomerBo(interactRecordBO);
                }
                // 最近访问时间
                if (potentialCustomerBO.getLastAccessTime().before(new Date(interactRecordMessageBO.getLastAccessTime()))) {
                    potentialCustomerBO.setLastAccessTime(new Date(interactRecordMessageBO.getLastAccessTime()));
                }
                // 标记为未读
                potentialCustomerBO.setSeeFlag(0);
                potentialCustomerBO.setStoreId(interactRecordBO.getStoreId());
                potentialCustomerBO.setBizId(interactRecordBO.getBizId());
                potentialCustomerBO.setBizType(interactRecordBO.getBizType());
                potentialCustomerBO.setEventType(interactRecordBO.getEventType());
                potentialCustomerBO.setChannelSource(interactRecordBO.getChannelSource());
                potentialCustomerBO.setDurationTime(interactRecordBO.getDurationTime());
                potentialCustomerBO.setTimes(interactRecordBO.getTimes());
                potentialCustomerService.saveOrUpdatePotentialCustomer(potentialCustomerBO);
            }
            ServiceResponse<ContentSettingDTO> response = contentSettingApiService.queryContentSettingInfo(interactRecordMessageBO.getEnterpriseId());
            if (response.isSuccess() && response.getResult() != null) {
                Integer potentialNotifyInterval = response.getResult().getPotentialNotifyInterval();
                if (potentialNotifyInterval != null && potentialNotifyInterval <= 0) {
                    PotentialCustomerNotifyContext notifyContext = PotentialCustomerNotifyContext.builder()
                            .enterpriseId(interactRecordMessageBO.getEnterpriseId())
                            .customerStaticsBos(Lists.newArrayList(new PotentialCustomerStaticsBO(interactRecordBO.getClerkId(), 1)))
                            .build();
                    potentialCustomerService.sendPotentialCustomerNotice(notifyContext);
                }
            }
        }finally {
            RedisUtil.unlock(recordKey);
        }
    }

    /**
      查询订单事件的互动记录
     * @param interactRecordMessageBO
     * @return
     */
    public InteractRecordBO getInteractRecordBOWithOrderType(InteractRecordMessageBO interactRecordMessageBO) {
        InteractRecordBO interactRecordBO = null;
        String bizId = interactRecordMessageBO.getMaterialId();
        if (StringUtils.isBlank(bizId)) {
            bizId = interactRecordMessageBO.getGoodsId();
        }

        interactRecordBO = interactRecordService.queryLeastRecord(interactRecordMessageBO.getEnterpriseId(), interactRecordMessageBO.getClerkId(),
                bizId, interactRecordMessageBO.getMemberId());
        return interactRecordBO;
    }
}
