package com.airlock.iam.login.rest.application.service;

import com.airlock.iam.flow.api.domain.model.flow.FlowId;
import com.airlock.iam.flow.api.domain.model.step.StepAction;
import com.airlock.iam.flow.api.domain.model.step.StepResult;
import com.airlock.iam.flow.domain.model.FlowInformation;
import com.airlock.iam.flow.domain.model.session.InternalFlowSession;
import com.airlock.iam.flow.domain.model.session.MultiFlowSession;
import com.airlock.iam.flow.shared.application.service.FlowInformationService;
import com.airlock.iam.flow.shared.domain.model.session.MultiFlowCapableUserSession;
import com.airlock.iam.flow.types.api.domain.model.session.MultiFlowType;
import jakarta.inject.Inject;
import jakarta.inject.Provider;
import java.util.Optional;

public final class FlowInformationServiceImpl implements FlowInformationService {
   private final Provider<MultiFlowCapableUserSession> userSession;

   @Inject
   public FlowInformationServiceImpl(Provider<MultiFlowCapableUserSession> userSession) {
      this.userSession = userSession;
   }

   @Override
   public Optional<FlowInformation> getFlowInformation() {
      Optional<MultiFlowSession> multiFlowSession = ((MultiFlowCapableUserSession)this.userSession.get()).getMultiFlowSession();
      if (multiFlowSession.isEmpty()) {
         return Optional.empty();
      } else {
         Optional<StepAction> nextStep = this.getNextAction();
         if (nextStep.isPresent()) {
            FlowId flowId = multiFlowSession.get().getCurrentFlowId();
            MultiFlowType flowType = multiFlowSession.get().getType();
            return Optional.of(new FlowInformation(flowId, flowType, nextStep.get()));
         } else {
            return Optional.empty();
         }
      }
   }

   private Optional<StepAction> getNextAction() {
      return ((MultiFlowCapableUserSession)this.userSession.get())
         .getCurrentFlowSession()
         .flatMap(InternalFlowSession::lastResult)
         .flatMap(StepResult::nextAction);
   }
}
