package com.mortals.xhx.base.framework.config;

import com.mortals.xhx.common.key.QueueKey;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.DirectExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.rabbit.AsyncRabbitTemplate;
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.boot.autoconfigure.amqp.SimpleRabbitListenerContainerFactoryConfigurer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;

@Configuration
public class RabbitConfig {
    public Integer messageTtl = 86400000;
    public Map<String, Object> args = new HashMap<>();

    // 创建 Queue
    @Bean
    public Queue accessLogQueue() {
        args.put("x-message-ttl", messageTtl);
        return new Queue(QueueKey.ACCESS_LOG_QUEUE, // Queue 名字
                true, // durable: 是否持久化
                false, // exclusive: 是否排它
                false,
                args); // autoDelete: 是否自动删除
    }

    @Bean
    public Queue bizLogQueue() {
        args.put("x-message-ttl", messageTtl);
        return new Queue(QueueKey.BIZ_LOG_QUEUE, // Queue 名字
                true, // durable: 是否持久化
                false, // exclusive: 是否排它
                false, args); // autoDelete: 是否自动删除
    }


    @Bean
    public Queue errorLogQueue() {
        return new Queue(QueueKey.ERROR_LOG_QUEUE, // Queue 名字
                true, // durable: 是否持久化
                false, // exclusive: 是否排它
                false, args); // autoDelete: 是否自动删除
    }

    @Bean
    public Queue operationLogQueue() {
        return new Queue(QueueKey.OPERATION_LOG_QUEUE, // Queue 名字
                true, // durable: 是否持久化
                false, // exclusive: 是否排它
                false, args); // autoDelete: 是否自动删除
    }


    // 创建 Direct Exchange
    @Bean
    public DirectExchange exchange() {
        return new DirectExchange(QueueKey.EXCHANGE,
                true,  // durable: 是否持久化
                false);  // exclusive: 是否排它
    }

    // 创建 Binding
    @Bean
    public Binding accessBinding() {
        return BindingBuilder.bind(accessLogQueue()).to(exchange()).with(QueueKey.ACCESS_LOG_QUEUE);
    }

    @Bean
    public Binding bizBinding() {
        return BindingBuilder.bind(bizLogQueue()).to(exchange()).with(QueueKey.BIZ_LOG_QUEUE);
    }

    @Bean
    public Binding errorBinding() {
        return BindingBuilder.bind(errorLogQueue()).to(exchange()).with(QueueKey.ERROR_LOG_QUEUE);
    }

    @Bean
    public Binding operBinding() {
        return BindingBuilder.bind(operationLogQueue()).to(exchange()).with(QueueKey.OPERATION_LOG_QUEUE);
    }


    @Bean(name = "consumerBatchContainerFactory")
    public SimpleRabbitListenerContainerFactory consumerBatchContainerFactory(
            SimpleRabbitListenerContainerFactoryConfigurer configurer, ConnectionFactory connectionFactory) {
        // 创建 SimpleRabbitListenerContainerFactory 对象
        SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();

        factory.setAfterReceivePostProcessors(m -> {
                    m.getMessageProperties().setContentType("application/json");
                    return m;
                });

        configurer.configure(factory, connectionFactory);
        // 额外添加批量消费的属性
        factory.setBatchListener(true);
        factory.setBatchSize(10);
        factory.setReceiveTimeout(5 * 1000L);
        factory.setConsumerBatchEnabled(true);
        return factory;
    }

    //修改系列和与反序列化转换器
    @Bean
    public MessageConverter messageConverter() {
        return new Jackson2JsonMessageConverter();
    }


   // @Bean
    public AsyncRabbitTemplate asyncRabbitTemplate(RabbitTemplate rabbitTemplate) {
        AsyncRabbitTemplate asyncRabbitTemplate = new AsyncRabbitTemplate(rabbitTemplate);
        asyncRabbitTemplate.setReceiveTimeout(10000);
        return asyncRabbitTemplate;
    }

}
