class AccountListService {

    public ResponseObject<Xs2aAccountListHolder> getAccountList(String consentId, boolean withBalance, String requestUri) {
        xs2aEventService.recordConsentTppRequest(consentId, EventType.READ_ACCOUNT_LIST_REQUEST_RECEIVED);

        Optional<AisConsent> aisConsentOptional = aisConsentService.getAccountConsentById(consentId);

        if (aisConsentOptional.isEmpty()) {
            log.info("Consent-ID [{}]. Get account list failed. Account consent not found by id", consentId);
            return ResponseObject.<Xs2aAccountListHolder>builder()
                       .fail(AIS_400, TppMessageInformation.of(CONSENT_UNKNOWN_400))
                       .build();
        }

        AisConsent aisConsent = aisConsentOptional.get();

        ValidationResult validationResult = getValidationResultForGetAccountListConsent(withBalance, requestUri, aisConsent);

        if (validationResult.isNotValid()) {
            log.info("Consent-ID [{}], WithBalance [{}], RequestUri [{}]. Get account list - validation failed: {}",
                     consentId, withBalance, requestUri, validationResult.getMessageError());
            return ResponseObject.<Xs2aAccountListHolder>builder()
                       .fail(validationResult.getMessageError())
                       .build();
        }

        SpiResponse<List<SpiAccountDetails>> spiResponse = getSpiResponse(aisConsent, consentId, withBalance);

        if (spiResponse.hasError()) {
            ErrorHolder errorHolder = spiErrorMapper.mapToErrorHolder(spiResponse, ServiceType.AIS);
            log.info("Consent-ID: [{}]. Get account list failed: couldn't get accounts. Error msg: [{}]",
                     consentId, errorHolder);
            return ResponseObject.<Xs2aAccountListHolder>builder()
                       .fail(new MessageError(errorHolder))
                       .build();
        }

        List<Xs2aAccountDetails> accountDetails = accountDetailsMapper.mapToXs2aAccountDetailsList(spiResponse.getPayload());

        CmsResponse<AisConsent> aisConsentUpdated =
            accountReferenceUpdater.updateAccountReferences(consentId, aisConsent, accountDetails);

        if (aisConsentUpdated.hasError()) {
            log.info("Consent-ID: [{}]. Get account list failed: couldn't update account consent access.", consentId);

            if (CmsError.CHECKSUM_ERROR == aisConsentUpdated.getError()) {
                return ResponseObject.<Xs2aAccountListHolder>builder()
                           .fail(AIS_500, TppMessageInformation.of(CONSENT_VALIDATION_FAILED))
                           .build();
            }

            return ResponseObject.<Xs2aAccountListHolder>builder()
                       .fail(AIS_400, TppMessageInformation.of(CONSENT_UNKNOWN_400))
                       .build();
        }

        loggingContextService.storeConsentStatus(aisConsent.getConsentStatus());

        return getXs2aAccountListHolderResponseObject(consentId, withBalance, requestUri, aisConsentUpdated.getPayload(), accountDetails);
    }

}