<?php

declare(strict_types=1);

namespace AmazonPHP\SellingPartner\Api\ProductPricingApi;

use AmazonPHP\SellingPartner\AccessToken;
use AmazonPHP\SellingPartner\Configuration;
use AmazonPHP\SellingPartner\Exception\ApiException;
use AmazonPHP\SellingPartner\Exception\InvalidArgumentException;
use AmazonPHP\SellingPartner\HttpFactory;
use AmazonPHP\SellingPartner\HttpSignatureHeaders;
use AmazonPHP\SellingPartner\ObjectSerializer;
use Psr\Http\Client\ClientExceptionInterface;
use Psr\Http\Client\ClientInterface;
use Psr\Http\Message\RequestInterface;
use Psr\Log\LoggerInterface;

/**
 * Selling Partner API for Pricing.
 *
 * The Selling Partner API for Pricing helps you programmatically retrieve product pricing and offer information for Amazon Marketplace products.
 *
 * The version of the OpenAPI document: v0
 *
 * This class was auto-generated by https://openapi-generator.tech
 * Do not change it, it will be overwritten with next execution of /bin/generate.sh
 */
final class ProductPricingSDK implements ProductPricingSDKInterface
{
    public function __construct(private readonly ClientInterface $client, private readonly HttpFactory $httpFactory, private readonly Configuration $configuration, private readonly LoggerInterface $logger)
    {
    }

    /**
     * Operation getCompetitivePricing.
     *
     * @param string $marketplace_id A marketplace identifier. Specifies the marketplace for which prices are returned. (required)
     * @param string $item_type Indicates whether ASIN values or seller SKU values are used to identify items. If you specify Asin, the information in the response will be dependent on the list of Asins you provide in the Asins parameter. If you specify Sku, the information in the response will be dependent on the list of Skus you provide in the Skus parameter. Possible values: Asin, Sku. (required)
     * @param null|string[] $asins A list of up to twenty Amazon Standard Identification Number (ASIN) values used to identify items in the given marketplace. (optional)
     * @param null|string[] $skus A list of up to twenty seller SKU values used to identify items in the given marketplace. (optional)
     * @param null|string $customer_type Indicates whether to request pricing information from the point of view of Consumer or Business buyers. Default is Consumer. (optional)
     *
     * @throws ApiException on non-2xx response
     * @throws InvalidArgumentException
     */
    public function getCompetitivePricing(AccessToken $accessToken, string $region, string $marketplace_id, string $item_type, ?array $asins = null, ?array $skus = null, ?string $customer_type = null) : \AmazonPHP\SellingPartner\Model\ProductPricing\GetPricingResponse
    {
        $request = $this->getCompetitivePricingRequest($accessToken, $region, $marketplace_id, $item_type, $asins, $skus, $customer_type);

        $this->configuration->extensions()->preRequest('ProductPricing', 'getCompetitivePricing', $request);

        try {
            $correlationId = $this->configuration->idGenerator()->generate();

            if ($this->configuration->loggingEnabled('ProductPricing', 'getCompetitivePricing')) {
                $sanitizedRequest = $request;

                foreach ($this->configuration->loggingSkipHeaders() as $sensitiveHeader) {
                    $sanitizedRequest = $sanitizedRequest->withoutHeader($sensitiveHeader);
                }

                $this->logger->log(
                    $this->configuration->logLevel('ProductPricing', 'getCompetitivePricing'),
                    'Amazon Selling Partner API pre request',
                    [
                        'api' => 'ProductPricing',
                        'operation' => 'getCompetitivePricing',
                        'request_correlation_id' => $correlationId,
                        'request_body' => (string) $sanitizedRequest->getBody(),
                        'request_headers' => $sanitizedRequest->getHeaders(),
                        'request_uri' => (string) $sanitizedRequest->getUri(),
                    ]
                );
            }

            $response = $this->client->sendRequest($request);

            $this->configuration->extensions()->postRequest('ProductPricing', 'getCompetitivePricing', $request, $response);

            if ($this->configuration->loggingEnabled('ProductPricing', 'getCompetitivePricing')) {
                $sanitizedResponse = $response;

                foreach ($this->configuration->loggingSkipHeaders() as $sensitiveHeader) {
                    $sanitizedResponse = $sanitizedResponse->withoutHeader($sensitiveHeader);
                }

                $this->logger->log(
                    $this->configuration->logLevel('ProductPricing', 'getCompetitivePricing'),
                    'Amazon Selling Partner API post request',
                    [
                        'api' => 'ProductPricing',
                        'operation' => 'getCompetitivePricing',
                        'response_correlation_id' => $correlationId,
                        'response_body' => (string) $sanitizedResponse->getBody(),
                        'response_headers' => $sanitizedResponse->getHeaders(),
                        'response_status_code' => $sanitizedResponse->getStatusCode(),
                    ]
                );
            }
        } catch (ClientExceptionInterface $e) {
            throw new ApiException(
                "[{$e->getCode()}] {$e->getMessage()}",
                (int) $e->getCode(),
                null,
                null,
                $e
            );
        }

        $statusCode = $response->getStatusCode();

        if ($statusCode < 200 || $statusCode > 299) {
            throw new ApiException(
                \sprintf(
                    '[%d] Error connecting to the API (%s)',
                    $statusCode,
                    (string) $request->getUri()
                ),
                $statusCode,
                $response->getHeaders(),
                (string) $response->getBody()
            );
        }

        return ObjectSerializer::deserialize(
            $this->configuration,
            (string) $response->getBody(),
            '\AmazonPHP\SellingPartner\Model\ProductPricing\GetPricingResponse',
            []
        );
    }

