package com.airlock.iam.flow.shared.application.service.airlock2fa;

import com.airlock.iam.airlock2fa.api.domain.model.Airlock2FADeviceId;
import com.airlock.iam.factor.domain.model.airlock2fa.otp.Airlock2FAOtp;
import com.airlock.iam.factor.domain.model.airlock2fa.otp.Airlock2FAPasscode;
import com.airlock.iam.flow.api.domain.model.flow.FlowResult;
import com.airlock.iam.flow.api.domain.model.step.StepResult;
import com.airlock.iam.flow.domain.model.flow.FlowProvider;
import com.airlock.iam.flow.shared.domain.model.airlock2fa.Airlock2FAApprovalStep;
import jakarta.inject.Inject;
import java.util.function.Function;

public final class Airlock2FAApproval {
   private final FlowProvider flowProvider;

   @Inject
   public Airlock2FAApproval(FlowProvider flowProvider) {
      this.flowProvider = flowProvider;
   }

   public FlowResult checkOtp(Airlock2FAOtp code) {
      return this.executeStepMethod(step -> step.checkOtp(code));
   }

   public FlowResult checkPasscode(Airlock2FAPasscode passcode) {
      return this.executeStepMethod(step -> step.checkPasscode(passcode));
   }

   public FlowResult retrieveOfflineQrCode() {
      return this.executeStepMethod(Airlock2FAApprovalStep::retrieveOfflineQrCode);
   }

   public FlowResult retrieveMobileOnlyChallenge() {
      return this.executeStepMethod(Airlock2FAApprovalStep::retrieveMobileOnlyChallenge);
   }

   public FlowResult pollOnlineValidation(boolean queryOnly) {
      return this.executeStepMethod(step -> step.pollOnlineValidation(queryOnly));
   }

   public FlowResult switchToOffline() {
      return this.executeStepMethod(Airlock2FAApprovalStep::switchToOffline);
   }

   public FlowResult listDevices() {
      return this.executeStepMethod(Airlock2FAApprovalStep::listDevices);
   }

   public FlowResult selectDevice(Airlock2FADeviceId deviceId) {
      return this.executeStepMethod(step -> step.selectDevice(deviceId));
   }

   private FlowResult executeStepMethod(Function<Airlock2FAApprovalStep, StepResult> stepMethod) {
      return this.flowProvider.getCurrentOrStartNew().execute(stepMethod, Airlock2FAApprovalStep.class);
   }
}
