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

import com.airlock.iam.base.api.infrastructure.plugin.ModuleForConfig;
import com.airlock.iam.base.misc.time.TimeProvider;
import com.airlock.iam.common.api.domain.model.user.CurrentLocale;
import com.airlock.iam.common.domain.model.otp.OneTimePasswordFactory;
import com.airlock.iam.common.domain.model.otp.OneTimePasswordFactoryImpl;
import com.airlock.iam.common.domain.service.email.EmailSenderService;
import com.airlock.iam.common.domain.service.email.EmailSenderServiceImpl;
import com.airlock.iam.core.misc.impl.authen.StringResourceProvider;
import com.airlock.iam.flow.api.domain.model.session.FlowSession;
import com.airlock.iam.flow.infrastructure.step.StepSessionModuleHelper;
import com.airlock.iam.publicselfservice.application.configuration.steps.EmailIdentityVerificationStepConfig;
import com.airlock.iam.publicselfservice.domain.model.flow.session.OtpIdentityVerificationStepSession;
import com.airlock.iam.publicselfservice.domain.model.step.EmailIdentityVerificationStepSettings;
import com.google.inject.Exposed;
import com.google.inject.PrivateModule;
import com.google.inject.Provides;
import java.util.Locale;

@ModuleForConfig(EmailIdentityVerificationStepConfig.class)
public final class EmailIdentityVerificationStepModule extends PrivateModule {
   @Exposed
   @Provides
   EmailSenderService provideEmailSenderService(EmailIdentityVerificationStepConfig config, StringResourceProvider stringResourceProvider) {
      return EmailSenderServiceImpl.builder()
         .bodyResourceKey(config.getBodyResourceKey())
         .subjectResourceKey(config.getSubjectResourceKey())
         .emailService(config.getEmailService())
         .sendAsHtml(config.isSendAsHtml())
         .htmlEscapingEnabled(config.isEscapeHtmlValues())
         .stringResourceProvider(stringResourceProvider)
         .build();
   }

   @Exposed
   @Provides
   Locale provideLocale(CurrentLocale currentLocale) {
      return currentLocale.get();
   }

   @Exposed
   @Provides
   OneTimePasswordFactory provideOneTimePasswordFactory(EmailIdentityVerificationStepConfig config, TimeProvider timeProvider) {
      return new OneTimePasswordFactoryImpl(config::getOtpGenerator, config::getOtpValidty, timeProvider);
   }

   @Exposed
   @Provides
   EmailIdentityVerificationStepSettings provideEmailIdentityVerificationStepSettings(EmailIdentityVerificationStepConfig config) {
      return new EmailIdentityVerificationStepSettings(
         config.getEmailContextData(), config.getMaxFailedAttempts(), config.getOtpValidty(), config.isOtpCaseSensitive(), config.getAuthenticationMethodId()
      );
   }

   @Exposed
   @Provides
   OtpIdentityVerificationStepSession provideEmailIdentityVerificationStepSession(FlowSession flowSession) {
      return StepSessionModuleHelper.retrieveStepSession(flowSession, OtpIdentityVerificationStepSession.class);
   }

   protected void configure() {
   }
}
