package com.junmp.jyzb.config.rabbitMQ;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.junmp.jyzb.entity.Cabinet;
import com.junmp.jyzb.entity.PubOrg;
import com.junmp.jyzb.service.CabinetService;
import com.junmp.jyzb.service.PubOrgService;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;

@Configuration
public class TopicRabbitConfig {

    private static final String EXCHANGE = "topicExchange";
    private static final String ORG_ROUTING_KEY_PREFIX = "org";
    private static final String CABINET_ROUTING_KEY_PREFIX = "cabinet";

    @Resource
    private PubOrgService pubOrgService;
    @Resource
    private CabinetService cabinetService;

    @Resource
    private RabbitAdmin rabbitAdmin;


    // Inject the services using constructor injection
    public TopicRabbitConfig() {

    }

    @Bean
    public TopicExchange topicExchange() {
        return new TopicExchange(EXCHANGE);
    }

    // Dynamic creation of queues and bindings for each organization and cabinet
    @Bean
    public List<Binding> createQueuesAndBindings(TopicExchange topicExchange) {
        CompletableFuture<List<PubOrg>> orgListFuture = CompletableFuture.supplyAsync(() ->
                pubOrgService.list(new LambdaQueryWrapper<PubOrg>().eq(PubOrg::getDelFlag, 1)));

        CompletableFuture<List<Cabinet>> cabinetListFuture = CompletableFuture.supplyAsync(() ->
                cabinetService.list());

        List<PubOrg> orgList = orgListFuture.join();
        List<Cabinet> cabinetList = cabinetListFuture.join();
          List<Binding> bindings = new ArrayList<>();

        for (PubOrg org : orgList) {
            // Create a unique queue for each organization
            Queue orgQueue = new Queue(org.getOrgId().toString(),true,false,false);

            // Bind the queue to the exchange with the routing key specific to the organization
            Binding orgBinding = BindingBuilder.bind(orgQueue).to(topicExchange)
                    .with(ORG_ROUTING_KEY_PREFIX);
            rabbitAdmin.declareQueue(orgQueue);
            rabbitAdmin.declareBinding(orgBinding);
            bindings.add(orgBinding);
        }

        for (Cabinet cabinet : cabinetList) {
            // Create a unique queue for each cabinet
            Queue cabinetQueue = new Queue(cabinet.getCabinetNum().toString(),true,false,false);

            // Bind the queue to the exchange with the routing key specific to the cabinet
            Binding cabinetBinding = BindingBuilder.bind(cabinetQueue).to(topicExchange)
                    .with(CABINET_ROUTING_KEY_PREFIX);
            rabbitAdmin.declareQueue(cabinetQueue);
            rabbitAdmin.declareBinding(cabinetBinding);
            bindings.add(cabinetBinding);
        }

        return bindings;
    }
}

