package com.airlock.iam.publicselfservice.infrastructure.settings.ui;

import com.airlock.iam.flow.api.application.configuration.step.FlowStepConfig;
import com.airlock.iam.flow.api.domain.model.step.StepAction;
import com.airlock.iam.flow.shared.application.configuration.acknowledgemessage.AcknowledgeMessageStepConfig;
import com.airlock.iam.flow.shared.application.configuration.airlock2fa.DefaultAirlock2FAApprovalStepActions;
import com.airlock.iam.flow.shared.domain.model.cronto.CrontoCheckingStep;
import com.airlock.iam.flow.shared.domain.model.mtan.MtanOtpCheckingStep;
import com.airlock.iam.flow.ui.api.domain.model.step.KnownStepUiPath;
import com.airlock.iam.flow.ui.infrastructure.service.ui.CreatableScreenConfigsDefinition;
import com.airlock.iam.flow.ui.infrastructure.service.ui.GlobalUiAttributes;
import com.airlock.iam.flow.ui.infrastructure.service.ui.ScreenConfig;
import com.airlock.iam.flow.ui.infrastructure.service.ui.StepUiSettingsCreator;
import com.airlock.iam.flow.ui.infrastructure.service.ui.StepUiSettingsFactory;
import com.airlock.iam.flow.ui.infrastructure.settings.SimpleDefaultUiSettings;
import com.airlock.iam.flow.ui.infrastructure.settings.StepUiSettings;
import com.airlock.iam.flow.ui.infrastructure.settings.annotation.DefaultUiCreator;
import com.airlock.iam.publicselfservice.application.configuration.steps.Airlock2FAPublicSelfServiceApprovalStepConfig;
import com.airlock.iam.publicselfservice.application.configuration.steps.CrontoPublicSelfServiceApprovalStealthStepConfig;
import com.airlock.iam.publicselfservice.application.configuration.steps.CrontoPublicSelfServiceApprovalStepConfig;
import com.airlock.iam.publicselfservice.application.configuration.steps.EmailIdentityVerificationStepConfig;
import com.airlock.iam.publicselfservice.application.configuration.steps.MatrixCardPublicSelfServiceApprovalStepConfig;
import com.airlock.iam.publicselfservice.application.configuration.steps.MtanPublicSelfServiceApprovalStepConfig;
import com.airlock.iam.publicselfservice.application.configuration.steps.PasswordResetStepConfig;
import com.airlock.iam.publicselfservice.application.configuration.steps.PublicSelfServiceFidoApprovalStepConfig;
import com.airlock.iam.publicselfservice.application.configuration.steps.PublicSelfServiceOathOtpApprovalStepConfig;
import com.airlock.iam.publicselfservice.application.configuration.steps.PublicSelfServiceUserIdentifyingStepConfig;
import com.airlock.iam.publicselfservice.application.configuration.steps.PublicSelfServiceVascoOtpApprovalStepConfig;
import com.airlock.iam.publicselfservice.application.configuration.steps.SecretQuestionsIdentityVerificationStepConfig;
import com.airlock.iam.publicselfservice.application.configuration.steps.SelectionStepConfigForPublicSelfServiceFlows;
import com.airlock.iam.publicselfservice.application.configuration.steps.SmsIdentityVerificationStepConfig;
import com.airlock.iam.ssi.application.configuration.step.SsiVerificationStepConfig;
import com.airlock.iam.ssi.domain.model.step.SsiVerificationStep;
import jakarta.inject.Inject;
import jakarta.inject.Provider;
import java.util.Map;
import java.util.Set;
import java.util.function.BiFunction;

