package com.prolog.cs.base.gsp.service.impl.mq;

import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson.JSONObject;
import com.prolog.cs.base.gsp.service.GspUpkeepCheckService;
import com.prolog.cs.base.gsp.service.MqGspConsumer;
import com.prolog.cs.base.gsp.service.MqGspProducer;
import com.prolog.entity.vo.OutboundTaskCallbackItemVO;
import com.prolog.entity.vo.OutboundTaskCallbackVO;
import com.prolog.framework.core.exception.BizException;
import com.prolog.upcloud.base.wh.operate.model.EisLog;
import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

import static com.prolog.constant.EisBusinessConstant.EIS;
import static com.prolog.constant.EisInterfaceConstant.OUTBOUND_TASK_CALLBACK;
import static com.prolog.constant.RabbitMqConstant.*;

@Slf4j
@Component
public class RabbitMqGspConsumerImpl implements MqGspConsumer {

    @Resource
    private MqGspProducer producer;

    @Resource
    private GspUpkeepCheckService gspUpkeepCheckService;


    @Override
    @RabbitListener(bindings = @QueueBinding(exchange = @Exchange(EIS2WMS_GSP_TASK_CALLBACK_EXCHANGE), key = EIS2WMS_GSP_TASK_CALLBACK_ROUTING_KEY, value = @Queue(EIS2WMS_GSP_TASK_CALLBACK_QUEUE)))
    public void gspTaskCallback(Message message, Channel channel) {
        final String params = new String(message.getBody());
        handleAndSaveLog(() -> {
            OutboundTaskCallbackVO vo = JSONObject.parseObject(params, OutboundTaskCallbackVO.class);
            List<String> ids = vo.getSubList().stream().map(OutboundTaskCallbackItemVO::getTaskLineId).distinct().collect(Collectors.toList());
            Assert.notEmpty(ids, "任务行号不能为空");
            gspUpkeepCheckService.callbackPushTask(ids);
        }, params, OUTBOUND_TASK_CALLBACK);
    }

    public void handleAndSaveLog(WmsHandleFunctional func, String params, String url) {
        EisLog eisLog = new EisLog();
        eisLog.setId(IdUtil.fastSimpleUUID());
        eisLog.setInitiator(EIS);
        eisLog.setStatus(1);
        eisLog.setUrl(url);
        eisLog.setRequest(params);
        eisLog.setGmtCreate(new Date());
        try {
            func.accept();
        } catch (Exception e) {
            eisLog.setStatus(2);
            eisLog.setGmtModified(new Date());
            eisLog.setResponse(e.getMessage());
            producer.saveEisLog(eisLog);
            log.error("", e);
            return;
        }
        eisLog.setResponse("接收请求成功");
        eisLog.setGmtModified(new Date());
        producer.saveEisLog(eisLog);
    }

    @FunctionalInterface
    public interface WmsHandleFunctional {
        void accept() throws BizException;
    }

}
