package com.airlock.iam.common.infrastructure.event;

import com.airlock.iam.base.api.domain.model.event.DomainEvent;
import com.airlock.iam.common.api.domain.model.event.EventData;
import com.airlock.iam.common.api.domain.model.event.UserEvent;
import com.airlock.iam.core.misc.util.config.Config;
import jakarta.inject.Inject;
import jakarta.inject.Provider;
import java.util.Map;

public final class OutboxEventSerializer {
   private final Provider<DomainEventMapper> domainEventMapper;
   private final Provider<CustomEventDataProvider> customDataProvider;

   @Inject
   public OutboxEventSerializer(Provider<DomainEventMapper> domainEventMapper, Provider<CustomEventDataProvider> customDataProvider) {
      this.domainEventMapper = domainEventMapper;
      this.customDataProvider = customDataProvider;
   }

   public EventData.EventPayload serialize(DomainEvent event) {
      return this.baseEventMapping(event)
         .addData(((DomainEventMapper)this.domainEventMapper.get()).toEventPayloadData(event).data())
         .addSource(((DomainEventMapper)this.domainEventMapper.get()).toEventPayloadSource(event.source()).source())
         .addCustomData(((CustomEventDataProvider)this.customDataProvider.get()).provideCustomData(event))
         .build();
   }

   private EventPayloadBuilder baseEventMapping(DomainEvent event) {
      EventPayloadBuilder builder = new EventPayloadBuilder()
         .addEventId(event.id().value())
         .addEventType(event.type().name())
         .addOccurredAt(event.createdAt())
         .addSource(Map.of("application", Config.getAppIdentifier().id()));
      if (event instanceof UserEvent userEvent) {
         builder.addData(Map.of("userId", userEvent.userId().getValue()));
      }

      return builder;
   }
}
