package com.airlock.iam.authentication.infrastructure.mapper;

import com.airlock.iam.authentication.infrastructure.transfer.response.AuthenticationMtanRegistrationTokenInformationData;
import com.airlock.iam.base.api.domain.model.exception.FailureException;
import com.airlock.iam.flow.shared.api.domain.model.item.info.UserDataItemInfo;
import com.airlock.iam.flow.shared.domain.model.item.UserDataItemsInfo;
import java.util.Collection;
import java.util.Optional;
import ma.glasnost.orika.CustomConverter;
import ma.glasnost.orika.MappingContext;
import ma.glasnost.orika.metadata.Type;

public final class AuthMtanRegistrationInfoConverter extends CustomConverter<UserDataItemsInfo, AuthenticationMtanRegistrationTokenInformationData> {
   public AuthenticationMtanRegistrationTokenInformationData convert(
      UserDataItemsInfo source, Type<? extends AuthenticationMtanRegistrationTokenInformationData> destinationType, MappingContext mappingContext
   ) {
      Collection<UserDataItemInfo<?>> elements = source.getElements();
      UserDataItemInfo<String> numberInfo = this.findInfo(elements, "number")
         .orElseThrow(() -> new FailureException("No number user data item information provided"));
      Optional<UserDataItemInfo<String>> labelInfo = this.findInfo(elements, "label");
      boolean labelInfoRequirement = labelInfo.flatMap(UserDataItemInfo::getRequired).orElse(false);
      AuthenticationMtanRegistrationTokenInformationData.AuthenticationMtanRegistrationTokenNumberData number = new AuthenticationMtanRegistrationTokenInformationData.AuthenticationMtanRegistrationTokenNumberData(
         numberInfo.getCurrentValue().orElse(null)
      );
      AuthenticationMtanRegistrationTokenInformationData.AuthenticationMtanRegistrationTokenLabelData label = labelInfo.<AuthenticationMtanRegistrationTokenInformationData.AuthenticationMtanRegistrationTokenLabelData>map(
            info -> new AuthenticationMtanRegistrationTokenInformationData.AuthenticationMtanRegistrationTokenLabelData(
               labelInfo.flatMap(UserDataItemInfo::getCurrentValue).orElse(null), labelInfoRequirement
            )
         )
         .orElse(null);
      return new AuthenticationMtanRegistrationTokenInformationData(number, label);
   }

   private Optional<UserDataItemInfo<String>> findInfo(Collection<UserDataItemInfo<?>> elements, String key) {
      return elements.stream().filter(info -> info.getName().equals(key)).map(x -> (UserDataItemInfo<String>)x).findFirst();
   }
}
