package com.airlock.iam.flow.shared.domain.model.airlock2fa;

import com.airlock.iam.base.api.domain.model.plugin.LogicForConfig;
import com.airlock.iam.base.api.domain.model.user.UserId;
import com.airlock.iam.base.misc.log.LogUtil;
import com.airlock.iam.elog.api.ELogger;
import com.airlock.iam.elog.api.ELoggerFactory;
import com.airlock.iam.factor.domain.model.airlock2fa.Airlock2FAUser;
import com.airlock.iam.factor.domain.model.airlock2fa.order.Airlock2FAActivationLetterOrder;
import com.airlock.iam.factor.domain.model.airlock2fa.order.Airlock2FAActivationLetterOrderCreator;
import com.airlock.iam.factor.domain.service.airlock2fa.activation.Airlock2FAActivationLetterOrderService;
import com.airlock.iam.flow.api.domain.model.step.FlowStep;
import com.airlock.iam.flow.api.domain.model.step.GenericStepError;
import com.airlock.iam.flow.api.domain.model.step.StepResult;
import com.airlock.iam.flow.shared.application.configuration.airlock2fa.Airlock2FALetterOrderStepConfig;
import com.airlock.iam.log.api.helpdesk.HelpdeskLogger;
import com.airlock.iam.log.api.signing.SigningLogger;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import jakarta.inject.Inject;
import java.util.Optional;

@LogicForConfig(Airlock2FALetterOrderStepConfig.class)
public class Airlock2FALetterOrderStep implements FlowStep {
   private static final ELogger LOG = ELoggerFactory.getLogger(Airlock2FALetterOrderStep.class);
   private final Optional<Airlock2FAActivationLetterOrderService> activationOrderService;
   private final Optional<Airlock2FAUser> user;
   private final SigningLogger signingLogger;
   private final HelpdeskLogger helpdeskLogger;

   @Inject
   public Airlock2FALetterOrderStep(
      Optional<Airlock2FAActivationLetterOrderService> activationOrderService,
      Optional<Airlock2FAUser> user,
      SigningLogger signingLogger,
      HelpdeskLogger helpdeskLogger
   ) {
      this.activationOrderService = activationOrderService;
      this.user = user;
      this.signingLogger = signingLogger;
      this.helpdeskLogger = helpdeskLogger;
   }

   @Override
   public StepResult initialize() {
      if (this.activationOrderService.isEmpty()) {
         LOG.info("Can't create activation letter order because no activation letter order configuration is present");
         return this.stepResultFactory().fail(GenericStepError.UNEXPECTED_CALL).build();
      }

      if (this.user.isEmpty()) {
         LOG.info("Can't create activation letter order because no 2FA user is associated with the executed step");
         return this.stepResultFactory().fail(GenericStepError.NO_VALID_TOKEN).build();
      }

      UserId iamUserId = this.user.get().getIamUserId();
      Airlock2FAActivationLetterOrderCreator creator = Airlock2FAActivationLetterOrderCreator.orderCreator(iamUserId);
      Optional<Airlock2FAActivationLetterOrder> order = this.activationOrderService.get().createOrder(this.user.get().getAccountId(), creator);
      if (order.isPresent()) {
         this.signingLogger
            .log(
               "User %s ordered an Airlock 2FA activation letter, which was created with ID %s",
               new Object[]{LogUtil.quote(iamUserId), LogUtil.quote(order.get().getId())}
            );
         this.helpdeskLogger.log(iamUserId, "Ordered an Airlock 2FA activation letter, which got the ID %s", new Object[]{LogUtil.quote(order.get().getId())});
      } else {
         this.signingLogger
            .log("User %s tried to order an Airlock 2FA activation letter, but a letter has already been ordered.", new Object[]{LogUtil.quote(iamUserId)});
         this.helpdeskLogger.log(iamUserId, "Tried to order an Airlock 2FA activation letter, but a letter has already been ordered");
      }

      return this.stepResultFactory().success().build();
   }

   @Override
   public String getDescription() {
      return "Airlock 2FA Non Interactive Letter Order Step";
   }

   @SuppressFBWarnings(justification = "generated code")
   public static Airlock2FALetterOrderStep.Airlock2FALetterOrderStepBuilder builder() {
      return new Airlock2FALetterOrderStep.Airlock2FALetterOrderStepBuilder();
   }

   @SuppressFBWarnings(justification = "generated code")
   public static class Airlock2FALetterOrderStepBuilder {
      @SuppressFBWarnings(justification = "generated code")
      private Optional<Airlock2FAActivationLetterOrderService> activationOrderService;
      @SuppressFBWarnings(justification = "generated code")
      private Optional<Airlock2FAUser> user;
      @SuppressFBWarnings(justification = "generated code")
      private SigningLogger signingLogger;
      @SuppressFBWarnings(justification = "generated code")
      private HelpdeskLogger helpdeskLogger;

      @SuppressFBWarnings(justification = "generated code")
      Airlock2FALetterOrderStepBuilder() {
      }

      @SuppressFBWarnings(justification = "generated code")
      public Airlock2FALetterOrderStep.Airlock2FALetterOrderStepBuilder activationOrderService(
         Optional<Airlock2FAActivationLetterOrderService> activationOrderService
      ) {
         this.activationOrderService = activationOrderService;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public Airlock2FALetterOrderStep.Airlock2FALetterOrderStepBuilder user(Optional<Airlock2FAUser> user) {
         this.user = user;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public Airlock2FALetterOrderStep.Airlock2FALetterOrderStepBuilder signingLogger(SigningLogger signingLogger) {
         this.signingLogger = signingLogger;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public Airlock2FALetterOrderStep.Airlock2FALetterOrderStepBuilder helpdeskLogger(HelpdeskLogger helpdeskLogger) {
         this.helpdeskLogger = helpdeskLogger;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public Airlock2FALetterOrderStep build() {
         return new Airlock2FALetterOrderStep(this.activationOrderService, this.user, this.signingLogger, this.helpdeskLogger);
      }

      @SuppressFBWarnings(justification = "generated code")
      @Override
      public String toString() {
         return "Airlock2FALetterOrderStep.Airlock2FALetterOrderStepBuilder(activationOrderService="
            + this.activationOrderService
            + ", user="
            + this.user
            + ", signingLogger="
            + this.signingLogger
            + ", helpdeskLogger="
            + this.helpdeskLogger
            + ")";
      }
   }
}
