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

import com.airlock.iam.base.api.domain.model.plugin.LogicForConfig;
import com.airlock.iam.base.misc.log.LogUtil;
import com.airlock.iam.flow.shared.api.domain.model.message.Airlock2FAMessage;
import com.airlock.iam.flow.shared.api.domain.model.message.Airlock2FAMessageItem;
import com.airlock.iam.flow.shared.api.domain.model.message.Airlock2FAMessageProvider;
import com.airlock.iam.flow.shared.api.domain.model.message.Airlock2FAMessageProviderException;
import com.airlock.iam.flow.shared.api.domain.model.valueprovider.ValueMapProvider;
import com.airlock.iam.flow.shared.application.configuration.message.GenericAirlock2FAMessageProviderConfig;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import jakarta.inject.Inject;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import org.apache.commons.lang3.StringUtils;

@LogicForConfig(GenericAirlock2FAMessageProviderConfig.class)
public final class GenericAirlock2FAMessageProvider implements Airlock2FAMessageProvider {
   private final GenericAirlock2FAMessageProvider.GenericAirlock2FAMessageProviderSettings settings;
   private final ValueMapProvider valueProvider;
   private final MessageProviderHelper messageProvider;

   @Inject
   public GenericAirlock2FAMessageProvider(
      GenericAirlock2FAMessageProvider.GenericAirlock2FAMessageProviderSettings settings, ValueMapProvider valueProvider, MessageProviderHelper messageProvider
   ) {
      this.settings = settings;
      this.valueProvider = valueProvider;
      this.messageProvider = messageProvider;
   }

   @Override
   public Airlock2FAMessage generateAirlock2FAMessage() throws Airlock2FAMessageProviderException {
      Map<String, Object> values = new HashMap<>(this.valueProvider.provideValueMap());
      String title = this.messageProvider.translateMessage(this.settings.getTitleResourceKey(), () -> values);
      List<Airlock2FAMessageItem> items = new ArrayList<>();

      for (GenericAirlock2FAMessageProvider.Airlock2FAInformationItemSettings item : this.settings.getInfoItems()) {
         this.resolveItem(item, values).ifPresent(items::add);
      }

      return Airlock2FAMessage.builder().type(title).items(items).build();
   }

   private Optional<Airlock2FAMessageItem> resolveItem(GenericAirlock2FAMessageProvider.Airlock2FAInformationItemSettings item, Map<String, Object> values) throws Airlock2FAMessageProviderException {
      String key = this.messageProvider.translateGrowableMessage(item.getKeyResourceKey(), item.getMaxKeyLength(), () -> values);
      if (StringUtils.isBlank(key)) {
         throw Airlock2FAMessageProviderException.airlock2faMessageProviderException("Airlock 2FA message key is blank.");
      }

      String value = this.messageProvider.translateGrowableMessage(item.getValueResourceKey(), item.getMaxValueLength(), () -> values);
      if (StringUtils.isBlank(value)) {
         if (item.isOmitIfValueEmpty()) {
            return Optional.empty();
         } else {
            throw Airlock2FAMessageProviderException.airlock2faMessageProviderException(
               String.format("Airlock 2FA message value for key %s is blank.", LogUtil.quote(key))
            );
         }
      } else {
         return Optional.of(Airlock2FAMessageItem.messageItem(key, value));
      }
   }

   public static final class Airlock2FAInformationItemSettings {
      private final String keyResourceKey;
      private final String valueResourceKey;
      private final boolean omitIfValueEmpty;
      private final int maxKeyLength;
      private final int maxValueLength;

      @SuppressFBWarnings(justification = "generated code")
      public static GenericAirlock2FAMessageProvider.Airlock2FAInformationItemSettings.Airlock2FAInformationItemSettingsBuilder builder() {
         return new GenericAirlock2FAMessageProvider.Airlock2FAInformationItemSettings.Airlock2FAInformationItemSettingsBuilder();
      }

      @SuppressFBWarnings(justification = "generated code")
      public Airlock2FAInformationItemSettings(String keyResourceKey, String valueResourceKey, boolean omitIfValueEmpty, int maxKeyLength, int maxValueLength) {
         this.keyResourceKey = keyResourceKey;
         this.valueResourceKey = valueResourceKey;
         this.omitIfValueEmpty = omitIfValueEmpty;
         this.maxKeyLength = maxKeyLength;
         this.maxValueLength = maxValueLength;
      }

