package de.accso.flexinale.ticketing.api_out.event;

import de.accso.flexinale.common.api.eventbus.EventBus;
import de.accso.flexinale.common.api.eventbus.EventBusFactory;
import de.accso.flexinale.common.api.eventbus.EventNotification;
import de.accso.flexinale.common.api.eventbus.EventPublisher;
import de.accso.flexinale.common.api.event.EventContext;
import de.accso.flexinale.ticketing.api_contract.event.OnlineKontingentChangedEvent;
import de.accso.flexinale.ticketing.api_contract.event.model.OnlineKontingentTO;
import de.accso.flexinale.ticketing.application.services.OnlineKontingentChangedPublication;
import de.accso.flexinale.ticketing.domain.model.Kontingent;

import java.util.List;

import static de.accso.flexinale.common.shared_kernel.RawWrapper.getRawOrNull;

public class OnlineKontingentChangedPublisher implements EventPublisher<OnlineKontingentChangedEvent>, OnlineKontingentChangedPublication {
    private final EventBus<OnlineKontingentChangedEvent> onlineKontingentChangedEventEventBus;
    private final EventNotification notification;

    public OnlineKontingentChangedPublisher(final EventBusFactory eventBusFactory,
                                            final EventNotification notification) {
        this.onlineKontingentChangedEventEventBus = eventBusFactory.createOrGetEventBusFor(OnlineKontingentChangedEvent.class);
        this.notification = notification;
    }

    @Override
    public void publishOnlineKontingentChanged(final List<Kontingent> kontingente) {
        EventContext predecessorEventContext = onlineKontingentChangedEventEventBus.getEventContextHolder().get();

        kontingente.forEach(kontingent -> {
            OnlineKontingentTO onlineKontingentTO =
                    new OnlineKontingentTO(kontingent.id, kontingent.version,
                            kontingent.getVorfuehrungId(),
                            new OnlineKontingentTO.RestKontingent(getRawOrNull(kontingent.getRestKontingentOnline())));

            post(OnlineKontingentChangedEvent.class,
                    (predecessorEventContext == null)
                            ? new OnlineKontingentChangedEvent(onlineKontingentTO)
                            : new OnlineKontingentChangedEvent(predecessorEventContext, onlineKontingentTO)
            );
        });
    }

    @Override
    public String getName() {
        return OnlineKontingentChangedPublisher.class.getName();
    }

    @Override
    public void post(final Class<OnlineKontingentChangedEvent> eventType, final OnlineKontingentChangedEvent event) {
        this.onlineKontingentChangedEventEventBus.publish(OnlineKontingentChangedEvent.class, event);
        this.notification.notify(event);
    }
}
