package com.quantgroup.asset.distribution.config.rabbitmq;

import cn.quantgroup.tech.brave.service.ITechRabbitBuilder;
import com.alibaba.fastjson.JSONObject;
import com.google.common.base.Stopwatch;
import com.quantgroup.asset.distribution.enums.funding.FundingResult;
import com.quantgroup.asset.distribution.service.distribute.IAssetDistributeService;
import com.quantgroup.asset.distribution.service.funding.IAidFundRouteRecordService;
import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.AcknowledgeMode;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.*;
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.listener.RabbitListenerEndpointRegistrar;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.converter.MappingJackson2MessageConverter;
import org.springframework.messaging.handler.annotation.support.DefaultMessageHandlerMethodFactory;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.concurrent.TimeUnit;

@Slf4j
@Configuration
@EnableRabbit
public class ConsumerConfig implements RabbitListenerConfigurer {



    @Autowired
    private IAidFundRouteRecordService iAidFundRouteRecordService;
    @Autowired
    private IAssetDistributeService distributeService;

    @Resource
    private ITechRabbitBuilder techRabbitBuilder;

    @Bean
    public DefaultMessageHandlerMethodFactory myHandlerMethodFactory() {
        DefaultMessageHandlerMethodFactory factory = new DefaultMessageHandlerMethodFactory();
        factory.setMessageConverter(new MappingJackson2MessageConverter());
        return factory;
    }

    @Bean(name="rabbitListenerContainerFactory")
    public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory(@Qualifier("assetDistributionConnectionFactory")CachingConnectionFactory assetDistributionConnectionFactory) {
        SimpleRabbitListenerContainerFactory factory = techRabbitBuilder.createSimpleRabbitListenerContainerFactory(assetDistributionConnectionFactory);
        factory.setPrefetchCount(100);
        factory.setAcknowledgeMode(AcknowledgeMode.MANUAL);
        return factory;
    }

    @Override
    public void configureRabbitListeners(RabbitListenerEndpointRegistrar registrar) {
        registrar.setMessageHandlerMethodFactory(myHandlerMethodFactory());
    }



    @RabbitListener(bindings = {@QueueBinding(value = @Queue(value = "funding.state"), exchange = @Exchange(value = "quota"))})
    public void process(Message message, Channel channel) throws IOException {
        String ms = null;
        try{
            Stopwatch stopwatch = Stopwatch.createStarted();
            ms = new String(message.getBody(), "utf-8");
            JSONObject jo = JSONObject.parseObject(ms);
            String noticeType = jo.getString("noticeType");
            if(FundingResult.REJECT.getCode().equals(noticeType)
                    || FundingResult.HANG_UP.getCode().equals(noticeType)
                    || FundingResult.CANCEL_LOAN.getCode().equals(noticeType)
                    || FundingResult.FUAD_ASSIGN_SUCC.getCode().equals(noticeType)){
                log.info("资金路由有效MQ消息接收, 消息内容 : {} ",ms);
                String applyNo = jo.getJSONObject("data").getString("applyNo");
                String nextOperateDate = getNextOperateDate(jo, noticeType);
//                iAidFundRouteRecordService.fundingResultNotity(applyNo,FundingResult.fromCode(noticeType));
                distributeService.receiveFundingResult(applyNo, FundingResult.fromCode(noticeType), nextOperateDate);
                log.info("资金路由有效MQ消息处理结束, bizNo : {} ,noticeType : {} , 耗时 : {} ",applyNo,noticeType,stopwatch.stop().elapsed(TimeUnit.MILLISECONDS));
            }
            // 采用手动应答模式, 手动确认应答更为安全稳定
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), true);

        }catch(IOException e){
            log.error("资金路由结果消息处理异常,消息 : {} ",ms,e);
            //害怕队列堵住  暂放开
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), true);

            //重新放回队列
//            channel.basicNack(message.getMessageProperties().getDeliveryTag(),false,true);
        }


    }
    
    /**
     * 获取下次可操作之间, 只有拒绝才有
     * @param jo
     * @return
     */
    private String getNextOperateDate(JSONObject jo, String noticeType) {
    	try {
			if (FundingResult.REJECT.getCode().equals(noticeType)) {
				return jo.getJSONObject("extraData").getString("nextOperateDate");
			}
			return null;
		} catch (Exception e) {
			log.error("资金路由结果消息解析下次可操作时间异常!", e);
			return null;
		}
    }
}

