package com.airlock.iam.common.domain.service.sms;

import com.airlock.iam.base.api.domain.model.exception.FailureException;
import com.airlock.iam.base.api.domain.model.exception.ViolationException;
import com.airlock.iam.common.api.domain.model.otp.Otp;
import com.airlock.iam.common.api.domain.model.user.CurrentLocale;
import com.airlock.iam.common.domain.model.sms.Sms;
import com.airlock.iam.core.domain.model.phone.CountryCallingCode;
import com.airlock.iam.core.misc.format.FormatterException;
import com.airlock.iam.core.misc.impl.authen.mtan.SmsMessageInterpolator;
import com.airlock.iam.core.misc.impl.token.MtanItem;
import com.airlock.iam.core.misc.util.phone.PhoneUtils;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import jakarta.inject.Inject;
import java.text.ParseException;
import lombok.NonNull;

public class MtanSmsFactory {
   private final MtanSmsFactory.MtanSmsFactorySettings settings;
   private final CurrentLocale currentLocale;

   @Inject
   public MtanSmsFactory(MtanSmsFactory.MtanSmsFactorySettings settings, CurrentLocale currentLocale) {
      this.settings = settings;
      this.currentLocale = currentLocale;
   }

   public Sms createSmsFor(Otp mtanOtp, String phoneNumber, String message) {
      return this.createSmsFor(phoneNumber, this.message(mtanOtp, message), this.settings.isFlashMessageEnabled());
   }

   public Sms createSmsFor(Otp mtanOtp, MtanItem mtanItem, String messageTemplate) {
      return this.createSmsFor(mtanItem.getMobilePhoneNumber(), this.message(mtanOtp, messageTemplate), this.isSendSmsByFlashEnabled(mtanItem));
   }

   private Sms createSmsFor(String phoneNumber, String message, boolean sendByFlash) {
      String normalizedPhoneNumber = this.normalizedPhoneNumber(phoneNumber);
      return Sms.builder().originator(this.settings.getOriginatorName()).phoneNumber(normalizedPhoneNumber).message(message).flashMessage(sendByFlash).build();
   }

   private boolean isSendSmsByFlashEnabled(MtanItem mtanItem) {
      Boolean sendSmsAsFlash = mtanItem.getSendSmsAsFlash();
      return sendSmsAsFlash == null ? this.settings.isFlashMessageEnabled() : sendSmsAsFlash;
   }

   private String message(Otp otp, String messageTemplate) {
      try {
         return SmsMessageInterpolator.applyReplacementsToMessage(messageTemplate, otp, this.currentLocale.get());
      } catch (FormatterException e) {
         throw new FailureException(e);
      }
   }

   private String normalizedPhoneNumber(String phoneNumber) {
      try {
         return PhoneUtils.normalizePhoneNumber(phoneNumber, this.settings.getDefaultCountryCode().getCode());
      } catch (ParseException e) {
         throw new ViolationException("Could not normalize mobile phone number", e);
      }
   }

   public static final class MtanSmsFactorySettings {
      @NonNull
      private final String originatorName;
      private final boolean flashMessageEnabled;
      @NonNull
      private final CountryCallingCode defaultCountryCode;

      @SuppressFBWarnings(justification = "generated code")
      MtanSmsFactorySettings(@NonNull String originatorName, boolean flashMessageEnabled, @NonNull CountryCallingCode defaultCountryCode) {
         if (originatorName == null) {
            throw new NullPointerException("originatorName is marked non-null but is null");
         }

         if (defaultCountryCode == null) {
            throw new NullPointerException("defaultCountryCode is marked non-null but is null");
         }

         this.originatorName = originatorName;
         this.flashMessageEnabled = flashMessageEnabled;
         this.defaultCountryCode = defaultCountryCode;
      }

      @SuppressFBWarnings(justification = "generated code")
      public static MtanSmsFactory.MtanSmsFactorySettings.MtanSmsFactorySettingsBuilder builder() {
         return new MtanSmsFactory.MtanSmsFactorySettings.MtanSmsFactorySettingsBuilder();
      }

      @NonNull
      @SuppressFBWarnings(justification = "generated code")
      public String getOriginatorName() {
         return this.originatorName;
      }

