class ConsentService {

    public ResponseObject<CreateConsentResponse> createAccountConsentsWithResponse(CreateConsentReq request, PsuIdData psuData,
                                                                                   boolean explicitPreferred) {
        xs2aEventService.recordTppRequest(EventType.CREATE_AIS_CONSENT_REQUEST_RECEIVED, request);
        CreateConsentReq requestAfterCheck = additionalInformationSupportedService.checkIfAdditionalInformationSupported(request);

        ValidationResult validationResult = consentValidationService.validateConsentOnCreate(requestAfterCheck, psuData);
        if (validationResult.isNotValid()) {
            log.info("Create account consent with response - validation failed: {}",
                     validationResult.getMessageError());
            return ResponseObject.<CreateConsentResponse>builder()
                       .fail(validationResult.getMessageError())
                       .build();
        }

        if (requestAfterCheck.isGlobalOrAllAccountsAccessConsent()) {
            requestAfterCheck.setAccess(spiToXs2aAccountAccessMapper.getAccessForGlobalOrAllAvailableAccountsConsent(requestAfterCheck));
        }

        TppInfo tppInfo = tppService.getTppInfo();
        Optional<Xs2aCreateAisConsentResponse> createAisConsentResponseOptional = aisConsentService.createConsent(requestAfterCheck, psuData, tppInfo);

        if (createAisConsentResponseOptional.isEmpty()) {
            return ResponseObject.<CreateConsentResponse>builder()
                       .fail(ErrorType.AIS_400, of(MessageErrorCode.RESOURCE_UNKNOWN_400))
                       .build();
        }

        Xs2aCreateAisConsentResponse createAisConsentResponse = createAisConsentResponseOptional.get();
        SpiContextData contextData = spiContextDataProvider.provide(psuData, tppInfo);
        InitialSpiAspspConsentDataProvider aspspConsentDataProvider = aspspConsentDataProviderFactory.getInitialAspspConsentDataProvider();
        AisConsent aisConsent = createAisConsentResponse.getAisConsent();

        SpiResponse<SpiInitiateAisConsentResponse> initiateAisConsentSpiResponse = aisConsentSpi.initiateAisConsent(contextData, aisConsentMapper.mapToSpiAccountConsent(aisConsent), aspspConsentDataProvider);

        String encryptedConsentId = createAisConsentResponse.getConsentId();
        aspspConsentDataProvider.saveWith(encryptedConsentId);

        if (initiateAisConsentSpiResponse.hasError()) {
            aisConsentService.updateConsentStatus(encryptedConsentId, ConsentStatus.REJECTED);
            ErrorHolder errorHolder = spiErrorMapper.mapToErrorHolder(initiateAisConsentSpiResponse, ServiceType.AIS);
            log.info("Consent-ID: [{}]. Create account consent  with response failed. Consent rejected. Couldn't initiate AIS consent at SPI level: {}",
                     encryptedConsentId, errorHolder);
            return ResponseObject.<CreateConsentResponse>builder()
                       .fail(new MessageError(errorHolder))
                       .build();
        }

        SpiInitiateAisConsentResponse spiResponsePayload = initiateAisConsentSpiResponse.getPayload();
        boolean multilevelScaRequired = spiResponsePayload.isMultilevelScaRequired()
                                            && !aisScaAuthorisationService.isOneFactorAuthorisation(aisConsent);

        updateMultilevelSca(encryptedConsentId, multilevelScaRequired);

        Optional<AccountAccess> xs2aAccountAccess = spiToXs2aAccountAccessMapper.mapToAccountAccess(spiResponsePayload.getAccountAccess());
        xs2aAccountAccess.ifPresent(accountAccess ->
                                        accountReferenceUpdater.rewriteAccountAccess(encryptedConsentId, accountAccess, ConsentType.AIS));

        ConsentStatus consentStatus = aisConsent.getConsentStatus();
        CreateConsentResponse createConsentResponse = new CreateConsentResponse(consentStatus.getValue(), encryptedConsentId,
                                                                                null, null, null,
                                                                                spiResponsePayload.getPsuMessage(), multilevelScaRequired,
                                                                                requestProviderService.getInternalRequestIdString(),
                                                                                createAisConsentResponse.getTppNotificationContentPreferred());

        createConsentResponse.setTppMessageInformation(consentValidationService.buildWarningMessages(requestAfterCheck));

        ResponseObject<CreateConsentResponse> createConsentResponseObject = ResponseObject.<CreateConsentResponse>builder().body(createConsentResponse).build();

        if (authorisationMethodDecider.isImplicitMethod(explicitPreferred, multilevelScaRequired)) {
            proceedImplicitCaseForCreateConsent(createConsentResponseObject.getBody(), psuData, encryptedConsentId);
        }

        loggingContextService.storeConsentStatus(consentStatus);

        return createConsentResponseObject;
    }

}