<?php

declare(strict_types=1);

namespace AmazonPHP\SellingPartner\Api\ListingsApi;

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 Listings Items.
 *
 * The Selling Partner API for Listings Items (Listings Items API) provides programmatic access to selling partner listings on Amazon. Use this API in collaboration with the Selling Partner API for Product Type Definitions, which you use to retrieve the information about Amazon product types needed to use the Listings Items API.  For more information, see the [Listings Items API Use Case Guide](https://developer-docs.amazon.com/sp-api/docs/listings-items-api-v2021-08-01-use-case-guide).
 *
 * The version of the OpenAPI document: 2021-08-01
 *
 * 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 ListingsItemsSDK implements ListingsItemsSDKInterface
{
    public function __construct(private readonly ClientInterface $client, private readonly HttpFactory $httpFactory, private readonly Configuration $configuration, private readonly LoggerInterface $logger)
    {
    }

    /**
     * Operation deleteListingsItem.
     *
     * @param string $seller_id A selling partner identifier, such as a merchant account or vendor code. (required)
     * @param string $sku A selling partner provided identifier for an Amazon listing. (required)
     * @param string[] $marketplace_ids A comma-delimited list of Amazon marketplace identifiers for the request. (required)
     * @param null|string $issue_locale A locale for localization of issues. When not provided, the default language code of the first marketplace is used. Examples: &#x60;en_US&#x60;, &#x60;fr_CA&#x60;, &#x60;fr_FR&#x60;. Localized messages default to &#x60;en_US&#x60; when a localization is not available in the specified locale. (optional)
     *
     * @throws ApiException on non-2xx response
     * @throws InvalidArgumentException
     */
    public function deleteListingsItem(AccessToken $accessToken, string $region, string $seller_id, string $sku, array $marketplace_ids, ?string $issue_locale = null) : \AmazonPHP\SellingPartner\Model\ListingsItems\ListingsItemSubmissionResponse
    {
        $request = $this->deleteListingsItemRequest($accessToken, $region, $seller_id, $sku, $marketplace_ids, $issue_locale);

        $this->configuration->extensions()->preRequest('ListingsItems', 'deleteListingsItem', $request);

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

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

            if ($this->configuration->loggingEnabled('ListingsItems', 'deleteListingsItem')) {
                $this->logger->log(
                    $this->configuration->logLevel('ListingsItems', 'deleteListingsItem'),
                    'Amazon Selling Partner API pre request',
                    [
                        'api' => 'ListingsItems',
                        'operation' => 'deleteListingsItem',
                        '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('ListingsItems', 'deleteListingsItem', $request, $response);

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

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

                $this->logger->log(
                    $this->configuration->logLevel('ListingsItems', 'deleteListingsItem'),
                    'Amazon Selling Partner API post request',
                    [
                        'api' => 'ListingsItems',
                        'operation' => 'deleteListingsItem',
                        'response_correlation_id' => $correlationId,
                        'response_body' => (string) $sanitizedResponse->getBody(),
                        'response_headers' => $sanitizedResponse->getHeaders(),
                        'response_status_code' => $sanitizedResponse->getStatusCode(),
                        'request_uri' => (string) $sanitizedRequest->getUri(),
                        'request_body' => (string) $sanitizedRequest->getBody(),
                    ]
                );
            }
        } 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\ListingsItems\ListingsItemSubmissionResponse',
            []
        );
    }

    /**
     * Create request for operation 'deleteListingsItem'.
     *
     * @param string $seller_id A selling partner identifier, such as a merchant account or vendor code. (required)
     * @param string $sku A selling partner provided identifier for an Amazon listing. (required)
     * @param string[] $marketplace_ids A comma-delimited list of Amazon marketplace identifiers for the request. (required)
     * @param null|string $issue_locale A locale for localization of issues. When not provided, the default language code of the first marketplace is used. Examples: &#x60;en_US&#x60;, &#x60;fr_CA&#x60;, &#x60;fr_FR&#x60;. Localized messages default to &#x60;en_US&#x60; when a localization is not available in the specified locale. (optional)
     *
     * @throws InvalidArgumentException
     */
    public function deleteListingsItemRequest(AccessToken $accessToken, string $region, string $seller_id, string $sku, array $marketplace_ids, ?string $issue_locale = null) : RequestInterface
    {
        // verify the required parameter 'seller_id' is set
        if ($seller_id === null || (\is_array($seller_id) && \count($seller_id) === 0)) {
            throw new InvalidArgumentException(
                'Missing the required parameter $seller_id when calling deleteListingsItem'
            );
        }

        // verify the required parameter 'sku' is set
        if ($sku === null || (\is_array($sku) && \count($sku) === 0)) {
            throw new InvalidArgumentException(
                'Missing the required parameter $sku when calling deleteListingsItem'
            );
        }

        // verify the required parameter 'marketplace_ids' is set
        if ($marketplace_ids === null || (\is_array($marketplace_ids) && \count($marketplace_ids) === 0)) {
            throw new InvalidArgumentException(
                'Missing the required parameter $marketplace_ids when calling deleteListingsItem'
            );
        }

        if (\count($marketplace_ids) > 1) {
            throw new InvalidArgumentException('invalid value for "$marketplace_ids" when calling ListingsApi.deleteListingsItem, number of items must be less than or equal to 1.');
        }

        $resourcePath = '/listings/2021-08-01/items/{sellerId}/{sku}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $multipart = false;
        $query = '';

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

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

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

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

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

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

        // path params
        if ($sku !== null) {
            $resourcePath = \str_replace(
                '{' . 'sku' . '}',
                ObjectSerializer::toPathValue($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(
            'DELETE',
            $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 getListingsItem.
     *
     * @param string $seller_id A selling partner identifier, such as a merchant account or vendor code. (required)
     * @param string $sku A selling partner provided identifier for an Amazon listing. (required)
     * @param string[] $marketplace_ids A comma-delimited list of Amazon marketplace identifiers for the request. (required)
     * @param null|string $issue_locale A locale for localization of issues. When not provided, the default language code of the first marketplace is used. Examples: &#x60;en_US&#x60;, &#x60;fr_CA&#x60;, &#x60;fr_FR&#x60;. Localized messages default to &#x60;en_US&#x60; when a localization is not available in the specified locale. (optional)
     * @param null|string[] $included_data A comma-delimited list of data sets to include in the response. Default: &#x60;summaries&#x60;. (optional)
     *
     * @throws ApiException on non-2xx response
     * @throws InvalidArgumentException
     */
    public function getListingsItem(AccessToken $accessToken, string $region, string $seller_id, string $sku, array $marketplace_ids, ?string $issue_locale = null, ?array $included_data = null) : \AmazonPHP\SellingPartner\Model\ListingsItems\Item
    {
        $request = $this->getListingsItemRequest($accessToken, $region, $seller_id, $sku, $marketplace_ids, $issue_locale, $included_data);

        $this->configuration->extensions()->preRequest('ListingsItems', 'getListingsItem', $request);

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

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

            if ($this->configuration->loggingEnabled('ListingsItems', 'getListingsItem')) {
                $this->logger->log(
                    $this->configuration->logLevel('ListingsItems', 'getListingsItem'),
                    'Amazon Selling Partner API pre request',
                    [
                        'api' => 'ListingsItems',
                        'operation' => 'getListingsItem',
                        '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('ListingsItems', 'getListingsItem', $request, $response);

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

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

                $this->logger->log(
                    $this->configuration->logLevel('ListingsItems', 'getListingsItem'),
                    'Amazon Selling Partner API post request',
                    [
                        'api' => 'ListingsItems',
                        'operation' => 'getListingsItem',
                        'response_correlation_id' => $correlationId,
                        'response_body' => (string) $sanitizedResponse->getBody(),
                        'response_headers' => $sanitizedResponse->getHeaders(),
                        'response_status_code' => $sanitizedResponse->getStatusCode(),
                        'request_uri' => (string) $sanitizedRequest->getUri(),
                        'request_body' => (string) $sanitizedRequest->getBody(),
                    ]
                );
            }
        } 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\ListingsItems\Item',
            []
        );
    }

    /**
     * Create request for operation 'getListingsItem'.
     *
     * @param string $seller_id A selling partner identifier, such as a merchant account or vendor code. (required)
     * @param string $sku A selling partner provided identifier for an Amazon listing. (required)
     * @param string[] $marketplace_ids A comma-delimited list of Amazon marketplace identifiers for the request. (required)
     * @param null|string $issue_locale A locale for localization of issues. When not provided, the default language code of the first marketplace is used. Examples: &#x60;en_US&#x60;, &#x60;fr_CA&#x60;, &#x60;fr_FR&#x60;. Localized messages default to &#x60;en_US&#x60; when a localization is not available in the specified locale. (optional)
     * @param null|string[] $included_data A comma-delimited list of data sets to include in the response. Default: &#x60;summaries&#x60;. (optional)
     *
     * @throws InvalidArgumentException
     */
    public function getListingsItemRequest(AccessToken $accessToken, string $region, string $seller_id, string $sku, array $marketplace_ids, ?string $issue_locale = null, ?array $included_data = null) : RequestInterface
    {
        // verify the required parameter 'seller_id' is set
        if ($seller_id === null || (\is_array($seller_id) && \count($seller_id) === 0)) {
            throw new InvalidArgumentException(
                'Missing the required parameter $seller_id when calling getListingsItem'
            );
        }

        // verify the required parameter 'sku' is set
        if ($sku === null || (\is_array($sku) && \count($sku) === 0)) {
            throw new InvalidArgumentException(
                'Missing the required parameter $sku when calling getListingsItem'
            );
        }

        // verify the required parameter 'marketplace_ids' is set
        if ($marketplace_ids === null || (\is_array($marketplace_ids) && \count($marketplace_ids) === 0)) {
            throw new InvalidArgumentException(
                'Missing the required parameter $marketplace_ids when calling getListingsItem'
            );
        }

        if (\count($marketplace_ids) > 1) {
            throw new InvalidArgumentException('invalid value for "$marketplace_ids" when calling ListingsApi.getListingsItem, number of items must be less than or equal to 1.');
        }

        $resourcePath = '/listings/2021-08-01/items/{sellerId}/{sku}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $multipart = false;
        $query = '';

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

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

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

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

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

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

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

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

        // path params
        if ($sku !== null) {
            $resourcePath = \str_replace(
                '{' . 'sku' . '}',
                ObjectSerializer::toPathValue($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 patchListingsItem.
     *
     * @param string $seller_id A selling partner identifier, such as a merchant account or vendor code. (required)
     * @param string $sku A selling partner provided identifier for an Amazon listing. (required)
     * @param string[] $marketplace_ids A comma-delimited list of Amazon marketplace identifiers for the request. (required)
     * @param \AmazonPHP\SellingPartner\Model\ListingsItems\ListingsItemPatchRequest $body The request body schema for the &#x60;patchListingsItem&#x60; operation. (required)
     * @param null|string[] $included_data A comma-delimited list of data sets to include in the response. Default: &#x60;issues&#x60;. (optional)
     * @param null|string $mode The mode of operation for the request. (optional)
     * @param null|string $issue_locale A locale for localization of issues. When not provided, the default language code of the first marketplace is used. Examples: &#x60;en_US&#x60;, &#x60;fr_CA&#x60;, &#x60;fr_FR&#x60;. Localized messages default to &#x60;en_US&#x60; when a localization is not available in the specified locale. (optional)
     *
     * @throws ApiException on non-2xx response
     * @throws InvalidArgumentException
     */
    public function patchListingsItem(AccessToken $accessToken, string $region, string $seller_id, string $sku, array $marketplace_ids, \AmazonPHP\SellingPartner\Model\ListingsItems\ListingsItemPatchRequest $body, ?array $included_data = null, ?string $mode = null, ?string $issue_locale = null) : \AmazonPHP\SellingPartner\Model\ListingsItems\ListingsItemSubmissionResponse
    {
        $request = $this->patchListingsItemRequest($accessToken, $region, $seller_id, $sku, $marketplace_ids, $body, $included_data, $mode, $issue_locale);

        $this->configuration->extensions()->preRequest('ListingsItems', 'patchListingsItem', $request);

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

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

            if ($this->configuration->loggingEnabled('ListingsItems', 'patchListingsItem')) {
                $this->logger->log(
                    $this->configuration->logLevel('ListingsItems', 'patchListingsItem'),
                    'Amazon Selling Partner API pre request',
                    [
                        'api' => 'ListingsItems',
                        'operation' => 'patchListingsItem',
                        '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('ListingsItems', 'patchListingsItem', $request, $response);

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

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

                $this->logger->log(
                    $this->configuration->logLevel('ListingsItems', 'patchListingsItem'),
                    'Amazon Selling Partner API post request',
                    [
                        'api' => 'ListingsItems',
                        'operation' => 'patchListingsItem',
                        'response_correlation_id' => $correlationId,
                        'response_body' => (string) $sanitizedResponse->getBody(),
                        'response_headers' => $sanitizedResponse->getHeaders(),
                        'response_status_code' => $sanitizedResponse->getStatusCode(),
                        'request_uri' => (string) $sanitizedRequest->getUri(),
                        'request_body' => (string) $sanitizedRequest->getBody(),
                    ]
                );
            }
        } 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\ListingsItems\ListingsItemSubmissionResponse',
            []
        );
    }

    /**
     * Create request for operation 'patchListingsItem'.
     *
     * @param string $seller_id A selling partner identifier, such as a merchant account or vendor code. (required)
     * @param string $sku A selling partner provided identifier for an Amazon listing. (required)
     * @param string[] $marketplace_ids A comma-delimited list of Amazon marketplace identifiers for the request. (required)
     * @param \AmazonPHP\SellingPartner\Model\ListingsItems\ListingsItemPatchRequest $body The request body schema for the &#x60;patchListingsItem&#x60; operation. (required)
     * @param null|string[] $included_data A comma-delimited list of data sets to include in the response. Default: &#x60;issues&#x60;. (optional)
     * @param null|string $mode The mode of operation for the request. (optional)
     * @param null|string $issue_locale A locale for localization of issues. When not provided, the default language code of the first marketplace is used. Examples: &#x60;en_US&#x60;, &#x60;fr_CA&#x60;, &#x60;fr_FR&#x60;. Localized messages default to &#x60;en_US&#x60; when a localization is not available in the specified locale. (optional)
     *
     * @throws InvalidArgumentException
     */
    public function patchListingsItemRequest(AccessToken $accessToken, string $region, string $seller_id, string $sku, array $marketplace_ids, \AmazonPHP\SellingPartner\Model\ListingsItems\ListingsItemPatchRequest $body, ?array $included_data = null, ?string $mode = null, ?string $issue_locale = null) : RequestInterface
    {
        // verify the required parameter 'seller_id' is set
        if ($seller_id === null || (\is_array($seller_id) && \count($seller_id) === 0)) {
            throw new InvalidArgumentException(
                'Missing the required parameter $seller_id when calling patchListingsItem'
            );
        }

        // verify the required parameter 'sku' is set
        if ($sku === null || (\is_array($sku) && \count($sku) === 0)) {
            throw new InvalidArgumentException(
                'Missing the required parameter $sku when calling patchListingsItem'
            );
        }

        // verify the required parameter 'marketplace_ids' is set
        if ($marketplace_ids === null || (\is_array($marketplace_ids) && \count($marketplace_ids) === 0)) {
            throw new InvalidArgumentException(
                'Missing the required parameter $marketplace_ids when calling patchListingsItem'
            );
        }

        if (\count($marketplace_ids) > 1) {
            throw new InvalidArgumentException('invalid value for "$marketplace_ids" when calling ListingsApi.patchListingsItem, number of items must be less than or equal to 1.');
        }

        // verify the required parameter 'body' is set
        if ($body === null || (\is_array($body) && \count($body) === 0)) {
            throw new InvalidArgumentException(
                'Missing the required parameter $body when calling patchListingsItem'
            );
        }

        $resourcePath = '/listings/2021-08-01/items/{sellerId}/{sku}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $multipart = false;
        $query = '';

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

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

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

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

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

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

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

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

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

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

        // path params
        if ($sku !== null) {
            $resourcePath = \str_replace(
                '{' . 'sku' . '}',
                ObjectSerializer::toPathValue($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(
            'PATCH',
            $this->configuration->apiURL($region) . $resourcePath . '?' . $query
        );

        // for model (json/xml)
        if (isset($body)) {
            if ($headers['content-type'] === ['application/json']) {
                $httpBody = \json_encode(ObjectSerializer::sanitizeForSerialization($body), JSON_THROW_ON_ERROR);
            } else {
                $httpBody = $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 putListingsItem.
     *
     * @param string $seller_id A selling partner identifier, such as a merchant account or vendor code. (required)
     * @param string $sku A selling partner provided identifier for an Amazon listing. (required)
     * @param string[] $marketplace_ids A comma-delimited list of Amazon marketplace identifiers for the request. (required)
     * @param \AmazonPHP\SellingPartner\Model\ListingsItems\ListingsItemPutRequest $body The request body schema for the &#x60;putListingsItem&#x60; operation. (required)
     * @param null|string[] $included_data A comma-delimited list of data sets to include in the response. Default: &#x60;issues&#x60;. (optional)
     * @param null|string $mode The mode of operation for the request. (optional)
     * @param null|string $issue_locale A locale for localization of issues. When not provided, the default language code of the first marketplace is used. Examples: &#x60;en_US&#x60;, &#x60;fr_CA&#x60;, &#x60;fr_FR&#x60;. Localized messages default to &#x60;en_US&#x60; when a localization is not available in the specified locale. (optional)
     *
     * @throws ApiException on non-2xx response
     * @throws InvalidArgumentException
     */
    public function putListingsItem(AccessToken $accessToken, string $region, string $seller_id, string $sku, array $marketplace_ids, \AmazonPHP\SellingPartner\Model\ListingsItems\ListingsItemPutRequest $body, ?array $included_data = null, ?string $mode = null, ?string $issue_locale = null) : \AmazonPHP\SellingPartner\Model\ListingsItems\ListingsItemSubmissionResponse
    {
        $request = $this->putListingsItemRequest($accessToken, $region, $seller_id, $sku, $marketplace_ids, $body, $included_data, $mode, $issue_locale);

        $this->configuration->extensions()->preRequest('ListingsItems', 'putListingsItem', $request);

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

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

            if ($this->configuration->loggingEnabled('ListingsItems', 'putListingsItem')) {
                $this->logger->log(
                    $this->configuration->logLevel('ListingsItems', 'putListingsItem'),
                    'Amazon Selling Partner API pre request',
                    [
                        'api' => 'ListingsItems',
                        'operation' => 'putListingsItem',
                        '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('ListingsItems', 'putListingsItem', $request, $response);

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

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

                $this->logger->log(
                    $this->configuration->logLevel('ListingsItems', 'putListingsItem'),
                    'Amazon Selling Partner API post request',
                    [
                        'api' => 'ListingsItems',
                        'operation' => 'putListingsItem',
                        'response_correlation_id' => $correlationId,
                        'response_body' => (string) $sanitizedResponse->getBody(),
                        'response_headers' => $sanitizedResponse->getHeaders(),
                        'response_status_code' => $sanitizedResponse->getStatusCode(),
                        'request_uri' => (string) $sanitizedRequest->getUri(),
                        'request_body' => (string) $sanitizedRequest->getBody(),
                    ]
                );
            }
        } 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\ListingsItems\ListingsItemSubmissionResponse',
            []
        );
    }

    /**
     * Create request for operation 'putListingsItem'.
     *
     * @param string $seller_id A selling partner identifier, such as a merchant account or vendor code. (required)
     * @param string $sku A selling partner provided identifier for an Amazon listing. (required)
     * @param string[] $marketplace_ids A comma-delimited list of Amazon marketplace identifiers for the request. (required)
     * @param \AmazonPHP\SellingPartner\Model\ListingsItems\ListingsItemPutRequest $body The request body schema for the &#x60;putListingsItem&#x60; operation. (required)
     * @param null|string[] $included_data A comma-delimited list of data sets to include in the response. Default: &#x60;issues&#x60;. (optional)
     * @param null|string $mode The mode of operation for the request. (optional)
     * @param null|string $issue_locale A locale for localization of issues. When not provided, the default language code of the first marketplace is used. Examples: &#x60;en_US&#x60;, &#x60;fr_CA&#x60;, &#x60;fr_FR&#x60;. Localized messages default to &#x60;en_US&#x60; when a localization is not available in the specified locale. (optional)
     *
     * @throws InvalidArgumentException
     */
    public function putListingsItemRequest(AccessToken $accessToken, string $region, string $seller_id, string $sku, array $marketplace_ids, \AmazonPHP\SellingPartner\Model\ListingsItems\ListingsItemPutRequest $body, ?array $included_data = null, ?string $mode = null, ?string $issue_locale = null) : RequestInterface
    {
        // verify the required parameter 'seller_id' is set
        if ($seller_id === null || (\is_array($seller_id) && \count($seller_id) === 0)) {
            throw new InvalidArgumentException(
                'Missing the required parameter $seller_id when calling putListingsItem'
            );
        }

        // verify the required parameter 'sku' is set
        if ($sku === null || (\is_array($sku) && \count($sku) === 0)) {
            throw new InvalidArgumentException(
                'Missing the required parameter $sku when calling putListingsItem'
            );
        }

        // verify the required parameter 'marketplace_ids' is set
        if ($marketplace_ids === null || (\is_array($marketplace_ids) && \count($marketplace_ids) === 0)) {
            throw new InvalidArgumentException(
                'Missing the required parameter $marketplace_ids when calling putListingsItem'
            );
        }

        if (\count($marketplace_ids) > 1) {
            throw new InvalidArgumentException('invalid value for "$marketplace_ids" when calling ListingsApi.putListingsItem, number of items must be less than or equal to 1.');
        }

        // verify the required parameter 'body' is set
        if ($body === null || (\is_array($body) && \count($body) === 0)) {
            throw new InvalidArgumentException(
                'Missing the required parameter $body when calling putListingsItem'
            );
        }

        $resourcePath = '/listings/2021-08-01/items/{sellerId}/{sku}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $multipart = false;
        $query = '';

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

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

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

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

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

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

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

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

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

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

        // path params
        if ($sku !== null) {
            $resourcePath = \str_replace(
                '{' . 'sku' . '}',
                ObjectSerializer::toPathValue($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(
            'PUT',
            $this->configuration->apiURL($region) . $resourcePath . '?' . $query
        );

        // for model (json/xml)
        if (isset($body)) {
            if ($headers['content-type'] === ['application/json']) {
                $httpBody = \json_encode(ObjectSerializer::sanitizeForSerialization($body), JSON_THROW_ON_ERROR);
            } else {
                $httpBody = $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 searchListingsItems.
     *
     * @param string $seller_id A selling partner identifier, such as a merchant account or vendor code. (required)
     * @param string[] $marketplace_ids A comma-delimited list of Amazon marketplace identifiers for the request. (required)
     * @param null|string $issue_locale A locale that is used to localize issues. When not provided, the default language code of the first marketplace is used. Examples: \&quot;en_US\&quot;, \&quot;fr_CA\&quot;, \&quot;fr_FR\&quot;. When a localization is not available in the specified locale, localized messages default to \&quot;en_US\&quot;. (optional)
     * @param null|string[] $included_data A comma-delimited list of datasets that you want to include in the response. Default: &#x60;summaries&#x60;. (optional)
     * @param null|string[] $identifiers A comma-delimited list of product identifiers that you can use to search for listings items.   **Note**:  1. This is required when you specify &#x60;identifiersType&#x60;. 2. You cannot use &#39;identifiers&#39; if you specify &#x60;variationParentSku&#x60; or &#x60;packageHierarchySku&#x60;. (optional)
     * @param null|string $identifiers_type A type of product identifiers that you can use to search for listings items.   **Note**:  This is required when &#x60;identifiers&#x60; is provided. (optional)
     * @param null|string $variation_parent_sku Filters results to include listing items that are variation children of the specified SKU.   **Note**: You cannot use &#x60;variationParentSku&#x60; if you include &#x60;identifiers&#x60; or &#x60;packageHierarchySku&#x60; in your request. (optional)
     * @param null|string $package_hierarchy_sku Filter results to include listing items that contain or are contained by the specified SKU.   **Note**: You cannot use &#x60;packageHierarchySku&#x60; if you include &#x60;identifiers&#x60; or &#x60;variationParentSku&#x60; in your request. (optional)
     * @param null|\DateTimeInterface $created_after A date-time that is used to filter listing items. The response includes listings items that were created at or after this time. Values are in [ISO 8601](https://developer-docs.amazon.com/sp-api/docs/iso-8601) date-time format. (optional)
     * @param null|\DateTimeInterface $created_before A date-time that is used to filter listing items. The response includes listings items that were created at or before this time. Values are in [ISO 8601](https://developer-docs.amazon.com/sp-api/docs/iso-8601) date-time format. (optional)
     * @param null|\DateTimeInterface $last_updated_after A date-time that is used to filter listing items. The response includes listings items that were last updated at or after this time. Values are in [ISO 8601](https://developer-docs.amazon.com/sp-api/docs/iso-8601) date-time format. (optional)
     * @param null|\DateTimeInterface $last_updated_before A date-time that is used to filter listing items. The response includes listings items that were last updated at or before this time. Values are in [ISO 8601](https://developer-docs.amazon.com/sp-api/docs/iso-8601) date-time format. (optional)
     * @param null|string[] $with_issue_severity Filter results to include only listing items that have issues that match one or more of the specified severity levels. (optional)
     * @param null|string[] $with_status Filter results to include only listing items that have the specified status. (optional)
     * @param null|string[] $without_status Filter results to include only listing items that don&#39;t contain the specified statuses. (optional)
     * @param null|string $sort_by An attribute by which to sort the returned listing items. (optional, default to 'lastUpdatedDate')
     * @param null|string $sort_order The order in which to sort the result items. (optional, default to 'DESC')
     * @param null|int $page_size The number of results that you want to include on each page. (optional, default to 10)
     * @param null|string $page_token A token that you can use to fetch a specific page when there are multiple pages of results. (optional)
     *
     * @throws ApiException on non-2xx response
     * @throws InvalidArgumentException
     */
    public function searchListingsItems(AccessToken $accessToken, string $region, string $seller_id, array $marketplace_ids, ?string $issue_locale = null, ?array $included_data = null, ?array $identifiers = null, ?string $identifiers_type = null, ?string $variation_parent_sku = null, ?string $package_hierarchy_sku = null, ?\DateTimeInterface $created_after = null, ?\DateTimeInterface $created_before = null, ?\DateTimeInterface $last_updated_after = null, ?\DateTimeInterface $last_updated_before = null, ?array $with_issue_severity = null, ?array $with_status = null, ?array $without_status = null, ?string $sort_by = 'lastUpdatedDate', ?string $sort_order = 'DESC', ?int $page_size = 10, ?string $page_token = null) : \AmazonPHP\SellingPartner\Model\ListingsItems\ItemSearchResults
    {
        $request = $this->searchListingsItemsRequest($accessToken, $region, $seller_id, $marketplace_ids, $issue_locale, $included_data, $identifiers, $identifiers_type, $variation_parent_sku, $package_hierarchy_sku, $created_after, $created_before, $last_updated_after, $last_updated_before, $with_issue_severity, $with_status, $without_status, $sort_by, $sort_order, $page_size, $page_token);

        $this->configuration->extensions()->preRequest('ListingsItems', 'searchListingsItems', $request);

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

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

            if ($this->configuration->loggingEnabled('ListingsItems', 'searchListingsItems')) {
                $this->logger->log(
                    $this->configuration->logLevel('ListingsItems', 'searchListingsItems'),
                    'Amazon Selling Partner API pre request',
                    [
                        'api' => 'ListingsItems',
                        'operation' => 'searchListingsItems',
                        '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('ListingsItems', 'searchListingsItems', $request, $response);

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

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

                $this->logger->log(
                    $this->configuration->logLevel('ListingsItems', 'searchListingsItems'),
                    'Amazon Selling Partner API post request',
                    [
                        'api' => 'ListingsItems',
                        'operation' => 'searchListingsItems',
                        'response_correlation_id' => $correlationId,
                        'response_body' => (string) $sanitizedResponse->getBody(),
                        'response_headers' => $sanitizedResponse->getHeaders(),
                        'response_status_code' => $sanitizedResponse->getStatusCode(),
                        'request_uri' => (string) $sanitizedRequest->getUri(),
                        'request_body' => (string) $sanitizedRequest->getBody(),
                    ]
                );
            }
        } 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\ListingsItems\ItemSearchResults',
            []
        );
    }

    /**
     * Create request for operation 'searchListingsItems'.
     *
     * @param string $seller_id A selling partner identifier, such as a merchant account or vendor code. (required)
     * @param string[] $marketplace_ids A comma-delimited list of Amazon marketplace identifiers for the request. (required)
     * @param null|string $issue_locale A locale that is used to localize issues. When not provided, the default language code of the first marketplace is used. Examples: \&quot;en_US\&quot;, \&quot;fr_CA\&quot;, \&quot;fr_FR\&quot;. When a localization is not available in the specified locale, localized messages default to \&quot;en_US\&quot;. (optional)
     * @param null|string[] $included_data A comma-delimited list of datasets that you want to include in the response. Default: &#x60;summaries&#x60;. (optional)
     * @param null|string[] $identifiers A comma-delimited list of product identifiers that you can use to search for listings items.   **Note**:  1. This is required when you specify &#x60;identifiersType&#x60;. 2. You cannot use &#39;identifiers&#39; if you specify &#x60;variationParentSku&#x60; or &#x60;packageHierarchySku&#x60;. (optional)
     * @param null|string $identifiers_type A type of product identifiers that you can use to search for listings items.   **Note**:  This is required when &#x60;identifiers&#x60; is provided. (optional)
     * @param null|string $variation_parent_sku Filters results to include listing items that are variation children of the specified SKU.   **Note**: You cannot use &#x60;variationParentSku&#x60; if you include &#x60;identifiers&#x60; or &#x60;packageHierarchySku&#x60; in your request. (optional)
     * @param null|string $package_hierarchy_sku Filter results to include listing items that contain or are contained by the specified SKU.   **Note**: You cannot use &#x60;packageHierarchySku&#x60; if you include &#x60;identifiers&#x60; or &#x60;variationParentSku&#x60; in your request. (optional)
     * @param null|\DateTimeInterface $created_after A date-time that is used to filter listing items. The response includes listings items that were created at or after this time. Values are in [ISO 8601](https://developer-docs.amazon.com/sp-api/docs/iso-8601) date-time format. (optional)
     * @param null|\DateTimeInterface $created_before A date-time that is used to filter listing items. The response includes listings items that were created at or before this time. Values are in [ISO 8601](https://developer-docs.amazon.com/sp-api/docs/iso-8601) date-time format. (optional)
     * @param null|\DateTimeInterface $last_updated_after A date-time that is used to filter listing items. The response includes listings items that were last updated at or after this time. Values are in [ISO 8601](https://developer-docs.amazon.com/sp-api/docs/iso-8601) date-time format. (optional)
     * @param null|\DateTimeInterface $last_updated_before A date-time that is used to filter listing items. The response includes listings items that were last updated at or before this time. Values are in [ISO 8601](https://developer-docs.amazon.com/sp-api/docs/iso-8601) date-time format. (optional)
     * @param null|string[] $with_issue_severity Filter results to include only listing items that have issues that match one or more of the specified severity levels. (optional)
     * @param null|string[] $with_status Filter results to include only listing items that have the specified status. (optional)
     * @param null|string[] $without_status Filter results to include only listing items that don&#39;t contain the specified statuses. (optional)
     * @param null|string $sort_by An attribute by which to sort the returned listing items. (optional, default to 'lastUpdatedDate')
     * @param null|string $sort_order The order in which to sort the result items. (optional, default to 'DESC')
     * @param null|int $page_size The number of results that you want to include on each page. (optional, default to 10)
     * @param null|string $page_token A token that you can use to fetch a specific page when there are multiple pages of results. (optional)
     *
     * @throws InvalidArgumentException
     */
    public function searchListingsItemsRequest(AccessToken $accessToken, string $region, string $seller_id, array $marketplace_ids, ?string $issue_locale = null, ?array $included_data = null, ?array $identifiers = null, ?string $identifiers_type = null, ?string $variation_parent_sku = null, ?string $package_hierarchy_sku = null, ?\DateTimeInterface $created_after = null, ?\DateTimeInterface $created_before = null, ?\DateTimeInterface $last_updated_after = null, ?\DateTimeInterface $last_updated_before = null, ?array $with_issue_severity = null, ?array $with_status = null, ?array $without_status = null, ?string $sort_by = 'lastUpdatedDate', ?string $sort_order = 'DESC', ?int $page_size = 10, ?string $page_token = null) : RequestInterface
    {
        // verify the required parameter 'seller_id' is set
        if ($seller_id === null || (\is_array($seller_id) && \count($seller_id) === 0)) {
            throw new InvalidArgumentException(
                'Missing the required parameter $seller_id when calling searchListingsItems'
            );
        }

        // verify the required parameter 'marketplace_ids' is set
        if ($marketplace_ids === null || (\is_array($marketplace_ids) && \count($marketplace_ids) === 0)) {
            throw new InvalidArgumentException(
                'Missing the required parameter $marketplace_ids when calling searchListingsItems'
            );
        }

        if (\count($marketplace_ids) > 1) {
            throw new InvalidArgumentException('invalid value for "$marketplace_ids" when calling ListingsApi.searchListingsItems, number of items must be less than or equal to 1.');
        }

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

        if ($page_size !== null && $page_size > 20) {
            throw new InvalidArgumentException('invalid value for "$page_size" when calling ListingsApi.searchListingsItems, must be smaller than or equal to 20.');
        }

        $resourcePath = '/listings/2021-08-01/items/{sellerId}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $multipart = false;
        $query = '';

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        // path params
        if ($seller_id !== null) {
            $resourcePath = \str_replace(
                '{' . 'sellerId' . '}',
                ObjectSerializer::toPathValue($seller_id),
                $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
        );
    }
}
