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

import com.airlock.iam.base.api.domain.model.exception.FailureException;
import com.airlock.iam.base.api.domain.model.exception.ServiceConfigurationException;
import com.airlock.iam.base.misc.log.LogUtil;
import com.airlock.iam.common.domain.model.user.PrincipalInfo;
import com.airlock.iam.core.misc.impl.authen.mtan.MtanHandler;
import com.airlock.iam.core.misc.impl.authen.mtan.MtanHandlerException;
import com.airlock.iam.core.misc.impl.token.MtanItem;
import com.airlock.iam.elog.api.ELogger;
import com.airlock.iam.elog.api.ELoggerFactory;
import com.airlock.iam.flow.shared.domain.model.mtan.Iak;
import com.airlock.iam.flow.shared.domain.model.step.mtan.MtanVerificationSettings;
import jakarta.inject.Inject;
import jakarta.inject.Provider;
import java.util.List;
import java.util.Optional;

public final class MtanVerificationIakServiceImpl implements MtanVerificationIakService {
   private static final ELogger LOG = ELoggerFactory.getLogger(MtanVerificationIakServiceImpl.class);
   private final Provider<PrincipalInfo> user;
   private final MtanVerificationSettings settings;
   private final MtanHandler handler;

   @Inject
   public MtanVerificationIakServiceImpl(Provider<PrincipalInfo> user, MtanVerificationSettings settings, MtanHandler handler) {
      this.user = user;
      this.settings = settings;
      this.handler = handler;
   }

   @Override
   public boolean isIakMissing() {
      if (!this.settings.isIakRequired()) {
         return false;
      }

      try {
         ServiceConfigurationException.checkTrue(
            this.handler.isIAKVerificationSupported(), "IAK verification required, but not supported by mTAN Handler configuration."
         );
         return !this.handler.isIakAvailable(this.username());
      } catch (MtanHandlerException e) {
         throw new FailureException(e);
      }
   }

   @Override
   public boolean checkIak(Iak iak) {
      try {
         Optional<MtanItem> iakItem = this.handler.checkIakNonDestructive(this.username(), iak.getValue());
         if (iakItem.isEmpty()) {
            LOG.info("IAK verification for user " + LogUtil.quote(this.username()) + " failed.");
            return false;
         }

         LOG.info("IAK verification for user " + LogUtil.quote(this.username()) + " successful. Deleting IAK.");
         this.handler.deleteIak(this.username(), iakItem.get());
         if (iakItem.get().getMobilePhoneNumber() == null) {
            this.handler.deleteMtanItem(iakItem.get(), this.username(), this.username(), List.of());
         }

         return true;
      } catch (MtanHandlerException e) {
         throw new FailureException(e);
      }
   }

   private String username() {
      return ((PrincipalInfo)this.user.get()).getKnownIdentity().orElseThrow().id().getValue();
   }
}