    /**
     * Create request for operation 'getCompetitivePricing'.
     *
     * @param string $marketplace_id A marketplace identifier. Specifies the marketplace for which prices are returned. (required)
     * @param string $item_type Indicates whether ASIN values or seller SKU values are used to identify items. If you specify Asin, the information in the response will be dependent on the list of Asins you provide in the Asins parameter. If you specify Sku, the information in the response will be dependent on the list of Skus you provide in the Skus parameter. Possible values: Asin, Sku. (required)
     * @param null|string[] $asins A list of up to twenty Amazon Standard Identification Number (ASIN) values used to identify items in the given marketplace. (optional)
     * @param null|string[] $skus A list of up to twenty seller SKU values used to identify items in the given marketplace. (optional)
     * @param null|string $customer_type Indicates whether to request pricing information from the point of view of Consumer or Business buyers. Default is Consumer. (optional)
     *
     * @throws \AmazonPHP\SellingPartner\Exception\InvalidArgumentException
     */
    public function getCompetitivePricingRequest(AccessToken $accessToken, string $region, string $marketplace_id, string $item_type, ?array $asins = null, ?array $skus = null, ?string $customer_type = null) : RequestInterface
    {
        // verify the required parameter 'marketplace_id' is set
        if ($marketplace_id === null || (\is_array($marketplace_id) && \count($marketplace_id) === 0)) {
            throw new InvalidArgumentException(
                'Missing the required parameter $marketplace_id when calling getCompetitivePricing'
            );
        }
        // verify the required parameter 'item_type' is set
        if ($item_type === null || (\is_array($item_type) && \count($item_type) === 0)) {
            throw new InvalidArgumentException(
                'Missing the required parameter $item_type when calling getCompetitivePricing'
            );
        }

        if ($asins !== null && \count($asins) > 20) {
            throw new InvalidArgumentException('invalid value for "$asins" when calling ProductPricingApi.getCompetitivePricing, number of items must be less than or equal to 20.');
        }

        if ($skus !== null && \count($skus) > 20) {
            throw new InvalidArgumentException('invalid value for "$skus" when calling ProductPricingApi.getCompetitivePricing, number of items must be less than or equal to 20.');
        }

        $resourcePath = '/products/pricing/v0/competitivePrice';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $multipart = false;
        $query = '';

        // query params
        if (\is_array($marketplace_id)) {
            $marketplace_id = ObjectSerializer::serializeCollection($marketplace_id, '', true);
        }

        if ($marketplace_id !== null) {
            $queryParams['MarketplaceId'] = ObjectSerializer::toString($marketplace_id);
        }
        // query params
        if (\is_array($asins)) {
            $asins = ObjectSerializer::serializeCollection($asins, 'form', true);
        }

        if ($asins !== null) {
            $queryParams['Asins'] = ObjectSerializer::toString($asins);
        }
        // query params
        if (\is_array($skus)) {
            $skus = ObjectSerializer::serializeCollection($skus, 'form', true);
        }

        if ($skus !== null) {
            $queryParams['Skus'] = ObjectSerializer::toString($skus);
        }
        // query params
        if (\is_array($item_type)) {
            $item_type = ObjectSerializer::serializeCollection($item_type, '', true);
        }

        if ($item_type !== null) {
            $queryParams['ItemType'] = ObjectSerializer::toString($item_type);
        }
        // query params
        if (\is_array($customer_type)) {
            $customer_type = ObjectSerializer::serializeCollection($customer_type, '', true);
        }

        if ($customer_type !== null) {
            $queryParams['CustomerType'] = ObjectSerializer::toString($customer_type);
        }

        if (\count($queryParams)) {
            $query = \http_build_query($queryParams);
        }

        if ($multipart) {
            $headers = [
                'accept' => ['application/json'],
                'host' => [$this->configuration->apiHost($region)],
                'user-agent' => [$this->configuration->userAgent()],
            ];
        } else {
            $headers = [
                'content-type' => ['application/json'],
                'accept' => ['application/json'],
                'host' => [$this->configuration->apiHost($region)],
                'user-agent' => [$this->configuration->userAgent()],
            ];
        }

        $request = $this->httpFactory->createRequest(
            'GET',
            $this->configuration->apiURL($region) . $resourcePath . '?' . $query
        );

        // for model (json/xml)
        if (\count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [];

                foreach ($formParams as $formParamName => $formParamValue) {
                    $formParamValueItems = \is_array($formParamValue) ? $formParamValue : [$formParamValue];

                    foreach ($formParamValueItems as $formParamValueItem) {
                        $multipartContents[] = [
                            'name' => $formParamName,
                            'contents' => $formParamValueItem,
                        ];
                    }
                }
                $request = $request->withParsedBody($multipartContents);
            } elseif ($headers['content-type'] === ['application/json']) {
                $request = $request->withBody($this->httpFactory->createStreamFromString(\json_encode($formParams, JSON_THROW_ON_ERROR)));
            } else {
                $request = $request->withParsedBody($formParams);
            }
        }

        foreach (\array_merge($headerParams, $headers) as $name => $header) {
            $request = $request->withHeader($name, $header);
        }

