package com.persagy.dmp.rwd.handler;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.persagy.dmp.amqp.handler.AbstractRabbitHandlerTemplate;
import com.persagy.dmp.basic.constant.DigitalMessageConstant;
import com.persagy.dmp.basic.model.DigitalManageMessage;
import com.persagy.dmp.basic.utils.JsonNodeUtils;
import com.persagy.dmp.common.constant.CommonConstant;
import com.persagy.dmp.common.context.AppContext;
import com.persagy.dmp.digital.entity.ObjectDigital;
import com.persagy.dmp.mybatis.helper.DynamicDataSourceHelper;
import com.persagy.dmp.rwd.qrcode.service.impl.QrCodeServiceImpl;
import com.persagy.dmp.rwd.version.service.IObjectDigitalHistoryService;
import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;

/**
 * 物理世界对象消息处理
 * @author:linhuili
 * @date:2021/11/23
 */
@Slf4j
@Component
@RabbitListener(queues = DigitalMessageConstant.MESSAGE_DIGITAL_OBJECT_QUEUE)
public class DigitalObjectMessageHandler extends AbstractRabbitHandlerTemplate {

    @Autowired
    private ObjectMapper objectMapper;

    @Autowired
    private QrCodeServiceImpl qrCodeService;

    @Autowired
    private IObjectDigitalHistoryService objectDigitalHisService;

    /**
     * 物理世界对象：消息监听处理
     * @param message 消息体字符串
     * @param channel 通道对象
     * @param vo     消息对象
     */
    @Override
    protected void handler(String message, Channel channel, Message vo) {
        try {
            //接收对象消息
            DigitalManageMessage messageVO = objectMapper.readValue(message, DigitalManageMessage.class);
            ObjectNode newObj = messageVO.getNewObj();
            ObjectNode oldObj = messageVO.getOldObj();
            if(newObj == null || StrUtil.isEmpty(messageVO.getOperatorType()) || StrUtil.isEmpty(messageVO.getOperatorObj())){
                log.info("对象消息格式有误：{}"+ messageVO);
                return;
            }
            if(!ObjectDigital.class.getSimpleName().equals(messageVO.getOperatorObj())){
                return;
            }
            log.info("处理对象消息：{}", newObj);
            //处理物理世界对象数据
            handleDigitalObjectMessage(messageVO,newObj,oldObj);
        }catch (Exception e){
          log.info("物理世界对象消息处理失败：{} "+e.getMessage());
        }
    }

    /**
     * 处理物理世界对象消息
     * @param messageVO
     * @param newObj
     * @param oldObj
     * @throws Exception
     */
    private void handleDigitalObjectMessage(DigitalManageMessage messageVO, ObjectNode newObj,ObjectNode oldObj) throws Exception{
        ObjectDigital objectDigitalVO = JsonNodeUtils.toEntity(newObj, ObjectDigital.class, ObjectDigital.EXTRA_COLUMN);
        //获取基本参数
        String groupCode = newObj.get("groupCode").textValue();
        String projectId = newObj.get("projectId").textValue();
        //初始化数据源
        initContextInfo(groupCode,projectId,null,null);
        //处理物理世界对象消息
        if(DigitalMessageConstant.OPERATE_AFTER_INSERT.equals(messageVO.getOperatorType())){
            //创建二维码信息
            List<ObjectDigital> objectDigitalList = qrCodeService.createObjectQrCode(groupCode, projectId, newObj);
            if(CollUtil.isNotEmpty(objectDigitalList)){
                //记录对象新增操作
                objectDigitalHisService.insert(objectDigitalList.get(0));
            }
        }
        if(DigitalMessageConstant.OPERATE_AFTER_UPDATE.equals(messageVO.getOperatorType())){
            //校验对象是否进行修改
            Boolean isUpdate = checkIsUpdate(newObj, oldObj);
            if(!isUpdate){
              //对象无任何修改信息
                return;
            }
            //记录对象修改操作
            objectDigitalHisService.update(objectDigitalVO);
        }
        if(DigitalMessageConstant.OPERATE_AFTER_DELETE.equals(messageVO.getOperatorType())){
            //删除对象二维码
            qrCodeService.removeQrCodePic(groupCode,projectId,newObj);
            //记录对象删除操作
            objectDigitalHisService.update(objectDigitalVO);
        }
    }

    /**
     * 校验对象是否进行内容修改
     * @param newObj
     * @param oldObj
     * @return
     */
    private Boolean checkIsUpdate(ObjectNode newObj,ObjectNode oldObj){
        if(newObj == null || oldObj == null){
            return true;
        }
        newObj.remove("modifiedTime");
        oldObj.remove("modifiedTime");
        if(newObj.equals(oldObj)){
            return false;
        }
        return true;
    }
    
    /**
     * 初始化上下文，切换数据源
     * @param groupCode
     * @param projectId
     * @param appId
     * @param userId
     */
    private void initContextInfo(String groupCode,String projectId,String appId,String userId) {
        AppContext.getContext().setGroupCode(groupCode);
        AppContext.getContext().setProjectId(projectId);
        AppContext.getContext().setAppId(appId);
        // 无用户时，默认为默认系统用户
        if(StrUtil.isBlank(userId)) {
            userId = CommonConstant.DEFAULT_ID;
        }
        AppContext.getContext().setAccountId(userId);
        DynamicDataSourceHelper.loadDataSource();
    }

}