      @SuppressFBWarnings(justification = "generated code")
      public boolean isFlashMessageEnabled() {
         return this.flashMessageEnabled;
      }

      @NonNull
      @SuppressFBWarnings(justification = "generated code")
      public CountryCallingCode getDefaultCountryCode() {
         return this.defaultCountryCode;
      }

      @SuppressFBWarnings(justification = "generated code")
      @Override
      public boolean equals(Object o) {
         if (o == this) {
            return true;
         } else if (!(o instanceof MtanSmsFactory.MtanSmsFactorySettings other)) {
            return false;
         } else if (this.flashMessageEnabled != other.flashMessageEnabled) {
            return false;
         } else {
            Object this$originatorName = this.originatorName;
            Object other$originatorName = other.originatorName;
            if (this$originatorName == null ? other$originatorName == null : this$originatorName.equals(other$originatorName)) {
               Object this$defaultCountryCode = this.defaultCountryCode;
               Object other$defaultCountryCode = other.defaultCountryCode;
               return this$defaultCountryCode == null ? other$defaultCountryCode == null : this$defaultCountryCode.equals(other$defaultCountryCode);
            } else {
               return false;
            }
         }
      }

      @SuppressFBWarnings(justification = "generated code")
      @Override
      public int hashCode() {
         int PRIME = 59;
         int result = 1;
         result = result * 59 + (this.flashMessageEnabled ? 79 : 97);
         Object $originatorName = this.originatorName;
         result = result * 59 + ($originatorName == null ? 43 : $originatorName.hashCode());
         Object $defaultCountryCode = this.defaultCountryCode;
         return result * 59 + ($defaultCountryCode == null ? 43 : $defaultCountryCode.hashCode());
      }

      @SuppressFBWarnings(justification = "generated code")
      @Override
      public String toString() {
         return "MtanSmsFactory.MtanSmsFactorySettings(originatorName="
            + this.getOriginatorName()
            + ", flashMessageEnabled="
            + this.isFlashMessageEnabled()
            + ", defaultCountryCode="
            + this.getDefaultCountryCode()
            + ")";
      }

      @SuppressFBWarnings(justification = "generated code")
      public static class MtanSmsFactorySettingsBuilder {
         @SuppressFBWarnings(justification = "generated code")
         private String originatorName;
         @SuppressFBWarnings(justification = "generated code")
         private boolean flashMessageEnabled;
         @SuppressFBWarnings(justification = "generated code")
         private CountryCallingCode defaultCountryCode;

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

         @SuppressFBWarnings(justification = "generated code")
         public MtanSmsFactory.MtanSmsFactorySettings.MtanSmsFactorySettingsBuilder originatorName(@NonNull String originatorName) {
            if (originatorName == null) {
               throw new NullPointerException("originatorName is marked non-null but is null");
            }

            this.originatorName = originatorName;
            return this;
         }

         @SuppressFBWarnings(justification = "generated code")
         public MtanSmsFactory.MtanSmsFactorySettings.MtanSmsFactorySettingsBuilder flashMessageEnabled(boolean flashMessageEnabled) {
            this.flashMessageEnabled = flashMessageEnabled;
            return this;
         }

         @SuppressFBWarnings(justification = "generated code")
         public MtanSmsFactory.MtanSmsFactorySettings.MtanSmsFactorySettingsBuilder defaultCountryCode(@NonNull CountryCallingCode defaultCountryCode) {
            if (defaultCountryCode == null) {
               throw new NullPointerException("defaultCountryCode is marked non-null but is null");
            }

            this.defaultCountryCode = defaultCountryCode;
            return this;
         }

         @SuppressFBWarnings(justification = "generated code")
         public MtanSmsFactory.MtanSmsFactorySettings build() {
            return new MtanSmsFactory.MtanSmsFactorySettings(this.originatorName, this.flashMessageEnabled, this.defaultCountryCode);
         }

         @SuppressFBWarnings(justification = "generated code")
         @Override
         public String toString() {
            return "MtanSmsFactory.MtanSmsFactorySettings.MtanSmsFactorySettingsBuilder(originatorName="
               + this.originatorName
               + ", flashMessageEnabled="
               + this.flashMessageEnabled
               + ", defaultCountryCode="
               + this.defaultCountryCode
               + ")";
         }
      }
   }
}
