package com.airlock.iam.admin.infrastructure.factory.shared;

import com.airlock.iam.admin.api.domain.service.user.ManagedUserRepository;
import com.airlock.iam.admin.application.configuration.event.AdminappSmsEventSubscriberConfig;
import com.airlock.iam.admin.domain.model.event.ManagedUserLocaleProvider;
import com.airlock.iam.base.api.infrastructure.plugin.ModuleForConfig;
import com.airlock.iam.base.api.infrastructure.plugin.PluginConfigToLogic;
import com.airlock.iam.base.domain.model.event.SubscribedEvent;
import com.airlock.iam.common.application.configuration.mtan.BasicMtanSettings;
import com.airlock.iam.common.domain.model.encoder.IdentityValueMapEncoder;
import com.airlock.iam.common.domain.model.encoder.ValueMapEncoder;
import com.airlock.iam.common.domain.model.locale.ResourceKey;
import com.airlock.iam.common.domain.model.sms.SmsMessageTemplate;
import com.airlock.iam.common.domain.model.sms.SmsOriginator;
import com.airlock.iam.common.domain.service.event.DomainEventMessageProvider;
import com.airlock.iam.common.domain.service.event.LocaleProvider;
import com.airlock.iam.common.domain.service.sms.DefaultSmsValidator;
import com.airlock.iam.common.domain.service.sms.SmsSendingService;
import com.airlock.iam.common.domain.service.sms.SmsService;
import com.airlock.iam.common.domain.service.sms.SmsService.SmsServiceSettings;
import com.airlock.iam.common.infrastructure.event.DomainEventMessageProviderImpl;
import com.airlock.iam.common.infrastructure.sms.SmsSendingServiceImpl;
import com.airlock.iam.log.api.signing.SigningLogger;
import com.google.inject.Exposed;
import com.google.inject.PrivateModule;
import com.google.inject.Provides;
import jakarta.inject.Provider;

@ModuleForConfig(AdminappSmsEventSubscriberConfig.class)
public final class AdminappSmsEventSubscriberModule extends PrivateModule {
   @Provides
   @Exposed
   SubscribedEvent provideSubscribedEvent(AdminappSmsEventSubscriberConfig config, PluginConfigToLogic toLogic) {
      return (SubscribedEvent)toLogic.getLogic(config.getEvent());
   }

   @Provides
   LocaleProvider provideUserLocale(AdminappSmsEventSubscriberConfig config, Provider<ManagedUserRepository> repository) {
      return ManagedUserLocaleProvider.builder()
         .repository(repository)
         .languageContextDataname(config.getLanguageContextDataName().getContextDataName())
         .defaultLocale(config.getDefaultLocale())
         .build();
   }

   @Provides
   BasicMtanSettings provideMtanSettings(AdminappSmsEventSubscriberConfig config) {
      return config.getSmsSettings();
   }

   @Provides
   @Exposed
   SmsMessageTemplate provideSmsMessageTemplate(AdminappSmsEventSubscriberConfig config) {
      return SmsMessageTemplate.smsMessageTemplate(
         ResourceKey.resourceKey(config.getMessageResourceKey()), SmsOriginator.smsOriginator(config.getSmsSettings().getOriginator())
      );
   }

   @Provides
   SmsServiceSettings smsServiceSettings(BasicMtanSettings config) {
      return SmsServiceSettings.builder()
         .smsGateway(config.getSmsGateway())
         .smsValidator(new DefaultSmsValidator(config.getSmsGateway()))
         .configuredOriginator(config.getOriginator())
         .build();
   }

   @Provides
   @Exposed
   SmsSendingService provideSmsSendingService(BasicMtanSettings config, SmsServiceSettings smsServiceSettings, SigningLogger signingLogger) {
      return SmsSendingServiceImpl.builder()
         .smsService(new SmsService(smsServiceSettings, signingLogger))
         .flashMessageEnabled(config.isUseFlashMessages())
         .defaultCountryCode(config.getDefaultCountryCode())
         .build();
   }

   protected void configure() {
      this.bind(ValueMapEncoder.class).to(IdentityValueMapEncoder.class);
      this.bind(DomainEventMessageProvider.class).to(DomainEventMessageProviderImpl.class);
      this.expose(DomainEventMessageProvider.class);
   }
}
