class ConsentController implements ConsentApi {

    @Override
    public ResponseEntity createConsent(UUID xRequestID, String psuIpAddress, Consents body, String digest, String signature,
                                        byte[] tppSignatureCertificate, String psuId, String psuIdType, String psuCorporateId,
                                        String psuCorporateIdType, Boolean tppRedirectPreferred, String tppRedirectUri, String tppNokRedirectUri,
                                        Boolean tppExplicitAuthorisationPreferred, String tppBrandLoggingInformation,
                                        String tppNotificationUri, String tppNotificationContentPreferred, String psuIpPort,
                                        String psuAccept, String psuAcceptCharset, String psuAcceptEncoding,
                                        String psuAcceptLanguage, String psuUserAgent, String psuHttpMethod,
                                        UUID psuDeviceId, String psuGeoLocation) {

        TppRedirectUri xs2aTppRedirectUri = tppRedirectUriMapper.mapToTppRedirectUri(tppRedirectUri, tppNokRedirectUri);
        TppNotificationData tppNotificationData = notificationSupportedModeService.getTppNotificationData(tppNotificationContentPreferred, tppNotificationUri);

        CreateConsentReq createConsent = consentModelMapper.mapToCreateConsentReq(body, xs2aTppRedirectUri, tppNotificationData, tppBrandLoggingInformation,
                                                                                  requestProviderService.getInstanceId());

        PsuIdData psuData = new PsuIdData(psuId, psuIdType, psuCorporateId, psuCorporateIdType, psuIpAddress,
                                          new AdditionalPsuIdData(psuIpPort, psuUserAgent, psuGeoLocation, psuAccept, psuAcceptCharset, psuAcceptEncoding, psuAcceptLanguage, psuHttpMethod, psuDeviceId));

        ResponseObject<CreateConsentResponse> createResponse =
            consentService.createAccountConsentsWithResponse(createConsent, psuData, BooleanUtils.isTrue(tppExplicitAuthorisationPreferred));

        if (createResponse.hasError()) {
            return responseErrorMapper.generateErrorResponse(createResponse.getError());
        }

        CreateConsentResponse createConsentResponse = createResponse.getBody();
        NotificationModeResponseHeaders notificationHeaders = notificationSupportedModeService.resolveNotificationHeaders(createConsentResponse.getTppNotificationContentPreferred());

        ResponseHeaders headers = consentHeadersBuilder.buildCreateConsentHeaders(createConsentResponse.getAuthorizationId(),
                                                                                  Optional.ofNullable(createConsentResponse.getLinks().getSelf())
                                                                                      .map(HrefType::getHref)
                                                                                      .orElseThrow(() -> new IllegalArgumentException("Wrong href type in self link")),
                                                                                  notificationHeaders);

        return responseMapper.created(createResponse, consentModelMapper::mapToConsentsResponse201, headers);
    }

}