      @SuppressFBWarnings(justification = "generated code")
      public String getKeyResourceKey() {
         return this.keyResourceKey;
      }

      @SuppressFBWarnings(justification = "generated code")
      public String getValueResourceKey() {
         return this.valueResourceKey;
      }

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

      @SuppressFBWarnings(justification = "generated code")
      public int getMaxKeyLength() {
         return this.maxKeyLength;
      }

      @SuppressFBWarnings(justification = "generated code")
      public int getMaxValueLength() {
         return this.maxValueLength;
      }

      @SuppressFBWarnings(justification = "generated code")
      public static class Airlock2FAInformationItemSettingsBuilder {
         @SuppressFBWarnings(justification = "generated code")
         private String keyResourceKey;
         @SuppressFBWarnings(justification = "generated code")
         private String valueResourceKey;
         @SuppressFBWarnings(justification = "generated code")
         private boolean omitIfValueEmpty;
         @SuppressFBWarnings(justification = "generated code")
         private int maxKeyLength;
         @SuppressFBWarnings(justification = "generated code")
         private int maxValueLength;

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

         @SuppressFBWarnings(justification = "generated code")
         public GenericAirlock2FAMessageProvider.Airlock2FAInformationItemSettings.Airlock2FAInformationItemSettingsBuilder keyResourceKey(
            String keyResourceKey
         ) {
            this.keyResourceKey = keyResourceKey;
            return this;
         }

         @SuppressFBWarnings(justification = "generated code")
         public GenericAirlock2FAMessageProvider.Airlock2FAInformationItemSettings.Airlock2FAInformationItemSettingsBuilder valueResourceKey(
            String valueResourceKey
         ) {
            this.valueResourceKey = valueResourceKey;
            return this;
         }

         @SuppressFBWarnings(justification = "generated code")
         public GenericAirlock2FAMessageProvider.Airlock2FAInformationItemSettings.Airlock2FAInformationItemSettingsBuilder omitIfValueEmpty(
            boolean omitIfValueEmpty
         ) {
            this.omitIfValueEmpty = omitIfValueEmpty;
            return this;
         }

         @SuppressFBWarnings(justification = "generated code")
         public GenericAirlock2FAMessageProvider.Airlock2FAInformationItemSettings.Airlock2FAInformationItemSettingsBuilder maxKeyLength(int maxKeyLength) {
            this.maxKeyLength = maxKeyLength;
            return this;
         }

         @SuppressFBWarnings(justification = "generated code")
         public GenericAirlock2FAMessageProvider.Airlock2FAInformationItemSettings.Airlock2FAInformationItemSettingsBuilder maxValueLength(int maxValueLength) {
            this.maxValueLength = maxValueLength;
            return this;
         }

         @SuppressFBWarnings(justification = "generated code")
         public GenericAirlock2FAMessageProvider.Airlock2FAInformationItemSettings build() {
            return new GenericAirlock2FAMessageProvider.Airlock2FAInformationItemSettings(
               this.keyResourceKey, this.valueResourceKey, this.omitIfValueEmpty, this.maxKeyLength, this.maxValueLength
            );
         }

         @SuppressFBWarnings(justification = "generated code")
         @Override
         public String toString() {
            return "GenericAirlock2FAMessageProvider.Airlock2FAInformationItemSettings.Airlock2FAInformationItemSettingsBuilder(keyResourceKey="
               + this.keyResourceKey
               + ", valueResourceKey="
               + this.valueResourceKey
               + ", omitIfValueEmpty="
               + this.omitIfValueEmpty
               + ", maxKeyLength="
               + this.maxKeyLength
               + ", maxValueLength="
               + this.maxValueLength
               + ")";
         }
      }
   }

   public static final class GenericAirlock2FAMessageProviderSettings {
      private final String titleResourceKey;
      private final List<GenericAirlock2FAMessageProvider.Airlock2FAInformationItemSettings> infoItems;

