package de.accso.flexinale.besucherportal.infrastructure;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import de.accso.flexinale.besucherportal.api_in.event.*;
import de.accso.flexinale.besucherportal.api_out.event.GutscheinEinloesenBeauftragtPublisher;
import de.accso.flexinale.besucherportal.application.services.*;
import de.accso.flexinale.common.application.Config;
import de.accso.flexinale.common.api.eventbus.EventBusFactory;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;

@Configuration
@Profile({ "!testdata-backoffice & !testdata-ticketing" })
public class FlexinaleBesucherPortalSpringFactory {

    // Backoffice

    // Film
    @Bean
    public FilmService createBesucherPortalFilmService(final FKKsVTInMemoryCache cache,
                                                       final VorfuehrungService vorfuehrungService,
                                                       final Config config) {
        return new FilmService(cache, vorfuehrungService, config.getMinZeitZwischenVorfuehrungenInMinuten());
    }

    @Bean
    public FilmSubscriber createBesucherPortalFilmSubscriber(final EventBusFactory eventBusFactory,
                                                             final FKKsVTInMemoryCache cache,
                                                             final FlexinaleBesucherPortalActuatorEndpointEventsConsumed endpointEventsConsumed) {
        return new FilmSubscriber(eventBusFactory, cache, endpointEventsConsumed);
    }

    // Kino
    @Bean
    public KinoService createBesucherPortalBesucherPortalKinoService(final FKKsVTInMemoryCache cache) {
        return new KinoService(cache);
    }

    @Bean
    public KinoSubscriber createBesucherPortalKinoSubscriber(final EventBusFactory eventBusFactory,
                                                             final FKKsVTInMemoryCache cache,
                                                             final FlexinaleBesucherPortalActuatorEndpointEventsConsumed endpointEventsConsumed) {
        return new KinoSubscriber(eventBusFactory, cache, endpointEventsConsumed);
    }

    // Vorfuehrung
    @Bean
    public VorfuehrungService createBesucherPortalVorfuehrungService() {
        return new VorfuehrungService();
    }

    @Bean
    public VorfuehrungSubscriber createBesucherPortalVorfuehrungSubscriber(final EventBusFactory eventBusFactory,
                                                                           final FKKsVTInMemoryCache cache,
                                                                           final FlexinaleBesucherPortalActuatorEndpointEventsConsumed endpointEventsConsumed) {
        return new VorfuehrungSubscriber(eventBusFactory, cache, endpointEventsConsumed);
    }

    // Ticket
    @Bean
    public TicketSubscriber createBesucherPortalTicketGekauftSubscriber(final EventBusFactory eventBusFactory,
                                                                        final FKKsVTInMemoryCache cache,
                                                                        final FlexinaleBesucherPortalActuatorEndpointEventsConsumed endpointEventsConsumed) {
        return new TicketSubscriber(eventBusFactory, cache, endpointEventsConsumed);
    }

    @Bean
    public TicketService createBesucherPortalTicketService(
            final GutscheinEinloesenBeauftragtPublication gutscheinEinloesenBeauftragtPublisher) {
        return new TicketService(gutscheinEinloesenBeauftragtPublisher);
    }

    @Bean
    public GutscheinEinloesenBeauftragtPublication createBesucherPortalGutscheinEinloesenBeauftragtPublisher(
            final EventBusFactory eventBusFactory,
            final FlexinaleBesucherPortalActuatorEndpointEventsPublished endpointEventsPublished) {
        return new GutscheinEinloesenBeauftragtPublisher(eventBusFactory, endpointEventsPublished);
    }

    // Kontingent
    @Bean
    public KontingentSubscriber createBesucherPortalKontingentSubscriber(final EventBusFactory eventBusFactory,
                                                                         final FKKsVTInMemoryCache cache,
                                                                         final FlexinaleBesucherPortalActuatorEndpointEventsConsumed endpointEventsConsumed) {
        return new KontingentSubscriber(eventBusFactory, cache, endpointEventsConsumed);
    }

    // ------------------------------------------------------------------------------------------------

    // Cache
    @Bean
    public FKKsVTInMemoryCache createBesucherPortalFKKsVTInMemoryCache() {
        return new FKKsVTInMemoryCache();
    }

    // ------------------------------------------------------------------------------------------------

    // Actuator Event serialization
    @Bean
    public Jackson2ObjectMapperBuilderCustomizer jsonBesucherPortalCustomizer() {
        return builder -> builder.visibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);
    }
}