        return HttpSignatureHeaders::forConfig(
            $this->configuration,
            $accessToken,
            $region,
            $request
        );
    }

    /**
     * Operation getItemOffers.
     *
     * @param string $marketplace_id A marketplace identifier. Specifies the marketplace for which prices are returned. (required)
     * @param string $item_condition Filters the offer listings to be considered based on item condition. Possible values: New, Used, Collectible, Refurbished, Club. (required)
     * @param string $asin The Amazon Standard Identification Number (ASIN) of the item. (required)
     * @param null|string $customer_type Indicates whether to request Consumer or Business offers. Default is Consumer. (optional)
     *
     * @throws ApiException on non-2xx response
     * @throws InvalidArgumentException
     */
    public function getItemOffers(AccessToken $accessToken, string $region, string $marketplace_id, string $item_condition, string $asin, ?string $customer_type = null) : \AmazonPHP\SellingPartner\Model\ProductPricing\GetOffersResponse
    {
        $request = $this->getItemOffersRequest($accessToken, $region, $marketplace_id, $item_condition, $asin, $customer_type);

        $this->configuration->extensions()->preRequest('ProductPricing', 'getItemOffers', $request);

        try {
            $correlationId = $this->configuration->idGenerator()->generate();

            if ($this->configuration->loggingEnabled('ProductPricing', 'getItemOffers')) {
                $sanitizedRequest = $request;

                foreach ($this->configuration->loggingSkipHeaders() as $sensitiveHeader) {
                    $sanitizedRequest = $sanitizedRequest->withoutHeader($sensitiveHeader);
                }

                $this->logger->log(
                    $this->configuration->logLevel('ProductPricing', 'getItemOffers'),
                    'Amazon Selling Partner API pre request',
                    [
                        'api' => 'ProductPricing',
                        'operation' => 'getItemOffers',
                        'request_correlation_id' => $correlationId,
                        'request_body' => (string) $sanitizedRequest->getBody(),
                        'request_headers' => $sanitizedRequest->getHeaders(),
                        'request_uri' => (string) $sanitizedRequest->getUri(),
                    ]
                );
            }

            $response = $this->client->sendRequest($request);

            $this->configuration->extensions()->postRequest('ProductPricing', 'getItemOffers', $request, $response);

            if ($this->configuration->loggingEnabled('ProductPricing', 'getItemOffers')) {
                $sanitizedResponse = $response;

                foreach ($this->configuration->loggingSkipHeaders() as $sensitiveHeader) {
                    $sanitizedResponse = $sanitizedResponse->withoutHeader($sensitiveHeader);
                }

                $this->logger->log(
                    $this->configuration->logLevel('ProductPricing', 'getItemOffers'),
                    'Amazon Selling Partner API post request',
                    [
                        'api' => 'ProductPricing',
                        'operation' => 'getItemOffers',
                        'response_correlation_id' => $correlationId,
                        'response_body' => (string) $sanitizedResponse->getBody(),
                        'response_headers' => $sanitizedResponse->getHeaders(),
                        'response_status_code' => $sanitizedResponse->getStatusCode(),
                    ]
                );
            }
        } catch (ClientExceptionInterface $e) {
            throw new ApiException(
                "[{$e->getCode()}] {$e->getMessage()}",
                (int) $e->getCode(),
                null,
                null,
                $e
            );
        }

        $statusCode = $response->getStatusCode();

        if ($statusCode < 200 || $statusCode > 299) {
            throw new ApiException(
                \sprintf(
                    '[%d] Error connecting to the API (%s)',
                    $statusCode,
                    (string) $request->getUri()
                ),
                $statusCode,
                $response->getHeaders(),
                (string) $response->getBody()
            );
        }

        return ObjectSerializer::deserialize(
            $this->configuration,
            (string) $response->getBody(),
            '\AmazonPHP\SellingPartner\Model\ProductPricing\GetOffersResponse',
            []
        );
    }

    /**
     * Create request for operation 'getItemOffers'.
     *
     * @param string $marketplace_id A marketplace identifier. Specifies the marketplace for which prices are returned. (required)
     * @param string $item_condition Filters the offer listings to be considered based on item condition. Possible values: New, Used, Collectible, Refurbished, Club. (required)
     * @param string $asin The Amazon Standard Identification Number (ASIN) of the item. (required)
     * @param null|string $customer_type Indicates whether to request Consumer or Business offers. Default is Consumer. (optional)
     *
     * @throws \AmazonPHP\SellingPartner\Exception\InvalidArgumentException
     */
    public function getItemOffersRequest(AccessToken $accessToken, string $region, string $marketplace_id, string $item_condition, string $asin, ?string $customer_type = null) : RequestInterface
    {
        // verify the required parameter 'marketplace_id' is set
        if ($marketplace_id === null || (\is_array($marketplace_id) && \count($marketplace_id) === 0)) {
            throw new InvalidArgumentException(
                'Missing the required parameter $marketplace_id when calling getItemOffers'
            );
        }
        // verify the required parameter 'item_condition' is set
        if ($item_condition === null || (\is_array($item_condition) && \count($item_condition) === 0)) {
            throw new InvalidArgumentException(
                'Missing the required parameter $item_condition when calling getItemOffers'
            );
        }
        // verify the required parameter 'asin' is set
        if ($asin === null || (\is_array($asin) && \count($asin) === 0)) {
            throw new InvalidArgumentException(
                'Missing the required parameter $asin when calling getItemOffers'
            );
        }

        $resourcePath = '/products/pricing/v0/items/{Asin}/offers';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $multipart = false;
        $query = '';

        // query params
        if (\is_array($marketplace_id)) {
            $marketplace_id = ObjectSerializer::serializeCollection($marketplace_id, '', true);
        }

        if ($marketplace_id !== null) {
            $queryParams['MarketplaceId'] = ObjectSerializer::toString($marketplace_id);
        }
        // query params
        if (\is_array($item_condition)) {
            $item_condition = ObjectSerializer::serializeCollection($item_condition, '', true);
        }

        if ($item_condition !== null) {
            $queryParams['ItemCondition'] = ObjectSerializer::toString($item_condition);
        }
        // query params
        if (\is_array($customer_type)) {
            $customer_type = ObjectSerializer::serializeCollection($customer_type, '', true);
        }

        if ($customer_type !== null) {
            $queryParams['CustomerType'] = ObjectSerializer::toString($customer_type);
        }

        if (\count($queryParams)) {
            $query = \http_build_query($queryParams);
        }

        // path params
        if ($asin !== null) {
            $resourcePath = \str_replace(
                '{' . 'Asin' . '}',
                ObjectSerializer::toPathValue($asin),
                $resourcePath
            );
        }

        if ($multipart) {
            $headers = [
                'accept' => ['application/json'],
                'host' => [$this->configuration->apiHost($region)],
                'user-agent' => [$this->configuration->userAgent()],
            ];
        } else {
            $headers = [
                'content-type' => ['application/json'],
                'accept' => ['application/json'],
                'host' => [$this->configuration->apiHost($region)],
                'user-agent' => [$this->configuration->userAgent()],
            ];
        }

        $request = $this->httpFactory->createRequest(
            'GET',
            $this->configuration->apiURL($region) . $resourcePath . '?' . $query
        );

        // for model (json/xml)
        if (\count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [];

                foreach ($formParams as $formParamName => $formParamValue) {
                    $formParamValueItems = \is_array($formParamValue) ? $formParamValue : [$formParamValue];

                    foreach ($formParamValueItems as $formParamValueItem) {
                        $multipartContents[] = [
                            'name' => $formParamName,
                            'contents' => $formParamValueItem,
                        ];
                    }
                }
                $request = $request->withParsedBody($multipartContents);
            } elseif ($headers['content-type'] === ['application/json']) {
                $request = $request->withBody($this->httpFactory->createStreamFromString(\json_encode($formParams, JSON_THROW_ON_ERROR)));
            } else {
                $request = $request->withParsedBody($formParams);
            }
        }

        foreach (\array_merge($headerParams, $headers) as $name => $header) {
            $request = $request->withHeader($name, $header);
        }

        return HttpSignatureHeaders::forConfig(
            $this->configuration,
            $accessToken,
            $region,
            $request
        );
    }

    /**
     * Operation getItemOffersBatch.
     *
     * @param \AmazonPHP\SellingPartner\Model\ProductPricing\GetItemOffersBatchRequest $get_item_offers_batch_request_body get_item_offers_batch_request_body (required)
     *
     * @throws ApiException on non-2xx response
     * @throws InvalidArgumentException
     */
    public function getItemOffersBatch(AccessToken $accessToken, string $region, \AmazonPHP\SellingPartner\Model\ProductPricing\GetItemOffersBatchRequest $get_item_offers_batch_request_body) : \AmazonPHP\SellingPartner\Model\ProductPricing\GetItemOffersBatchResponse
    {
        $request = $this->getItemOffersBatchRequest($accessToken, $region, $get_item_offers_batch_request_body);

        $this->configuration->extensions()->preRequest('ProductPricing', 'getItemOffersBatch', $request);

        try {
            $correlationId = $this->configuration->idGenerator()->generate();

            if ($this->configuration->loggingEnabled('ProductPricing', 'getItemOffersBatch')) {
                $sanitizedRequest = $request;

                foreach ($this->configuration->loggingSkipHeaders() as $sensitiveHeader) {
                    $sanitizedRequest = $sanitizedRequest->withoutHeader($sensitiveHeader);
                }

                $this->logger->log(
                    $this->configuration->logLevel('ProductPricing', 'getItemOffersBatch'),
                    'Amazon Selling Partner API pre request',
                    [
                        'api' => 'ProductPricing',
                        'operation' => 'getItemOffersBatch',
                        'request_correlation_id' => $correlationId,
                        'request_body' => (string) $sanitizedRequest->getBody(),
                        'request_headers' => $sanitizedRequest->getHeaders(),
                        'request_uri' => (string) $sanitizedRequest->getUri(),
                    ]
                );
            }

            $response = $this->client->sendRequest($request);

            $this->configuration->extensions()->postRequest('ProductPricing', 'getItemOffersBatch', $request, $response);

            if ($this->configuration->loggingEnabled('ProductPricing', 'getItemOffersBatch')) {
                $sanitizedResponse = $response;

                foreach ($this->configuration->loggingSkipHeaders() as $sensitiveHeader) {
                    $sanitizedResponse = $sanitizedResponse->withoutHeader($sensitiveHeader);
                }

                $this->logger->log(
                    $this->configuration->logLevel('ProductPricing', 'getItemOffersBatch'),
                    'Amazon Selling Partner API post request',
                    [
                        'api' => 'ProductPricing',
                        'operation' => 'getItemOffersBatch',
                        'response_correlation_id' => $correlationId,
                        'response_body' => (string) $sanitizedResponse->getBody(),
                        'response_headers' => $sanitizedResponse->getHeaders(),
                        'response_status_code' => $sanitizedResponse->getStatusCode(),
                    ]
                );
            }
        } catch (ClientExceptionInterface $e) {
            throw new ApiException(
                "[{$e->getCode()}] {$e->getMessage()}",
                (int) $e->getCode(),
                null,
                null,
                $e
            );
        }

        $statusCode = $response->getStatusCode();

        if ($statusCode < 200 || $statusCode > 299) {
            throw new ApiException(
                \sprintf(
                    '[%d] Error connecting to the API (%s)',
                    $statusCode,
                    (string) $request->getUri()
                ),
                $statusCode,
                $response->getHeaders(),
                (string) $response->getBody()
            );
        }

        return ObjectSerializer::deserialize(
            $this->configuration,
            (string) $response->getBody(),
            '\AmazonPHP\SellingPartner\Model\ProductPricing\GetItemOffersBatchResponse',
            []
        );
    }

    /**
     * Create request for operation 'getItemOffersBatch'.
     *
     * @param \AmazonPHP\SellingPartner\Model\ProductPricing\GetItemOffersBatchRequest $get_item_offers_batch_request_body (required)
     *
     * @throws \AmazonPHP\SellingPartner\Exception\InvalidArgumentException
     */
    public function getItemOffersBatchRequest(AccessToken $accessToken, string $region, \AmazonPHP\SellingPartner\Model\ProductPricing\GetItemOffersBatchRequest $get_item_offers_batch_request_body) : RequestInterface
    {
        // verify the required parameter 'get_item_offers_batch_request_body' is set
        if ($get_item_offers_batch_request_body === null || (\is_array($get_item_offers_batch_request_body) && \count($get_item_offers_batch_request_body) === 0)) {
            throw new InvalidArgumentException(
                'Missing the required parameter $get_item_offers_batch_request_body when calling getItemOffersBatch'
            );
        }

        $resourcePath = '/batches/products/pricing/v0/itemOffers';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $multipart = false;
        $query = '';

        if (\count($queryParams)) {
            $query = \http_build_query($queryParams);
        }

        if ($multipart) {
            $headers = [
                'accept' => ['application/json'],
                'host' => [$this->configuration->apiHost($region)],
                'user-agent' => [$this->configuration->userAgent()],
            ];
        } else {
            $headers = [
                'content-type' => ['application/json'],
                'accept' => ['application/json'],
                'host' => [$this->configuration->apiHost($region)],
                'user-agent' => [$this->configuration->userAgent()],
            ];
        }

        $request = $this->httpFactory->createRequest(
            'POST',
            $this->configuration->apiURL($region) . $resourcePath . '?' . $query
        );

        // for model (json/xml)
        if (isset($get_item_offers_batch_request_body)) {
            if ($headers['content-type'] === ['application/json']) {
                $httpBody = \json_encode(ObjectSerializer::sanitizeForSerialization($get_item_offers_batch_request_body), JSON_THROW_ON_ERROR);
            } else {
                $httpBody = $get_item_offers_batch_request_body;
            }

            $request = $request->withBody($this->httpFactory->createStreamFromString($httpBody));
        } elseif (\count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [];

                foreach ($formParams as $formParamName => $formParamValue) {
                    $formParamValueItems = \is_array($formParamValue) ? $formParamValue : [$formParamValue];

                    foreach ($formParamValueItems as $formParamValueItem) {
                        $multipartContents[] = [
                            'name' => $formParamName,
                            'contents' => $formParamValueItem,
                        ];
                    }
                }
                $request = $request->withParsedBody($multipartContents);
            } elseif ($headers['content-type'] === ['application/json']) {
                $request = $request->withBody($this->httpFactory->createStreamFromString(\json_encode($formParams, JSON_THROW_ON_ERROR)));
            } else {
                $request = $request->withParsedBody($formParams);
            }
        }

        foreach (\array_merge($headerParams, $headers) as $name => $header) {
            $request = $request->withHeader($name, $header);
        }

        return HttpSignatureHeaders::forConfig(
            $this->configuration,
            $accessToken,
            $region,
            $request
        );
    }

    /**
     * Operation getListingOffers.
     *
     * @param string $marketplace_id A marketplace identifier. Specifies the marketplace for which prices are returned. (required)
     * @param string $item_condition Filters the offer listings based on item condition. Possible values: New, Used, Collectible, Refurbished, Club. (required)
     * @param string $seller_sku Identifies an item in the given marketplace. SellerSKU is qualified by the seller&#39;s SellerId, which is included with every operation that you submit. (required)
     * @param null|string $customer_type Indicates whether to request Consumer or Business offers. Default is Consumer. (optional)
     *
     * @throws ApiException on non-2xx response
     * @throws InvalidArgumentException
     */
    public function getListingOffers(AccessToken $accessToken, string $region, string $marketplace_id, string $item_condition, string $seller_sku, ?string $customer_type = null) : \AmazonPHP\SellingPartner\Model\ProductPricing\GetOffersResponse
    {
        $request = $this->getListingOffersRequest($accessToken, $region, $marketplace_id, $item_condition, $seller_sku, $customer_type);

        $this->configuration->extensions()->preRequest('ProductPricing', 'getListingOffers', $request);

        try {
            $correlationId = $this->configuration->idGenerator()->generate();

            if ($this->configuration->loggingEnabled('ProductPricing', 'getListingOffers')) {
                $sanitizedRequest = $request;

                foreach ($this->configuration->loggingSkipHeaders() as $sensitiveHeader) {
                    $sanitizedRequest = $sanitizedRequest->withoutHeader($sensitiveHeader);
                }

                $this->logger->log(
                    $this->configuration->logLevel('ProductPricing', 'getListingOffers'),
                    'Amazon Selling Partner API pre request',
                    [
                        'api' => 'ProductPricing',
                        'operation' => 'getListingOffers',
                        'request_correlation_id' => $correlationId,
                        'request_body' => (string) $sanitizedRequest->getBody(),
                        'request_headers' => $sanitizedRequest->getHeaders(),
                        'request_uri' => (string) $sanitizedRequest->getUri(),
                    ]
                );
            }

            $response = $this->client->sendRequest($request);

            $this->configuration->extensions()->postRequest('ProductPricing', 'getListingOffers', $request, $response);

            if ($this->configuration->loggingEnabled('ProductPricing', 'getListingOffers')) {
                $sanitizedResponse = $response;

                foreach ($this->configuration->loggingSkipHeaders() as $sensitiveHeader) {
                    $sanitizedResponse = $sanitizedResponse->withoutHeader($sensitiveHeader);
                }

                $this->logger->log(
                    $this->configuration->logLevel('ProductPricing', 'getListingOffers'),
                    'Amazon Selling Partner API post request',
                    [
                        'api' => 'ProductPricing',
                        'operation' => 'getListingOffers',
                        'response_correlation_id' => $correlationId,
                        'response_body' => (string) $sanitizedResponse->getBody(),
                        'response_headers' => $sanitizedResponse->getHeaders(),
                        'response_status_code' => $sanitizedResponse->getStatusCode(),
                    ]
                );
            }
        } catch (ClientExceptionInterface $e) {
            throw new ApiException(
                "[{$e->getCode()}] {$e->getMessage()}",
                (int) $e->getCode(),
                null,
                null,
                $e
            );
        }

        $statusCode = $response->getStatusCode();

        if ($statusCode < 200 || $statusCode > 299) {
            throw new ApiException(
                \sprintf(
                    '[%d] Error connecting to the API (%s)',
                    $statusCode,
                    (string) $request->getUri()
                ),
                $statusCode,
                $response->getHeaders(),
                (string) $response->getBody()
            );
        }

        return ObjectSerializer::deserialize(
            $this->configuration,
            (string) $response->getBody(),
            '\AmazonPHP\SellingPartner\Model\ProductPricing\GetOffersResponse',
            []
        );
    }

    /**
     * Create request for operation 'getListingOffers'.
     *
     * @param string $marketplace_id A marketplace identifier. Specifies the marketplace for which prices are returned. (required)
     * @param string $item_condition Filters the offer listings based on item condition. Possible values: New, Used, Collectible, Refurbished, Club. (required)
     * @param string $seller_sku Identifies an item in the given marketplace. SellerSKU is qualified by the seller&#39;s SellerId, which is included with every operation that you submit. (required)
     * @param null|string $customer_type Indicates whether to request Consumer or Business offers. Default is Consumer. (optional)
     *
     * @throws \AmazonPHP\SellingPartner\Exception\InvalidArgumentException
     */
    public function getListingOffersRequest(AccessToken $accessToken, string $region, string $marketplace_id, string $item_condition, string $seller_sku, ?string $customer_type = null) : RequestInterface
    {
        // verify the required parameter 'marketplace_id' is set
        if ($marketplace_id === null || (\is_array($marketplace_id) && \count($marketplace_id) === 0)) {
            throw new InvalidArgumentException(
                'Missing the required parameter $marketplace_id when calling getListingOffers'
            );
        }
        // verify the required parameter 'item_condition' is set
        if ($item_condition === null || (\is_array($item_condition) && \count($item_condition) === 0)) {
            throw new InvalidArgumentException(
                'Missing the required parameter $item_condition when calling getListingOffers'
            );
        }
        // verify the required parameter 'seller_sku' is set
        if ($seller_sku === null || (\is_array($seller_sku) && \count($seller_sku) === 0)) {
            throw new InvalidArgumentException(
                'Missing the required parameter $seller_sku when calling getListingOffers'
            );
        }

        $resourcePath = '/products/pricing/v0/listings/{SellerSKU}/offers';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $multipart = false;
        $query = '';

        // query params
        if (\is_array($marketplace_id)) {
            $marketplace_id = ObjectSerializer::serializeCollection($marketplace_id, '', true);
        }

        if ($marketplace_id !== null) {
            $queryParams['MarketplaceId'] = ObjectSerializer::toString($marketplace_id);
        }
        // query params
        if (\is_array($item_condition)) {
            $item_condition = ObjectSerializer::serializeCollection($item_condition, '', true);
        }

        if ($item_condition !== null) {
            $queryParams['ItemCondition'] = ObjectSerializer::toString($item_condition);
        }
        // query params
        if (\is_array($customer_type)) {
            $customer_type = ObjectSerializer::serializeCollection($customer_type, '', true);
        }

        if ($customer_type !== null) {
            $queryParams['CustomerType'] = ObjectSerializer::toString($customer_type);
        }

        if (\count($queryParams)) {
            $query = \http_build_query($queryParams);
        }

        // path params
        if ($seller_sku !== null) {
            $resourcePath = \str_replace(
                '{' . 'SellerSKU' . '}',
                ObjectSerializer::toPathValue($seller_sku),
                $resourcePath
            );
        }

        if ($multipart) {
            $headers = [
                'accept' => ['application/json'],
                'host' => [$this->configuration->apiHost($region)],
                'user-agent' => [$this->configuration->userAgent()],
            ];
        } else {
            $headers = [
                'content-type' => ['application/json'],
                'accept' => ['application/json'],
                'host' => [$this->configuration->apiHost($region)],
                'user-agent' => [$this->configuration->userAgent()],
            ];
        }

        $request = $this->httpFactory->createRequest(
            'GET',
            $this->configuration->apiURL($region) . $resourcePath . '?' . $query
        );

        // for model (json/xml)
        if (\count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [];

                foreach ($formParams as $formParamName => $formParamValue) {
                    $formParamValueItems = \is_array($formParamValue) ? $formParamValue : [$formParamValue];

                    foreach ($formParamValueItems as $formParamValueItem) {
                        $multipartContents[] = [
                            'name' => $formParamName,
                            'contents' => $formParamValueItem,
                        ];
                    }
                }
                $request = $request->withParsedBody($multipartContents);
            } elseif ($headers['content-type'] === ['application/json']) {
                $request = $request->withBody($this->httpFactory->createStreamFromString(\json_encode($formParams, JSON_THROW_ON_ERROR)));
            } else {
                $request = $request->withParsedBody($formParams);
            }
        }

        foreach (\array_merge($headerParams, $headers) as $name => $header) {
            $request = $request->withHeader($name, $header);
        }

        return HttpSignatureHeaders::forConfig(
            $this->configuration,
            $accessToken,
            $region,
            $request
        );
    }

    /**
     * Operation getListingOffersBatch.
     *
     * @param \AmazonPHP\SellingPartner\Model\ProductPricing\GetListingOffersBatchRequest $get_listing_offers_batch_request_body get_listing_offers_batch_request_body (required)
     *
     * @throws ApiException on non-2xx response
     * @throws InvalidArgumentException
     */
    public function getListingOffersBatch(AccessToken $accessToken, string $region, \AmazonPHP\SellingPartner\Model\ProductPricing\GetListingOffersBatchRequest $get_listing_offers_batch_request_body) : \AmazonPHP\SellingPartner\Model\ProductPricing\GetListingOffersBatchResponse
    {
        $request = $this->getListingOffersBatchRequest($accessToken, $region, $get_listing_offers_batch_request_body);

        $this->configuration->extensions()->preRequest('ProductPricing', 'getListingOffersBatch', $request);

        try {
            $correlationId = $this->configuration->idGenerator()->generate();

            if ($this->configuration->loggingEnabled('ProductPricing', 'getListingOffersBatch')) {
                $sanitizedRequest = $request;

                foreach ($this->configuration->loggingSkipHeaders() as $sensitiveHeader) {
                    $sanitizedRequest = $sanitizedRequest->withoutHeader($sensitiveHeader);
                }

                $this->logger->log(
                    $this->configuration->logLevel('ProductPricing', 'getListingOffersBatch'),
                    'Amazon Selling Partner API pre request',
                    [
                        'api' => 'ProductPricing',
                        'operation' => 'getListingOffersBatch',
                        'request_correlation_id' => $correlationId,
                        'request_body' => (string) $sanitizedRequest->getBody(),
                        'request_headers' => $sanitizedRequest->getHeaders(),
                        'request_uri' => (string) $sanitizedRequest->getUri(),
                    ]
                );
            }

            $response = $this->client->sendRequest($request);

            $this->configuration->extensions()->postRequest('ProductPricing', 'getListingOffersBatch', $request, $response);

            if ($this->configuration->loggingEnabled('ProductPricing', 'getListingOffersBatch')) {
                $sanitizedResponse = $response;

                foreach ($this->configuration->loggingSkipHeaders() as $sensitiveHeader) {
                    $sanitizedResponse = $sanitizedResponse->withoutHeader($sensitiveHeader);
                }

                $this->logger->log(
                    $this->configuration->logLevel('ProductPricing', 'getListingOffersBatch'),
                    'Amazon Selling Partner API post request',
                    [
                        'api' => 'ProductPricing',
                        'operation' => 'getListingOffersBatch',
                        'response_correlation_id' => $correlationId,
                        'response_body' => (string) $sanitizedResponse->getBody(),
                        'response_headers' => $sanitizedResponse->getHeaders(),
                        'response_status_code' => $sanitizedResponse->getStatusCode(),
                    ]
                );
            }
        } catch (ClientExceptionInterface $e) {
            throw new ApiException(
                "[{$e->getCode()}] {$e->getMessage()}",
                (int) $e->getCode(),
                null,
                null,
                $e
            );
        }

        $statusCode = $response->getStatusCode();

        if ($statusCode < 200 || $statusCode > 299) {
            throw new ApiException(
                \sprintf(
                    '[%d] Error connecting to the API (%s)',
                    $statusCode,
                    (string) $request->getUri()
                ),
                $statusCode,
                $response->getHeaders(),
                (string) $response->getBody()
            );
        }

        return ObjectSerializer::deserialize(
            $this->configuration,
            (string) $response->getBody(),
            '\AmazonPHP\SellingPartner\Model\ProductPricing\GetListingOffersBatchResponse',
            []
        );
    }

    /**
     * Create request for operation 'getListingOffersBatch'.
     *
     * @param \AmazonPHP\SellingPartner\Model\ProductPricing\GetListingOffersBatchRequest $get_listing_offers_batch_request_body (required)
     *
     * @throws \AmazonPHP\SellingPartner\Exception\InvalidArgumentException
     */
    public function getListingOffersBatchRequest(AccessToken $accessToken, string $region, \AmazonPHP\SellingPartner\Model\ProductPricing\GetListingOffersBatchRequest $get_listing_offers_batch_request_body) : RequestInterface
    {
        // verify the required parameter 'get_listing_offers_batch_request_body' is set
        if ($get_listing_offers_batch_request_body === null || (\is_array($get_listing_offers_batch_request_body) && \count($get_listing_offers_batch_request_body) === 0)) {
            throw new InvalidArgumentException(
                'Missing the required parameter $get_listing_offers_batch_request_body when calling getListingOffersBatch'
            );
        }

        $resourcePath = '/batches/products/pricing/v0/listingOffers';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $multipart = false;
        $query = '';

        if (\count($queryParams)) {
            $query = \http_build_query($queryParams);
        }

        if ($multipart) {
            $headers = [
                'accept' => ['application/json'],
                'host' => [$this->configuration->apiHost($region)],
                'user-agent' => [$this->configuration->userAgent()],
            ];
        } else {
            $headers = [
                'content-type' => ['application/json'],
                'accept' => ['application/json'],
                'host' => [$this->configuration->apiHost($region)],
                'user-agent' => [$this->configuration->userAgent()],
            ];
        }

        $request = $this->httpFactory->createRequest(
            'POST',
            $this->configuration->apiURL($region) . $resourcePath . '?' . $query
        );

        // for model (json/xml)
        if (isset($get_listing_offers_batch_request_body)) {
            if ($headers['content-type'] === ['application/json']) {
                $httpBody = \json_encode(ObjectSerializer::sanitizeForSerialization($get_listing_offers_batch_request_body), JSON_THROW_ON_ERROR);
            } else {
                $httpBody = $get_listing_offers_batch_request_body;
            }

            $request = $request->withBody($this->httpFactory->createStreamFromString($httpBody));
        } elseif (\count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [];

                foreach ($formParams as $formParamName => $formParamValue) {
                    $formParamValueItems = \is_array($formParamValue) ? $formParamValue : [$formParamValue];

                    foreach ($formParamValueItems as $formParamValueItem) {
                        $multipartContents[] = [
                            'name' => $formParamName,
                            'contents' => $formParamValueItem,
                        ];
                    }
                }
                $request = $request->withParsedBody($multipartContents);
            } elseif ($headers['content-type'] === ['application/json']) {
                $request = $request->withBody($this->httpFactory->createStreamFromString(\json_encode($formParams, JSON_THROW_ON_ERROR)));
            } else {
                $request = $request->withParsedBody($formParams);
            }
        }

        foreach (\array_merge($headerParams, $headers) as $name => $header) {
            $request = $request->withHeader($name, $header);
        }

        return HttpSignatureHeaders::forConfig(
            $this->configuration,
            $accessToken,
            $region,
            $request
        );
    }

    /**
     * Operation getPricing.
     *
     * @param string $marketplace_id A marketplace identifier. Specifies the marketplace for which prices are returned. (required)
     * @param string $item_type Indicates whether ASIN values or seller SKU values are used to identify items. If you specify Asin, the information in the response will be dependent on the list of Asins you provide in the Asins parameter. If you specify Sku, the information in the response will be dependent on the list of Skus you provide in the Skus parameter. (required)
     * @param null|string[] $asins A list of up to twenty Amazon Standard Identification Number (ASIN) values used to identify items in the given marketplace. (optional)
     * @param null|string[] $skus A list of up to twenty seller SKU values used to identify items in the given marketplace. (optional)
     * @param null|string $item_condition Filters the offer listings based on item condition. Possible values: New, Used, Collectible, Refurbished, Club. (optional)
     * @param null|string $offer_type Indicates whether to request pricing information for the seller&#39;s B2C or B2B offers. Default is B2C. (optional)
     *
     * @throws ApiException on non-2xx response
     * @throws InvalidArgumentException
     */
    public function getPricing(AccessToken $accessToken, string $region, string $marketplace_id, string $item_type, ?array $asins = null, ?array $skus = null, ?string $item_condition = null, ?string $offer_type = null) : \AmazonPHP\SellingPartner\Model\ProductPricing\GetPricingResponse
    {
        $request = $this->getPricingRequest($accessToken, $region, $marketplace_id, $item_type, $asins, $skus, $item_condition, $offer_type);

        $this->configuration->extensions()->preRequest('ProductPricing', 'getPricing', $request);

        try {
            $correlationId = $this->configuration->idGenerator()->generate();

            if ($this->configuration->loggingEnabled('ProductPricing', 'getPricing')) {
                $sanitizedRequest = $request;

                foreach ($this->configuration->loggingSkipHeaders() as $sensitiveHeader) {
                    $sanitizedRequest = $sanitizedRequest->withoutHeader($sensitiveHeader);
                }

                $this->logger->log(
                    $this->configuration->logLevel('ProductPricing', 'getPricing'),
                    'Amazon Selling Partner API pre request',
                    [
                        'api' => 'ProductPricing',
                        'operation' => 'getPricing',
                        'request_correlation_id' => $correlationId,
                        'request_body' => (string) $sanitizedRequest->getBody(),
                        'request_headers' => $sanitizedRequest->getHeaders(),
                        'request_uri' => (string) $sanitizedRequest->getUri(),
                    ]
                );
            }

            $response = $this->client->sendRequest($request);

            $this->configuration->extensions()->postRequest('ProductPricing', 'getPricing', $request, $response);

            if ($this->configuration->loggingEnabled('ProductPricing', 'getPricing')) {
                $sanitizedResponse = $response;

                foreach ($this->configuration->loggingSkipHeaders() as $sensitiveHeader) {
                    $sanitizedResponse = $sanitizedResponse->withoutHeader($sensitiveHeader);
                }

                $this->logger->log(
                    $this->configuration->logLevel('ProductPricing', 'getPricing'),
                    'Amazon Selling Partner API post request',
                    [
                        'api' => 'ProductPricing',
                        'operation' => 'getPricing',
                        'response_correlation_id' => $correlationId,
                        'response_body' => (string) $sanitizedResponse->getBody(),
                        'response_headers' => $sanitizedResponse->getHeaders(),
                        'response_status_code' => $sanitizedResponse->getStatusCode(),
                    ]
                );
            }
        } catch (ClientExceptionInterface $e) {
            throw new ApiException(
                "[{$e->getCode()}] {$e->getMessage()}",
                (int) $e->getCode(),
                null,
                null,
                $e
            );
        }

        $statusCode = $response->getStatusCode();

        if ($statusCode < 200 || $statusCode > 299) {
            throw new ApiException(
                \sprintf(
                    '[%d] Error connecting to the API (%s)',
                    $statusCode,
                    (string) $request->getUri()
                ),
                $statusCode,
                $response->getHeaders(),
                (string) $response->getBody()
            );
        }

        return ObjectSerializer::deserialize(
            $this->configuration,
            (string) $response->getBody(),
            '\AmazonPHP\SellingPartner\Model\ProductPricing\GetPricingResponse',
            []
        );
    }

    /**
     * Create request for operation 'getPricing'.
     *
     * @param string $marketplace_id A marketplace identifier. Specifies the marketplace for which prices are returned. (required)
     * @param string $item_type Indicates whether ASIN values or seller SKU values are used to identify items. If you specify Asin, the information in the response will be dependent on the list of Asins you provide in the Asins parameter. If you specify Sku, the information in the response will be dependent on the list of Skus you provide in the Skus parameter. (required)
     * @param null|string[] $asins A list of up to twenty Amazon Standard Identification Number (ASIN) values used to identify items in the given marketplace. (optional)
     * @param null|string[] $skus A list of up to twenty seller SKU values used to identify items in the given marketplace. (optional)
     * @param null|string $item_condition Filters the offer listings based on item condition. Possible values: New, Used, Collectible, Refurbished, Club. (optional)
     * @param null|string $offer_type Indicates whether to request pricing information for the seller&#39;s B2C or B2B offers. Default is B2C. (optional)
     *
     * @throws \AmazonPHP\SellingPartner\Exception\InvalidArgumentException
     */
    public function getPricingRequest(AccessToken $accessToken, string $region, string $marketplace_id, string $item_type, ?array $asins = null, ?array $skus = null, ?string $item_condition = null, ?string $offer_type = null) : RequestInterface
    {
        // verify the required parameter 'marketplace_id' is set
        if ($marketplace_id === null || (\is_array($marketplace_id) && \count($marketplace_id) === 0)) {
            throw new InvalidArgumentException(
                'Missing the required parameter $marketplace_id when calling getPricing'
            );
        }
        // verify the required parameter 'item_type' is set
        if ($item_type === null || (\is_array($item_type) && \count($item_type) === 0)) {
            throw new InvalidArgumentException(
                'Missing the required parameter $item_type when calling getPricing'
            );
        }

        if ($asins !== null && \count($asins) > 20) {
            throw new InvalidArgumentException('invalid value for "$asins" when calling ProductPricingApi.getPricing, number of items must be less than or equal to 20.');
        }

        if ($skus !== null && \count($skus) > 20) {
            throw new InvalidArgumentException('invalid value for "$skus" when calling ProductPricingApi.getPricing, number of items must be less than or equal to 20.');
        }

        $resourcePath = '/products/pricing/v0/price';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $multipart = false;
        $query = '';

        // query params
        if (\is_array($marketplace_id)) {
            $marketplace_id = ObjectSerializer::serializeCollection($marketplace_id, '', true);
        }

        if ($marketplace_id !== null) {
            $queryParams['MarketplaceId'] = ObjectSerializer::toString($marketplace_id);
        }
        // query params
        if (\is_array($asins)) {
            $asins = ObjectSerializer::serializeCollection($asins, 'form', true);
        }

        if ($asins !== null) {
            $queryParams['Asins'] = ObjectSerializer::toString($asins);
        }
        // query params
        if (\is_array($skus)) {
            $skus = ObjectSerializer::serializeCollection($skus, 'form', true);
        }

        if ($skus !== null) {
            $queryParams['Skus'] = ObjectSerializer::toString($skus);
        }
        // query params
        if (\is_array($item_type)) {
            $item_type = ObjectSerializer::serializeCollection($item_type, '', true);
        }

        if ($item_type !== null) {
            $queryParams['ItemType'] = ObjectSerializer::toString($item_type);
        }
        // query params
        if (\is_array($item_condition)) {
            $item_condition = ObjectSerializer::serializeCollection($item_condition, '', true);
        }

        if ($item_condition !== null) {
            $queryParams['ItemCondition'] = ObjectSerializer::toString($item_condition);
        }
        // query params
        if (\is_array($offer_type)) {
            $offer_type = ObjectSerializer::serializeCollection($offer_type, '', true);
        }

        if ($offer_type !== null) {
            $queryParams['OfferType'] = ObjectSerializer::toString($offer_type);
        }

        if (\count($queryParams)) {
            $query = \http_build_query($queryParams);
        }

        if ($multipart) {
            $headers = [
                'accept' => ['application/json'],
                'host' => [$this->configuration->apiHost($region)],
                'user-agent' => [$this->configuration->userAgent()],
            ];
        } else {
            $headers = [
                'content-type' => ['application/json'],
                'accept' => ['application/json'],
                'host' => [$this->configuration->apiHost($region)],
                'user-agent' => [$this->configuration->userAgent()],
            ];
        }

        $request = $this->httpFactory->createRequest(
            'GET',
            $this->configuration->apiURL($region) . $resourcePath . '?' . $query
        );

        // for model (json/xml)
        if (\count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [];

                foreach ($formParams as $formParamName => $formParamValue) {
                    $formParamValueItems = \is_array($formParamValue) ? $formParamValue : [$formParamValue];

                    foreach ($formParamValueItems as $formParamValueItem) {
                        $multipartContents[] = [
                            'name' => $formParamName,
                            'contents' => $formParamValueItem,
                        ];
                    }
                }
                $request = $request->withParsedBody($multipartContents);
            } elseif ($headers['content-type'] === ['application/json']) {
                $request = $request->withBody($this->httpFactory->createStreamFromString(\json_encode($formParams, JSON_THROW_ON_ERROR)));
            } else {
                $request = $request->withParsedBody($formParams);
            }
        }

        foreach (\array_merge($headerParams, $headers) as $name => $header) {
            $request = $request->withHeader($name, $header);
        }

        return HttpSignatureHeaders::forConfig(
            $this->configuration,
            $accessToken,
            $region,
            $request
        );
    }
}