      @SuppressFBWarnings(justification = "generated code")
      public static GenericAirlock2FAMessageProvider.GenericAirlock2FAMessageProviderSettings.GenericAirlock2FAMessageProviderSettingsBuilder builder() {
         return new GenericAirlock2FAMessageProvider.GenericAirlock2FAMessageProviderSettings.GenericAirlock2FAMessageProviderSettingsBuilder();
      }

      @SuppressFBWarnings(justification = "generated code")
      public GenericAirlock2FAMessageProviderSettings(
         String titleResourceKey, List<GenericAirlock2FAMessageProvider.Airlock2FAInformationItemSettings> infoItems
      ) {
         this.titleResourceKey = titleResourceKey;
         this.infoItems = infoItems;
      }

      @SuppressFBWarnings(justification = "generated code")
      public String getTitleResourceKey() {
         return this.titleResourceKey;
      }

      @SuppressFBWarnings(justification = "generated code")
      public List<GenericAirlock2FAMessageProvider.Airlock2FAInformationItemSettings> getInfoItems() {
         return this.infoItems;
      }

      @SuppressFBWarnings(justification = "generated code")
      public static class GenericAirlock2FAMessageProviderSettingsBuilder {
         @SuppressFBWarnings(justification = "generated code")
         private String titleResourceKey;
         @SuppressFBWarnings(justification = "generated code")
         private ArrayList<GenericAirlock2FAMessageProvider.Airlock2FAInformationItemSettings> infoItems;

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

         @SuppressFBWarnings(justification = "generated code")
         public GenericAirlock2FAMessageProvider.GenericAirlock2FAMessageProviderSettings.GenericAirlock2FAMessageProviderSettingsBuilder titleResourceKey(
            String titleResourceKey
         ) {
            this.titleResourceKey = titleResourceKey;
            return this;
         }

         @SuppressFBWarnings(justification = "generated code")
         public GenericAirlock2FAMessageProvider.GenericAirlock2FAMessageProviderSettings.GenericAirlock2FAMessageProviderSettingsBuilder infoItem(
            GenericAirlock2FAMessageProvider.Airlock2FAInformationItemSettings infoItem
         ) {
            if (this.infoItems == null) {
               this.infoItems = new ArrayList<>();
            }

            this.infoItems.add(infoItem);
            return this;
         }

         @SuppressFBWarnings(justification = "generated code")
         public GenericAirlock2FAMessageProvider.GenericAirlock2FAMessageProviderSettings.GenericAirlock2FAMessageProviderSettingsBuilder infoItems(
            Collection<? extends GenericAirlock2FAMessageProvider.Airlock2FAInformationItemSettings> infoItems
         ) {
            if (infoItems == null) {
               throw new NullPointerException("infoItems cannot be null");
            }

            if (this.infoItems == null) {
               this.infoItems = new ArrayList<>();
            }

            this.infoItems.addAll(infoItems);
            return this;
         }

         @SuppressFBWarnings(justification = "generated code")
         public GenericAirlock2FAMessageProvider.GenericAirlock2FAMessageProviderSettings.GenericAirlock2FAMessageProviderSettingsBuilder clearInfoItems() {
            if (this.infoItems != null) {
               this.infoItems.clear();
            }

            return this;
         }

         @SuppressFBWarnings(justification = "generated code")
         public GenericAirlock2FAMessageProvider.GenericAirlock2FAMessageProviderSettings build() {
            return new GenericAirlock2FAMessageProvider.GenericAirlock2FAMessageProviderSettings(
               this.titleResourceKey, switch (this.infoItems == null ? 0 : this.infoItems.size()) {
                  case 0 -> Collections.emptyList();
                  case 1 -> Collections.singletonList(this.infoItems.get(0));
                  default -> Collections.unmodifiableList(new ArrayList<>(this.infoItems));
               }
            );
         }

         @SuppressFBWarnings(justification = "generated code")
         @Override
         public String toString() {
            return "GenericAirlock2FAMessageProvider.GenericAirlock2FAMessageProviderSettings.GenericAirlock2FAMessageProviderSettingsBuilder(titleResourceKey="
               + this.titleResourceKey
               + ", infoItems="
               + this.infoItems
               + ")";
         }
      }
   }
}