@DefaultUiCreator(PublicSelfServiceStepUiSettingsCreator.PublicSelfServiceStepUiSettingsCreatorScreenConfigsDefinition.class)
public final class PublicSelfServiceStepUiSettingsCreator implements StepUiSettingsCreator {
   private final Provider<GlobalUiAttributes> globalUiAttributes;
   private static final Map<ScreenConfig, BiFunction<FlowStepConfig, GlobalUiAttributes, StepUiSettings>> DEFAULT_UIS = Map.ofEntries(
      Map.entry(
         ScreenConfig.screenConfigOf(PublicSelfServiceUserIdentifyingStepConfig.class), SimpleDefaultUiSettings.defaultFlowUiWithPath(KnownStepUiPath.USERNAME)
      ),
      Map.entry(ScreenConfig.screenConfigOf(PasswordResetStepConfig.class), SimpleDefaultUiSettings.defaultFlowUiWithPath(KnownStepUiPath.PASSWORD)),
      Map.entry(ScreenConfig.screenConfigOf(EmailIdentityVerificationStepConfig.class), SimpleDefaultUiSettings.defaultFlowUiWithPath(KnownStepUiPath.EMAIL)),
      Map.entry(ScreenConfig.screenConfigOf(SmsIdentityVerificationStepConfig.class), SimpleDefaultUiSettings.defaultFlowUiWithPath(KnownStepUiPath.MTAN)),
      Map.entry(
         ScreenConfig.screenConfigOf(SecretQuestionsIdentityVerificationStepConfig.class),
         SimpleDefaultUiSettings.defaultFlowUiWithPath(KnownStepUiPath.SECRET_QUESTIONS)
      ),
      Map.entry(
         ScreenConfig.screenConfigOf(SelectionStepConfigForPublicSelfServiceFlows.class),
         SimpleDefaultUiSettings.defaultFlowUiWithPath(KnownStepUiPath.SELECTION)
      ),
      Map.entry(
         ScreenConfig.screenConfigOf(CrontoPublicSelfServiceApprovalStepConfig.class),
         SimpleDefaultUiSettings.defaultFlowUiWithPath(KnownStepUiPath.APPROVAL_CRONTO_CHALLENGE)
      ),
      Map.entry(
         ScreenConfig.screenConfigOf(CrontoPublicSelfServiceApprovalStepConfig.class, CrontoCheckingStep.CrontoAuthStepActions.CRONTO_DEVICE_CHOICE_REQUIRED),
         SimpleDefaultUiSettings.defaultFlowUiWithPath(KnownStepUiPath.APPROVAL_CRONTO_SELECTION)
      ),
      Map.entry(
         ScreenConfig.screenConfigOf(CrontoPublicSelfServiceApprovalStealthStepConfig.class),
         SimpleDefaultUiSettings.defaultFlowUiWithPath(KnownStepUiPath.APPROVAL_CRONTO_CHALLENGE)
      ),
      Map.entry(
         ScreenConfig.screenConfigOf(
            Airlock2FAPublicSelfServiceApprovalStepConfig.class, DefaultAirlock2FAApprovalStepActions.Actions.AIRLOCK_2FA_POLLING_REQUIRED
         ),
         SimpleDefaultUiSettings.defaultFlowUiWithPath(KnownStepUiPath.APPROVAL_AIRLOCK_2FA_CHALLENGE_ONLY)
      ),
      Map.entry(
         ScreenConfig.screenConfigOf(
            Airlock2FAPublicSelfServiceApprovalStepConfig.class, DefaultAirlock2FAApprovalStepActions.Actions.AIRLOCK_2FA_POLLING_OR_OFFLINE_REQUIRED
         ),
         SimpleDefaultUiSettings.defaultFlowUiWithPath(KnownStepUiPath.APPROVAL_AIRLOCK_2FA_CHALLENGE)
      ),
      Map.entry(
         ScreenConfig.screenConfigOf(
            Airlock2FAPublicSelfServiceApprovalStepConfig.class, DefaultAirlock2FAApprovalStepActions.Actions.AIRLOCK_2FA_QR_CODE_OTP_REQUIRED
         ),
         SimpleDefaultUiSettings.defaultFlowUiWithPath(KnownStepUiPath.APPROVAL_AIRLOCK_2FA_QRCODE)
      ),
      Map.entry(
         ScreenConfig.screenConfigOf(
            Airlock2FAPublicSelfServiceApprovalStepConfig.class, DefaultAirlock2FAApprovalStepActions.Actions.AIRLOCK_2FA_DEVICE_CHOICE_REQUIRED
         ),
         SimpleDefaultUiSettings.defaultFlowUiWithPath(KnownStepUiPath.APPROVAL_AIRLOCK_2FA_SELECTION)
      ),
      Map.entry(
         ScreenConfig.screenConfigOf(
            Airlock2FAPublicSelfServiceApprovalStepConfig.class, DefaultAirlock2FAApprovalStepActions.Actions.AIRLOCK_2FA_PASSCODE_REQUIRED
         ),
         SimpleDefaultUiSettings.defaultFlowUiWithPath(KnownStepUiPath.APPROVAL_AIRLOCK_2FA_PASSCODE)
      ),
      Map.entry(
         ScreenConfig.screenConfigOf(MatrixCardPublicSelfServiceApprovalStepConfig.class),
         SimpleDefaultUiSettings.defaultFlowUiWithPath(KnownStepUiPath.APPROVAL_MATRIX)
      ),
      Map.entry(
         ScreenConfig.screenConfigOf(MtanPublicSelfServiceApprovalStepConfig.class, MtanOtpCheckingStep.MtanAuthStepActions.MTAN_OTP_REQUIRED),
         SimpleDefaultUiSettings.defaultFlowUiWithPath(KnownStepUiPath.APPROVAL_MTAN)
      ),
      Map.entry(
         ScreenConfig.screenConfigOf(MtanPublicSelfServiceApprovalStepConfig.class, MtanOtpCheckingStep.MtanAuthStepActions.MTAN_TOKEN_CHOICE_REQUIRED),
         SimpleDefaultUiSettings.defaultFlowUiWithPath(KnownStepUiPath.APPROVAL_MTAN_SELECTION)
      ),
      Map.entry(
         ScreenConfig.screenConfigOf(PublicSelfServiceVascoOtpApprovalStepConfig.class),
         SimpleDefaultUiSettings.defaultFlowUiWithPath(KnownStepUiPath.APPROVAL_VASCO_OTP)
      ),
      Map.entry(
         ScreenConfig.screenConfigOf(PublicSelfServiceFidoApprovalStepConfig.class),
         SimpleDefaultUiSettings.defaultFlowUiWithPath(KnownStepUiPath.APPROVAL_FIDO)
      ),
      Map.entry(ScreenConfig.screenConfigOf(AcknowledgeMessageStepConfig.class), SimpleDefaultUiSettings.defaultFlowUiWithPath(KnownStepUiPath.MESSAGE)),
      Map.entry(
         ScreenConfig.screenConfigOf(SsiVerificationStepConfig.class, SsiVerificationStep.SsiVerificationActions.SSI_PROOF_VERIFICATION_REQUIRED),
         SimpleDefaultUiSettings.defaultFlowUiWithPath(KnownStepUiPath.SSI_VERIFICATION)
      ),
      Map.entry(
         ScreenConfig.screenConfigOf(PublicSelfServiceOathOtpApprovalStepConfig.class),
         SimpleDefaultUiSettings.defaultFlowUiWithPath(KnownStepUiPath.APPROVAL_OATH_OTP)
      )
   );

   @Inject
   public PublicSelfServiceStepUiSettingsCreator(Provider<GlobalUiAttributes> globalUiAttributes) {
      this.globalUiAttributes = globalUiAttributes;
   }

   public StepUiSettings createUiSettings(FlowStepConfig stepConfig, StepAction action) {
      return StepUiSettingsFactory.createStepUiSettings(stepConfig, (GlobalUiAttributes)this.globalUiAttributes.get(), action, DEFAULT_UIS);
   }

   public static final class PublicSelfServiceStepUiSettingsCreatorScreenConfigsDefinition implements CreatableScreenConfigsDefinition {
      public Set<ScreenConfig> creatableScreenConfigs() {
         return PublicSelfServiceStepUiSettingsCreator.DEFAULT_UIS.keySet();
      }
   }
}
