<?php

declare(strict_types=1);

namespace AmazonPHP\SellingPartner\Api\AwdApi;

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;

/**
 * The Selling Partner API for Amazon Warehousing and Distribution.
 *
 * The Selling Partner API for Amazon Warehousing and Distribution (AWD) provides programmatic access to information about AWD shipments and inventory.
 *
 * The version of the OpenAPI document: 2024-05-09
 *
 * 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 WarehousingAndDistributionSDK implements WarehousingAndDistributionSDKInterface
{
    public function __construct(private readonly ClientInterface $client, private readonly HttpFactory $httpFactory, private readonly Configuration $configuration, private readonly LoggerInterface $logger)
    {
    }

    /**
     * Operation getInboundShipment.
     *
     * @param string $shipment_id ID for the shipment. A shipment contains the cases being inbounded. (required)
     * @param null|string $sku_quantities If equal to &#x60;SHOW&#x60;, the response includes the shipment SKU quantity details.  Defaults to &#x60;HIDE&#x60;, in which case the response does not contain SKU quantities (optional)
     *
     * @throws ApiException on non-2xx response
     * @throws InvalidArgumentException
     */
    public function getInboundShipment(AccessToken $accessToken, string $region, string $shipment_id, ?string $sku_quantities = null) : \AmazonPHP\SellingPartner\Model\WarehousingAndDistribution\InboundShipment
    {
        $request = $this->getInboundShipmentRequest($accessToken, $region, $shipment_id, $sku_quantities);

        $this->configuration->extensions()->preRequest('WarehousingAndDistribution', 'getInboundShipment', $request);

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

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

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

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

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

                $this->logger->log(
                    $this->configuration->logLevel('WarehousingAndDistribution', 'getInboundShipment'),
                    'Amazon Selling Partner API post request',
                    [
                        'api' => 'WarehousingAndDistribution',
                        'operation' => 'getInboundShipment',
                        '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\WarehousingAndDistribution\InboundShipment',
            []
        );
    }

    /**
     * Create request for operation 'getInboundShipment'.
     *
     * @param string $shipment_id ID for the shipment. A shipment contains the cases being inbounded. (required)
     * @param null|string $sku_quantities If equal to &#x60;SHOW&#x60;, the response includes the shipment SKU quantity details.  Defaults to &#x60;HIDE&#x60;, in which case the response does not contain SKU quantities (optional)
     *
     * @throws InvalidArgumentException
     */
    public function getInboundShipmentRequest(AccessToken $accessToken, string $region, string $shipment_id, ?string $sku_quantities = null) : RequestInterface
    {
        // verify the required parameter 'shipment_id' is set
        if ($shipment_id === null || (\is_array($shipment_id) && \count($shipment_id) === 0)) {
            throw new InvalidArgumentException(
                'Missing the required parameter $shipment_id when calling getInboundShipment'
            );
        }

        if (\strlen($shipment_id) < 1) {
            throw new InvalidArgumentException('invalid length for "$shipment_id" when calling AwdApi.getInboundShipment, must be bigger than or equal to 1.');
        }

        $resourcePath = '/awd/2024-05-09/inboundShipments/{shipmentId}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $multipart = false;
        $query = '';

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

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

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

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

    /**
     * Operation listInboundShipments.
     *
     * @param null|string $sort_by Field to sort results by. By default, the response will be sorted by UPDATED_AT. (optional)
     * @param null|string $sort_order Sort the response in ASCENDING or DESCENDING order. By default, the response will be sorted in DESCENDING order. (optional)
     * @param null|string $shipment_status Filter by inbound shipment status. (optional)
     * @param null|\DateTimeInterface $updated_after List the inbound shipments that were updated after a certain time (inclusive). The date must be in &lt;a href&#x3D;&#39;https://developer-docs.amazon.com/sp-api/docs/iso-8601&#39;&gt;ISO 8601&lt;/a&gt; format. (optional)
     * @param null|\DateTimeInterface $updated_before List the inbound shipments that were updated before a certain time (inclusive). The date must be in &lt;a href&#x3D;&#39;https://developer-docs.amazon.com/sp-api/docs/iso-8601&#39;&gt;ISO 8601&lt;/a&gt; format. (optional)
     * @param null|int $max_results Maximum number of results to return. (optional, default to 25)
     * @param null|string $next_token A token that is used to retrieve the next page of results. The response includes &#x60;nextToken&#x60; when the number of results exceeds the specified &#x60;maxResults&#x60; value. To get the next page of results, call the operation with this token and include the same arguments as the call that produced the token. To get a complete list, call this operation until &#x60;nextToken&#x60; is null. Note that this operation can return empty pages. (optional)
     *
     * @throws ApiException on non-2xx response
     * @throws InvalidArgumentException
     */
    public function listInboundShipments(AccessToken $accessToken, string $region, ?string $sort_by = null, ?string $sort_order = null, ?string $shipment_status = null, ?\DateTimeInterface $updated_after = null, ?\DateTimeInterface $updated_before = null, ?int $max_results = 25, ?string $next_token = null) : \AmazonPHP\SellingPartner\Model\WarehousingAndDistribution\ShipmentListing
    {
        $request = $this->listInboundShipmentsRequest($accessToken, $region, $sort_by, $sort_order, $shipment_status, $updated_after, $updated_before, $max_results, $next_token);

        $this->configuration->extensions()->preRequest('WarehousingAndDistribution', 'listInboundShipments', $request);

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

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

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

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

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

                $this->logger->log(
                    $this->configuration->logLevel('WarehousingAndDistribution', 'listInboundShipments'),
                    'Amazon Selling Partner API post request',
                    [
                        'api' => 'WarehousingAndDistribution',
                        'operation' => 'listInboundShipments',
                        '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\WarehousingAndDistribution\ShipmentListing',
            []
        );
    }

    /**
     * Create request for operation 'listInboundShipments'.
     *
     * @param null|string $sort_by Field to sort results by. By default, the response will be sorted by UPDATED_AT. (optional)
     * @param null|string $sort_order Sort the response in ASCENDING or DESCENDING order. By default, the response will be sorted in DESCENDING order. (optional)
     * @param null|string $shipment_status Filter by inbound shipment status. (optional)
     * @param null|\DateTimeInterface $updated_after List the inbound shipments that were updated after a certain time (inclusive). The date must be in &lt;a href&#x3D;&#39;https://developer-docs.amazon.com/sp-api/docs/iso-8601&#39;&gt;ISO 8601&lt;/a&gt; format. (optional)
     * @param null|\DateTimeInterface $updated_before List the inbound shipments that were updated before a certain time (inclusive). The date must be in &lt;a href&#x3D;&#39;https://developer-docs.amazon.com/sp-api/docs/iso-8601&#39;&gt;ISO 8601&lt;/a&gt; format. (optional)
     * @param null|int $max_results Maximum number of results to return. (optional, default to 25)
     * @param null|string $next_token A token that is used to retrieve the next page of results. The response includes &#x60;nextToken&#x60; when the number of results exceeds the specified &#x60;maxResults&#x60; value. To get the next page of results, call the operation with this token and include the same arguments as the call that produced the token. To get a complete list, call this operation until &#x60;nextToken&#x60; is null. Note that this operation can return empty pages. (optional)
     *
     * @throws InvalidArgumentException
     */
    public function listInboundShipmentsRequest(AccessToken $accessToken, string $region, ?string $sort_by = null, ?string $sort_order = null, ?string $shipment_status = null, ?\DateTimeInterface $updated_after = null, ?\DateTimeInterface $updated_before = null, ?int $max_results = 25, ?string $next_token = null) : RequestInterface
    {
        if ($max_results !== null && $max_results > 200) {
            throw new InvalidArgumentException('invalid value for "$max_results" when calling AwdApi.listInboundShipments, must be smaller than or equal to 200.');
        }

        if ($max_results !== null && $max_results < 1) {
            throw new InvalidArgumentException('invalid value for "$max_results" when calling AwdApi.listInboundShipments, must be bigger than or equal to 1.');
        }

        $resourcePath = '/awd/2024-05-09/inboundShipments';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $multipart = false;
        $query = '';

        // 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($shipment_status)) {
            $shipment_status = ObjectSerializer::serializeCollection($shipment_status, '', true);
        }

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

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

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

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

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

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

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

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

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

        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 listInventory.
     *
     * @param null|string $sku Filter by seller or merchant SKU for the item. (optional)
     * @param null|string $sort_order Sort the response in &#x60;ASCENDING&#x60; or &#x60;DESCENDING&#x60; order. (optional)
     * @param null|string $details Set to &#x60;SHOW&#x60; to return summaries with additional inventory details. Defaults to &#x60;HIDE,&#x60; which returns only inventory summary totals. (optional)
     * @param null|string $next_token A token that is used to retrieve the next page of results. The response includes &#x60;nextToken&#x60; when the number of results exceeds the specified &#x60;maxResults&#x60; value. To get the next page of results, call the operation with this token and include the same arguments as the call that produced the token. To get a complete list, call this operation until &#x60;nextToken&#x60; is null. Note that this operation can return empty pages. (optional)
     * @param null|int $max_results Maximum number of results to return. (optional, default to 25)
     *
     * @throws ApiException on non-2xx response
     * @throws InvalidArgumentException
     */
    public function listInventory(AccessToken $accessToken, string $region, ?string $sku = null, ?string $sort_order = null, ?string $details = null, ?string $next_token = null, ?int $max_results = 25) : \AmazonPHP\SellingPartner\Model\WarehousingAndDistribution\InventoryListing
    {
        $request = $this->listInventoryRequest($accessToken, $region, $sku, $sort_order, $details, $next_token, $max_results);

        $this->configuration->extensions()->preRequest('WarehousingAndDistribution', 'listInventory', $request);

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

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

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

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

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

                $this->logger->log(
                    $this->configuration->logLevel('WarehousingAndDistribution', 'listInventory'),
                    'Amazon Selling Partner API post request',
                    [
                        'api' => 'WarehousingAndDistribution',
                        'operation' => 'listInventory',
                        '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\WarehousingAndDistribution\InventoryListing',
            []
        );
    }

    /**
     * Create request for operation 'listInventory'.
     *
     * @param null|string $sku Filter by seller or merchant SKU for the item. (optional)
     * @param null|string $sort_order Sort the response in &#x60;ASCENDING&#x60; or &#x60;DESCENDING&#x60; order. (optional)
     * @param null|string $details Set to &#x60;SHOW&#x60; to return summaries with additional inventory details. Defaults to &#x60;HIDE,&#x60; which returns only inventory summary totals. (optional)
     * @param null|string $next_token A token that is used to retrieve the next page of results. The response includes &#x60;nextToken&#x60; when the number of results exceeds the specified &#x60;maxResults&#x60; value. To get the next page of results, call the operation with this token and include the same arguments as the call that produced the token. To get a complete list, call this operation until &#x60;nextToken&#x60; is null. Note that this operation can return empty pages. (optional)
     * @param null|int $max_results Maximum number of results to return. (optional, default to 25)
     *
     * @throws InvalidArgumentException
     */
    public function listInventoryRequest(AccessToken $accessToken, string $region, ?string $sku = null, ?string $sort_order = null, ?string $details = null, ?string $next_token = null, ?int $max_results = 25) : RequestInterface
    {
        if ($max_results !== null && $max_results > 200) {
            throw new InvalidArgumentException('invalid value for "$max_results" when calling AwdApi.listInventory, must be smaller than or equal to 200.');
        }

        if ($max_results !== null && $max_results < 1) {
            throw new InvalidArgumentException('invalid value for "$max_results" when calling AwdApi.listInventory, must be bigger than or equal to 1.');
        }

        $resourcePath = '/awd/2024-05-09/inventory';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $multipart = false;
        $query = '';

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

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

        // 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($details)) {
            $details = ObjectSerializer::serializeCollection($details, '', true);
        }

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

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

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

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

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

        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
        );
    }
}
