class FundsConfirmationService {

    public ResponseObject<FundsConfirmationResponse> fundsConfirmation(FundsConfirmationRequest request) {
        xs2aEventService.recordTppRequest(EventType.FUNDS_CONFIRMATION_REQUEST_RECEIVED, request);

        PiisConsent consent = null;
        PiisConsentSupported piisConsentSupported = profileService.getPiisConsentSupported();
        if (piisConsentSupported == PiisConsentSupported.ASPSP_CONSENT_SUPPORTED) {
            AccountReference accountReference = request.getPsuAccount();
            PiisConsentValidationResult validationResult = validateAccountReference(accountReference);

            if (validationResult.hasError()) {
                ErrorHolder errorHolder = validationResult.getErrorHolder();
                log.info("Check availability of funds validation failed: {}", errorHolder);
                return ResponseObject.<FundsConfirmationResponse>builder()
                           .fail(new MessageError(errorHolder))
                           .build();
            }

            consent = validationResult.getConsent();
        } else if (piisConsentSupported == PiisConsentSupported.TPP_CONSENT_SUPPORTED) {
            String consentId = request.getConsentId();
            if (StringUtils.isNotEmpty(consentId)) {
                Optional<PiisConsent> piisConsentOptional = xs2aPiisConsentService.getPiisConsentById(consentId);

                if (piisConsentOptional.isEmpty()) {
                    log.info("Consent-ID: [{}]. Get PIIS consent failed: initial consent not found by id", consentId);
                    return ResponseObject.<FundsConfirmationResponse>builder()
                               .fail(ErrorType.PIIS_403, of(MessageErrorCode.CONSENT_UNKNOWN_403))
                               .build();
                }

                consent = piisConsentOptional.get();
            }
        }

        PsuIdData psuIdData = requestProviderService.getPsuIdData();
        log.info("Corresponding PSU-ID {} was provided from request.", psuIdData);

        // We don't transfer provider to the SPI level if there is no PIIS consent. Both PIIS consent and the provider
        // parameters are marked as @Nullable in SPI.
        SpiAspspConsentDataProvider aspspConsentDataProvider =
            consent != null ? aspspConsentDataProviderFactory.getSpiAspspDataProviderFor(consent.getId()) : null;

        FundsConfirmationResponse response = executeRequest(psuIdData, consent, request, aspspConsentDataProvider);

        if (response.hasError()) {
            ErrorHolder errorHolder = response.getErrorHolder();
            return ResponseObject.<FundsConfirmationResponse>builder()
                       .fail(new MessageError(errorHolder))
                       .build();
        }

        return ResponseObject.<FundsConfirmationResponse>builder()
                   .body(response)
                   .build();
    }

}