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

import com.airlock.iam.base.api.domain.model.mapification.MapifiedValues;
import com.airlock.iam.base.domain.model.mapification.MapifiedValuesBuilder;
import com.airlock.iam.common.api.domain.model.mtan.MtanNumberId;
import com.airlock.iam.common.api.domain.model.phonenumber.PhoneNumber;
import com.airlock.iam.flow.shared.api.domain.model.session.ChangeDescriptionFlowAttribute;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.util.Optional;
import lombok.NonNull;

public final class SelectedMtanToken implements ChangeDescriptionFlowAttribute<SelectedMtanToken> {
   private static final String MTAN_NUMBER_ID_KEY = "mtan";
   private static final String PHONE_NUMBER_KEY = "phone";
   private static final String LABEL_KEY = "label";
   @NonNull
   private final MtanNumberId tokenId;
   @NonNull
   private final PhoneNumber phoneNumber;
   @NonNull
   private final Optional<String> label;

   public SelectedMtanToken mergeWith(SelectedMtanToken newAttribute) {
      return newAttribute;
   }

   @Override
   public String description() {
      return "Selected mTAN Token";
   }

   @Override
   public MapifiedValues mapify() {
      return MapifiedValuesBuilder.mapifiedValues()
         .put("mtan", this.tokenId.getId())
         .put("phone", this.phoneNumber.getValue())
         .putIfPresent("label", this.label)
         .build();
   }

   public static SelectedMtanToken demapify(MapifiedValues values) {
      return new SelectedMtanToken(new MtanNumberId(values.get("mtan")), PhoneNumber.phoneNumber(values.get("phone")), values.getOptional("label"));
   }

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

   @NonNull
   @SuppressFBWarnings(justification = "generated code")
   public MtanNumberId getTokenId() {
      return this.tokenId;
   }

   @NonNull
   @SuppressFBWarnings(justification = "generated code")
   public PhoneNumber getPhoneNumber() {
      return this.phoneNumber;
   }

   @NonNull
   @SuppressFBWarnings(justification = "generated code")
   public Optional<String> getLabel() {
      return this.label;
   }

   @SuppressFBWarnings(justification = "generated code")
   public SelectedMtanToken(@NonNull MtanNumberId tokenId, @NonNull PhoneNumber phoneNumber, @NonNull Optional<String> label) {
      if (tokenId == null) {
         throw new NullPointerException("tokenId is marked non-null but is null");
      }

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

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

      this.tokenId = tokenId;
      this.phoneNumber = phoneNumber;
      this.label = label;
   }

   @SuppressFBWarnings(justification = "generated code")
   public static class SelectedMtanTokenBuilder {
      @SuppressFBWarnings(justification = "generated code")
      private MtanNumberId tokenId;
      @SuppressFBWarnings(justification = "generated code")
      private PhoneNumber phoneNumber;
      @SuppressFBWarnings(justification = "generated code")
      private Optional<String> label;

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

      @SuppressFBWarnings(justification = "generated code")
      public SelectedMtanToken.SelectedMtanTokenBuilder tokenId(@NonNull MtanNumberId tokenId) {
         if (tokenId == null) {
            throw new NullPointerException("tokenId is marked non-null but is null");
         }

         this.tokenId = tokenId;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public SelectedMtanToken.SelectedMtanTokenBuilder phoneNumber(@NonNull PhoneNumber phoneNumber) {
         if (phoneNumber == null) {
            throw new NullPointerException("phoneNumber is marked non-null but is null");
         }

         this.phoneNumber = phoneNumber;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public SelectedMtanToken.SelectedMtanTokenBuilder label(@NonNull Optional<String> label) {
         if (label == null) {
            throw new NullPointerException("label is marked non-null but is null");
         }

         this.label = label;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public SelectedMtanToken build() {
         return new SelectedMtanToken(this.tokenId, this.phoneNumber, this.label);
      }

      @SuppressFBWarnings(justification = "generated code")
      @Override
      public String toString() {
         return "SelectedMtanToken.SelectedMtanTokenBuilder(tokenId=" + this.tokenId + ", phoneNumber=" + this.phoneNumber + ", label=" + this.label + ")";
      }
   }
}
