<?php
/**
 * ServiceOrdersApi
 * PHP version 8.1
 *
 * @category Class
 * @package  Vend202601
 * @author   OpenAPI Generator team
 * @link     https://openapi-generator.tech
 */

/**
 * API 2026-01
 *
 * Lightspeed Retail (X-Series) API.
 *
 * The version of the OpenAPI document: 2026-01
 * Contact: x-series.api@lightspeedhq.com
 * Generated by: https://openapi-generator.tech
 * Generator version: 7.20.0
 */

/**
 * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
 * https://openapi-generator.tech
 * Do not edit the class manually.
 */

namespace Vend202601\Api;

use GuzzleHttp\Client;
use GuzzleHttp\ClientInterface;
use GuzzleHttp\Exception\ConnectException;
use GuzzleHttp\Exception\RequestException;
use GuzzleHttp\Psr7\MultipartStream;
use GuzzleHttp\Psr7\Request;
use GuzzleHttp\RequestOptions;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
use Vend202601\ApiException;
use Vend202601\Configuration;
use Vend202601\FormDataProcessor;
use Vend202601\HeaderSelector;
use Vend202601\ObjectSerializer;

/**
 * ServiceOrdersApi Class Doc Comment
 *
 * @category Class
 * @package  Vend202601
 * @author   OpenAPI Generator team
 * @link     https://openapi-generator.tech
 */
class ServiceOrdersApi
{
    /**
     * @var ClientInterface
     */
    protected $client;

    /**
     * @var Configuration
     */
    protected $config;

    /**
     * @var HeaderSelector
     */
    protected $headerSelector;

    /**
     * @var int Host index
     */
    protected $hostIndex;

    /** @var string[] $contentTypes **/
    public const contentTypes = [
        'createService' => [
            'application/json',
        ],
        'getAgendaOutletId' => [
            'application/json',
        ],
        'getService' => [
            'application/json',
        ],
        'listServiceItems' => [
            'application/json',
        ],
        'listServices' => [
            'application/json',
        ],
    ];

    /**
     * @param ClientInterface $client
     * @param Configuration   $config
     * @param HeaderSelector  $selector
     * @param int             $hostIndex (Optional) host index to select the list of hosts if defined in the OpenAPI spec
     */
    public function __construct(
        ?ClientInterface $client = null,
        ?Configuration $config = null,
        ?HeaderSelector $selector = null,
        int $hostIndex = 0
    ) {
        $this->client = $client ?: new Client();
        $this->config = $config ?: Configuration::getDefaultConfiguration();
        $this->headerSelector = $selector ?: new HeaderSelector();
        $this->hostIndex = $hostIndex;
    }

    /**
     * Set the host index
     *
     * @param int $hostIndex Host index (required)
     */
    public function setHostIndex($hostIndex): void
    {
        $this->hostIndex = $hostIndex;
    }

    /**
     * Get the host index
     *
     * @return int Host index
     */
    public function getHostIndex()
    {
        return $this->hostIndex;
    }

    /**
     * @return Configuration
     */
    public function getConfig()
    {
        return $this->config;
    }

    /**
     * Operation createService
     *
     * Create a service order
     *
     * @param  \Vend202601\Model\ServiceOrderRequest $service_order_request service_order_request (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['createService'] to see the possible values for this operation
     *
     * @throws \Vend202601\ApiException on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     * @return \Vend202601\Model\DetailedService|\Vend202601\Model\CreateService400Response|\Vend202601\Model\CreateService401Response|\Vend202601\Model\CreateService403Response
     */
    public function createService($service_order_request, string $contentType = self::contentTypes['createService'][0])
    {
        list($response) = $this->createServiceWithHttpInfo($service_order_request, $contentType);
        return $response;
    }

    /**
     * Operation createServiceWithHttpInfo
     *
     * Create a service order
     *
     * @param  \Vend202601\Model\ServiceOrderRequest $service_order_request (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['createService'] to see the possible values for this operation
     *
     * @throws \Vend202601\ApiException on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     * @return array of \Vend202601\Model\DetailedService|\Vend202601\Model\CreateService400Response|\Vend202601\Model\CreateService401Response|\Vend202601\Model\CreateService403Response, HTTP status code, HTTP response headers (array of strings)
     */
    public function createServiceWithHttpInfo($service_order_request, string $contentType = self::contentTypes['createService'][0])
    {
        $request = $this->createServiceRequest($service_order_request, $contentType);

        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    (int) $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? (string) $e->getResponse()->getBody() : null
                );
            } catch (ConnectException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    (int) $e->getCode(),
                    null,
                    null
                );
            }

            $statusCode = $response->getStatusCode();


            switch($statusCode) {
                case 200:
                    return $this->handleResponseWithDataType(
                        '\Vend202601\Model\DetailedService',
                        $request,
                        $response,
                    );
                case 400:
                    return $this->handleResponseWithDataType(
                        '\Vend202601\Model\CreateService400Response',
                        $request,
                        $response,
                    );
                case 401:
                    return $this->handleResponseWithDataType(
                        '\Vend202601\Model\CreateService401Response',
                        $request,
                        $response,
                    );
                case 403:
                    return $this->handleResponseWithDataType(
                        '\Vend202601\Model\CreateService403Response',
                        $request,
                        $response,
                    );
            }

            

            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 $this->handleResponseWithDataType(
                '\Vend202601\Model\DetailedService',
                $request,
                $response,
            );
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Vend202601\Model\DetailedService',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    throw $e;
                case 400:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Vend202601\Model\CreateService400Response',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    throw $e;
                case 401:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Vend202601\Model\CreateService401Response',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    throw $e;
                case 403:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Vend202601\Model\CreateService403Response',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    throw $e;
            }
        

            throw $e;
        }
    }

    /**
     * Operation createServiceAsync
     *
     * Create a service order
     *
     * @param  \Vend202601\Model\ServiceOrderRequest $service_order_request (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['createService'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function createServiceAsync($service_order_request, string $contentType = self::contentTypes['createService'][0])
    {
        return $this->createServiceAsyncWithHttpInfo($service_order_request, $contentType)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }

    /**
     * Operation createServiceAsyncWithHttpInfo
     *
     * Create a service order
     *
     * @param  \Vend202601\Model\ServiceOrderRequest $service_order_request (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['createService'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function createServiceAsyncWithHttpInfo($service_order_request, string $contentType = self::contentTypes['createService'][0])
    {
        $returnType = '\Vend202601\Model\DetailedService';
        $request = $this->createServiceRequest($service_order_request, $contentType);

        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    if ($returnType === '\SplFileObject') {
                        $content = $response->getBody(); //stream goes to serializer
                    } else {
                        $content = (string) $response->getBody();
                        if ($returnType !== 'string') {
                            $content = json_decode($content);
                        }
                    }

                    return [
                        ObjectSerializer::deserialize($content, $returnType, []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                },
                function ($exception) {
                    $response = $exception->getResponse();
                    $statusCode = $response->getStatusCode();
                    throw new ApiException(
                        sprintf(
                            '[%d] Error connecting to the API (%s)',
                            $statusCode,
                            $exception->getRequest()->getUri()
                        ),
                        $statusCode,
                        $response->getHeaders(),
                        (string) $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'createService'
     *
     * @param  \Vend202601\Model\ServiceOrderRequest $service_order_request (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['createService'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request
     */
    public function createServiceRequest($service_order_request, string $contentType = self::contentTypes['createService'][0])
    {

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


        $resourcePath = '/services';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;





        $headers = $this->headerSelector->selectHeaders(
            ['application/json', ],
            $contentType,
            $multipart
        );

        // for model (json/xml)
        if (isset($service_order_request)) {
            if (stripos($headers['Content-Type'], 'application/json') !== false) {
                # if Content-Type contains "application/json", json_encode the body
                $httpBody = \GuzzleHttp\Utils::jsonEncode(ObjectSerializer::sanitizeForSerialization($service_order_request));
            } else {
                $httpBody = $service_order_request;
            }
        } 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
                        ];
                    }
                }
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif (stripos($headers['Content-Type'], 'application/json') !== false) {
                # if Content-Type contains "application/json", json_encode the form parameters
                $httpBody = \GuzzleHttp\Utils::jsonEncode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = ObjectSerializer::buildQuery($formParams);
            }
        }

        // this endpoint requires Bearer authentication (access token)
        if (!empty($this->config->getAccessToken())) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }

        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }

        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );

        $operationHost = $this->config->getHost();
        $query = ObjectSerializer::buildQuery($queryParams);
        return new Request(
            'POST',
            $operationHost . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getAgendaOutletId
     *
     * Get services agenda by outlet
     *
     * @param  \DateTime $start_date The first date of the time window for which the agenda is requested. (required)
     * @param  string $outlet_id outlet_id (required)
     * @param  int|null $days The size, in days, of the time window for which the agenda is requested. (optional, default to 7)
     * @param  string|null $timezone The timezone in which the agenda is requested. When provided, the agenda returned will account for time changes like daylight savings. (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['getAgendaOutletId'] to see the possible values for this operation
     *
     * @throws \Vend202601\ApiException on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     * @return \Vend202601\Model\DailyAgenda[]
     */
    public function getAgendaOutletId($start_date, $outlet_id, $days = 7, $timezone = null, string $contentType = self::contentTypes['getAgendaOutletId'][0])
    {
        list($response) = $this->getAgendaOutletIdWithHttpInfo($start_date, $outlet_id, $days, $timezone, $contentType);
        return $response;
    }

    /**
     * Operation getAgendaOutletIdWithHttpInfo
     *
     * Get services agenda by outlet
     *
     * @param  \DateTime $start_date The first date of the time window for which the agenda is requested. (required)
     * @param  string $outlet_id (required)
     * @param  int|null $days The size, in days, of the time window for which the agenda is requested. (optional, default to 7)
     * @param  string|null $timezone The timezone in which the agenda is requested. When provided, the agenda returned will account for time changes like daylight savings. (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['getAgendaOutletId'] to see the possible values for this operation
     *
     * @throws \Vend202601\ApiException on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     * @return array of \Vend202601\Model\DailyAgenda[], HTTP status code, HTTP response headers (array of strings)
     */
    public function getAgendaOutletIdWithHttpInfo($start_date, $outlet_id, $days = 7, $timezone = null, string $contentType = self::contentTypes['getAgendaOutletId'][0])
    {
        $request = $this->getAgendaOutletIdRequest($start_date, $outlet_id, $days, $timezone, $contentType);

        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    (int) $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? (string) $e->getResponse()->getBody() : null
                );
            } catch (ConnectException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    (int) $e->getCode(),
                    null,
                    null
                );
            }

            $statusCode = $response->getStatusCode();


            switch($statusCode) {
                case 200:
                    return $this->handleResponseWithDataType(
                        '\Vend202601\Model\DailyAgenda[]',
                        $request,
                        $response,
                    );
            }

            

            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 $this->handleResponseWithDataType(
                '\Vend202601\Model\DailyAgenda[]',
                $request,
                $response,
            );
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Vend202601\Model\DailyAgenda[]',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    throw $e;
            }
        

            throw $e;
        }
    }

    /**
     * Operation getAgendaOutletIdAsync
     *
     * Get services agenda by outlet
     *
     * @param  \DateTime $start_date The first date of the time window for which the agenda is requested. (required)
     * @param  string $outlet_id (required)
     * @param  int|null $days The size, in days, of the time window for which the agenda is requested. (optional, default to 7)
     * @param  string|null $timezone The timezone in which the agenda is requested. When provided, the agenda returned will account for time changes like daylight savings. (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['getAgendaOutletId'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getAgendaOutletIdAsync($start_date, $outlet_id, $days = 7, $timezone = null, string $contentType = self::contentTypes['getAgendaOutletId'][0])
    {
        return $this->getAgendaOutletIdAsyncWithHttpInfo($start_date, $outlet_id, $days, $timezone, $contentType)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }

    /**
     * Operation getAgendaOutletIdAsyncWithHttpInfo
     *
     * Get services agenda by outlet
     *
     * @param  \DateTime $start_date The first date of the time window for which the agenda is requested. (required)
     * @param  string $outlet_id (required)
     * @param  int|null $days The size, in days, of the time window for which the agenda is requested. (optional, default to 7)
     * @param  string|null $timezone The timezone in which the agenda is requested. When provided, the agenda returned will account for time changes like daylight savings. (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['getAgendaOutletId'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getAgendaOutletIdAsyncWithHttpInfo($start_date, $outlet_id, $days = 7, $timezone = null, string $contentType = self::contentTypes['getAgendaOutletId'][0])
    {
        $returnType = '\Vend202601\Model\DailyAgenda[]';
        $request = $this->getAgendaOutletIdRequest($start_date, $outlet_id, $days, $timezone, $contentType);

        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    if ($returnType === '\SplFileObject') {
                        $content = $response->getBody(); //stream goes to serializer
                    } else {
                        $content = (string) $response->getBody();
                        if ($returnType !== 'string') {
                            $content = json_decode($content);
                        }
                    }

                    return [
                        ObjectSerializer::deserialize($content, $returnType, []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                },
                function ($exception) {
                    $response = $exception->getResponse();
                    $statusCode = $response->getStatusCode();
                    throw new ApiException(
                        sprintf(
                            '[%d] Error connecting to the API (%s)',
                            $statusCode,
                            $exception->getRequest()->getUri()
                        ),
                        $statusCode,
                        $response->getHeaders(),
                        (string) $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getAgendaOutletId'
     *
     * @param  \DateTime $start_date The first date of the time window for which the agenda is requested. (required)
     * @param  string $outlet_id (required)
     * @param  int|null $days The size, in days, of the time window for which the agenda is requested. (optional, default to 7)
     * @param  string|null $timezone The timezone in which the agenda is requested. When provided, the agenda returned will account for time changes like daylight savings. (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['getAgendaOutletId'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request
     */
    public function getAgendaOutletIdRequest($start_date, $outlet_id, $days = 7, $timezone = null, string $contentType = self::contentTypes['getAgendaOutletId'][0])
    {

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

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




        $resourcePath = '/services_agenda/outlet/{outlet_id}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;

        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $days,
            'days', // param base name
            'integer', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $start_date,
            'start_date', // param base name
            'string', // openApiType
            'form', // style
            true, // explode
            true // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $timezone,
            'timezone', // param base name
            'string', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);


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


        $headers = $this->headerSelector->selectHeaders(
            ['application/json', ],
            $contentType,
            $multipart
        );

        // 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
                        ];
                    }
                }
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif (stripos($headers['Content-Type'], 'application/json') !== false) {
                # if Content-Type contains "application/json", json_encode the form parameters
                $httpBody = \GuzzleHttp\Utils::jsonEncode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = ObjectSerializer::buildQuery($formParams);
            }
        }

        // this endpoint requires Bearer authentication (access token)
        if (!empty($this->config->getAccessToken())) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }

        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }

        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );

        $operationHost = $this->config->getHost();
        $query = ObjectSerializer::buildQuery($queryParams);
        return new Request(
            'GET',
            $operationHost . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getService
     *
     * Get service
     *
     * @param  string $service_id ID of the service to get (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['getService'] to see the possible values for this operation
     *
     * @throws \Vend202601\ApiException on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     * @return \Vend202601\Model\DetailedService
     */
    public function getService($service_id, string $contentType = self::contentTypes['getService'][0])
    {
        list($response) = $this->getServiceWithHttpInfo($service_id, $contentType);
        return $response;
    }

    /**
     * Operation getServiceWithHttpInfo
     *
     * Get service
     *
     * @param  string $service_id ID of the service to get (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['getService'] to see the possible values for this operation
     *
     * @throws \Vend202601\ApiException on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     * @return array of \Vend202601\Model\DetailedService, HTTP status code, HTTP response headers (array of strings)
     */
    public function getServiceWithHttpInfo($service_id, string $contentType = self::contentTypes['getService'][0])
    {
        $request = $this->getServiceRequest($service_id, $contentType);

        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    (int) $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? (string) $e->getResponse()->getBody() : null
                );
            } catch (ConnectException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    (int) $e->getCode(),
                    null,
                    null
                );
            }

            $statusCode = $response->getStatusCode();


            switch($statusCode) {
                case 200:
                    return $this->handleResponseWithDataType(
                        '\Vend202601\Model\DetailedService',
                        $request,
                        $response,
                    );
            }

            

            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 $this->handleResponseWithDataType(
                '\Vend202601\Model\DetailedService',
                $request,
                $response,
            );
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Vend202601\Model\DetailedService',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    throw $e;
            }
        

            throw $e;
        }
    }

    /**
     * Operation getServiceAsync
     *
     * Get service
     *
     * @param  string $service_id ID of the service to get (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['getService'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getServiceAsync($service_id, string $contentType = self::contentTypes['getService'][0])
    {
        return $this->getServiceAsyncWithHttpInfo($service_id, $contentType)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }

    /**
     * Operation getServiceAsyncWithHttpInfo
     *
     * Get service
     *
     * @param  string $service_id ID of the service to get (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['getService'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getServiceAsyncWithHttpInfo($service_id, string $contentType = self::contentTypes['getService'][0])
    {
        $returnType = '\Vend202601\Model\DetailedService';
        $request = $this->getServiceRequest($service_id, $contentType);

        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    if ($returnType === '\SplFileObject') {
                        $content = $response->getBody(); //stream goes to serializer
                    } else {
                        $content = (string) $response->getBody();
                        if ($returnType !== 'string') {
                            $content = json_decode($content);
                        }
                    }

                    return [
                        ObjectSerializer::deserialize($content, $returnType, []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                },
                function ($exception) {
                    $response = $exception->getResponse();
                    $statusCode = $response->getStatusCode();
                    throw new ApiException(
                        sprintf(
                            '[%d] Error connecting to the API (%s)',
                            $statusCode,
                            $exception->getRequest()->getUri()
                        ),
                        $statusCode,
                        $response->getHeaders(),
                        (string) $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getService'
     *
     * @param  string $service_id ID of the service to get (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['getService'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request
     */
    public function getServiceRequest($service_id, string $contentType = self::contentTypes['getService'][0])
    {

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


        $resourcePath = '/services/{service_id}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;



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


        $headers = $this->headerSelector->selectHeaders(
            ['application/json', ],
            $contentType,
            $multipart
        );

        // 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
                        ];
                    }
                }
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif (stripos($headers['Content-Type'], 'application/json') !== false) {
                # if Content-Type contains "application/json", json_encode the form parameters
                $httpBody = \GuzzleHttp\Utils::jsonEncode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = ObjectSerializer::buildQuery($formParams);
            }
        }

        // this endpoint requires Bearer authentication (access token)
        if (!empty($this->config->getAccessToken())) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }

        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }

        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );

        $operationHost = $this->config->getHost();
        $query = ObjectSerializer::buildQuery($queryParams);
        return new Request(
            'GET',
            $operationHost . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation listServiceItems
     *
     * List a customer&#39;s service items
     *
     * @param  string $customer_id The customer id (required)
     * @param  int|null $after The lower limit for the service id to be included in the response. For proper pagination, it needs to be the item id of the last item in the response from your previous request. (optional)
     * @param  int|null $limit The maximum number of items to be returned in the response. (optional, default to 100)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['listServiceItems'] to see the possible values for this operation
     *
     * @throws \Vend202601\ApiException on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     * @return \Vend202601\Model\ListServiceItems200Response
     */
    public function listServiceItems($customer_id, $after = null, $limit = 100, string $contentType = self::contentTypes['listServiceItems'][0])
    {
        list($response) = $this->listServiceItemsWithHttpInfo($customer_id, $after, $limit, $contentType);
        return $response;
    }

    /**
     * Operation listServiceItemsWithHttpInfo
     *
     * List a customer&#39;s service items
     *
     * @param  string $customer_id The customer id (required)
     * @param  int|null $after The lower limit for the service id to be included in the response. For proper pagination, it needs to be the item id of the last item in the response from your previous request. (optional)
     * @param  int|null $limit The maximum number of items to be returned in the response. (optional, default to 100)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['listServiceItems'] to see the possible values for this operation
     *
     * @throws \Vend202601\ApiException on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     * @return array of \Vend202601\Model\ListServiceItems200Response, HTTP status code, HTTP response headers (array of strings)
     */
    public function listServiceItemsWithHttpInfo($customer_id, $after = null, $limit = 100, string $contentType = self::contentTypes['listServiceItems'][0])
    {
        $request = $this->listServiceItemsRequest($customer_id, $after, $limit, $contentType);

        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    (int) $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? (string) $e->getResponse()->getBody() : null
                );
            } catch (ConnectException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    (int) $e->getCode(),
                    null,
                    null
                );
            }

            $statusCode = $response->getStatusCode();


            switch($statusCode) {
                case 200:
                    return $this->handleResponseWithDataType(
                        '\Vend202601\Model\ListServiceItems200Response',
                        $request,
                        $response,
                    );
            }

            

            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 $this->handleResponseWithDataType(
                '\Vend202601\Model\ListServiceItems200Response',
                $request,
                $response,
            );
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Vend202601\Model\ListServiceItems200Response',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    throw $e;
            }
        

            throw $e;
        }
    }

    /**
     * Operation listServiceItemsAsync
     *
     * List a customer&#39;s service items
     *
     * @param  string $customer_id The customer id (required)
     * @param  int|null $after The lower limit for the service id to be included in the response. For proper pagination, it needs to be the item id of the last item in the response from your previous request. (optional)
     * @param  int|null $limit The maximum number of items to be returned in the response. (optional, default to 100)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['listServiceItems'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function listServiceItemsAsync($customer_id, $after = null, $limit = 100, string $contentType = self::contentTypes['listServiceItems'][0])
    {
        return $this->listServiceItemsAsyncWithHttpInfo($customer_id, $after, $limit, $contentType)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }

    /**
     * Operation listServiceItemsAsyncWithHttpInfo
     *
     * List a customer&#39;s service items
     *
     * @param  string $customer_id The customer id (required)
     * @param  int|null $after The lower limit for the service id to be included in the response. For proper pagination, it needs to be the item id of the last item in the response from your previous request. (optional)
     * @param  int|null $limit The maximum number of items to be returned in the response. (optional, default to 100)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['listServiceItems'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function listServiceItemsAsyncWithHttpInfo($customer_id, $after = null, $limit = 100, string $contentType = self::contentTypes['listServiceItems'][0])
    {
        $returnType = '\Vend202601\Model\ListServiceItems200Response';
        $request = $this->listServiceItemsRequest($customer_id, $after, $limit, $contentType);

        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    if ($returnType === '\SplFileObject') {
                        $content = $response->getBody(); //stream goes to serializer
                    } else {
                        $content = (string) $response->getBody();
                        if ($returnType !== 'string') {
                            $content = json_decode($content);
                        }
                    }

                    return [
                        ObjectSerializer::deserialize($content, $returnType, []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                },
                function ($exception) {
                    $response = $exception->getResponse();
                    $statusCode = $response->getStatusCode();
                    throw new ApiException(
                        sprintf(
                            '[%d] Error connecting to the API (%s)',
                            $statusCode,
                            $exception->getRequest()->getUri()
                        ),
                        $statusCode,
                        $response->getHeaders(),
                        (string) $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'listServiceItems'
     *
     * @param  string $customer_id The customer id (required)
     * @param  int|null $after The lower limit for the service id to be included in the response. For proper pagination, it needs to be the item id of the last item in the response from your previous request. (optional)
     * @param  int|null $limit The maximum number of items to be returned in the response. (optional, default to 100)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['listServiceItems'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request
     */
    public function listServiceItemsRequest($customer_id, $after = null, $limit = 100, string $contentType = self::contentTypes['listServiceItems'][0])
    {

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




        $resourcePath = '/service_items/customer/{customer_id}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;

        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $after,
            'after', // param base name
            'integer', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $limit,
            'limit', // param base name
            'integer', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);


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


        $headers = $this->headerSelector->selectHeaders(
            ['application/json', ],
            $contentType,
            $multipart
        );

        // 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
                        ];
                    }
                }
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif (stripos($headers['Content-Type'], 'application/json') !== false) {
                # if Content-Type contains "application/json", json_encode the form parameters
                $httpBody = \GuzzleHttp\Utils::jsonEncode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = ObjectSerializer::buildQuery($formParams);
            }
        }

        // this endpoint requires Bearer authentication (access token)
        if (!empty($this->config->getAccessToken())) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }

        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }

        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );

        $operationHost = $this->config->getHost();
        $query = ObjectSerializer::buildQuery($queryParams);
        return new Request(
            'GET',
            $operationHost . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation listServices
     *
     * List services
     *
     * @param  int|null $after The lower limit for the service id to be included in the response. For proper pagination, it needs to be the service id of the last item in the response from your previous request. (optional)
     * @param  int|null $limit The maximum number of items to be returned in the response. (optional, default to 100)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['listServices'] to see the possible values for this operation
     *
     * @throws \Vend202601\ApiException on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     * @return \Vend202601\Model\ListServices200Response
     */
    public function listServices($after = null, $limit = 100, string $contentType = self::contentTypes['listServices'][0])
    {
        list($response) = $this->listServicesWithHttpInfo($after, $limit, $contentType);
        return $response;
    }

    /**
     * Operation listServicesWithHttpInfo
     *
     * List services
     *
     * @param  int|null $after The lower limit for the service id to be included in the response. For proper pagination, it needs to be the service id of the last item in the response from your previous request. (optional)
     * @param  int|null $limit The maximum number of items to be returned in the response. (optional, default to 100)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['listServices'] to see the possible values for this operation
     *
     * @throws \Vend202601\ApiException on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     * @return array of \Vend202601\Model\ListServices200Response, HTTP status code, HTTP response headers (array of strings)
     */
    public function listServicesWithHttpInfo($after = null, $limit = 100, string $contentType = self::contentTypes['listServices'][0])
    {
        $request = $this->listServicesRequest($after, $limit, $contentType);

        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    (int) $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? (string) $e->getResponse()->getBody() : null
                );
            } catch (ConnectException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    (int) $e->getCode(),
                    null,
                    null
                );
            }

            $statusCode = $response->getStatusCode();


            switch($statusCode) {
                case 200:
                    return $this->handleResponseWithDataType(
                        '\Vend202601\Model\ListServices200Response',
                        $request,
                        $response,
                    );
            }

            

            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 $this->handleResponseWithDataType(
                '\Vend202601\Model\ListServices200Response',
                $request,
                $response,
            );
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Vend202601\Model\ListServices200Response',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    throw $e;
            }
        

            throw $e;
        }
    }

    /**
     * Operation listServicesAsync
     *
     * List services
     *
     * @param  int|null $after The lower limit for the service id to be included in the response. For proper pagination, it needs to be the service id of the last item in the response from your previous request. (optional)
     * @param  int|null $limit The maximum number of items to be returned in the response. (optional, default to 100)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['listServices'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function listServicesAsync($after = null, $limit = 100, string $contentType = self::contentTypes['listServices'][0])
    {
        return $this->listServicesAsyncWithHttpInfo($after, $limit, $contentType)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }

    /**
     * Operation listServicesAsyncWithHttpInfo
     *
     * List services
     *
     * @param  int|null $after The lower limit for the service id to be included in the response. For proper pagination, it needs to be the service id of the last item in the response from your previous request. (optional)
     * @param  int|null $limit The maximum number of items to be returned in the response. (optional, default to 100)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['listServices'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function listServicesAsyncWithHttpInfo($after = null, $limit = 100, string $contentType = self::contentTypes['listServices'][0])
    {
        $returnType = '\Vend202601\Model\ListServices200Response';
        $request = $this->listServicesRequest($after, $limit, $contentType);

        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    if ($returnType === '\SplFileObject') {
                        $content = $response->getBody(); //stream goes to serializer
                    } else {
                        $content = (string) $response->getBody();
                        if ($returnType !== 'string') {
                            $content = json_decode($content);
                        }
                    }

                    return [
                        ObjectSerializer::deserialize($content, $returnType, []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                },
                function ($exception) {
                    $response = $exception->getResponse();
                    $statusCode = $response->getStatusCode();
                    throw new ApiException(
                        sprintf(
                            '[%d] Error connecting to the API (%s)',
                            $statusCode,
                            $exception->getRequest()->getUri()
                        ),
                        $statusCode,
                        $response->getHeaders(),
                        (string) $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'listServices'
     *
     * @param  int|null $after The lower limit for the service id to be included in the response. For proper pagination, it needs to be the service id of the last item in the response from your previous request. (optional)
     * @param  int|null $limit The maximum number of items to be returned in the response. (optional, default to 100)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['listServices'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request
     */
    public function listServicesRequest($after = null, $limit = 100, string $contentType = self::contentTypes['listServices'][0])
    {




        $resourcePath = '/services';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;

        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $after,
            'after', // param base name
            'integer', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $limit,
            'limit', // param base name
            'integer', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);




        $headers = $this->headerSelector->selectHeaders(
            ['application/json', ],
            $contentType,
            $multipart
        );

        // 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
                        ];
                    }
                }
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif (stripos($headers['Content-Type'], 'application/json') !== false) {
                # if Content-Type contains "application/json", json_encode the form parameters
                $httpBody = \GuzzleHttp\Utils::jsonEncode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = ObjectSerializer::buildQuery($formParams);
            }
        }

        // this endpoint requires Bearer authentication (access token)
        if (!empty($this->config->getAccessToken())) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }

        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }

        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );

        $operationHost = $this->config->getHost();
        $query = ObjectSerializer::buildQuery($queryParams);
        return new Request(
            'GET',
            $operationHost . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Create http client option
     *
     * @throws \RuntimeException on file opening failure
     * @return array of http client options
     */
    protected function createHttpClientOption()
    {
        $options = [];
        if ($this->config->getDebug()) {
            $options[RequestOptions::DEBUG] = fopen($this->config->getDebugFile(), 'a');
            if (!$options[RequestOptions::DEBUG]) {
                throw new \RuntimeException('Failed to open the debug file: ' . $this->config->getDebugFile());
            }
        }

        if ($this->config->getCertFile()) {
            $options[RequestOptions::CERT] = $this->config->getCertFile();
        }

        if ($this->config->getKeyFile()) {
            $options[RequestOptions::SSL_KEY] = $this->config->getKeyFile();
        }

        return $options;
    }

    private function handleResponseWithDataType(
        string $dataType,
        RequestInterface $request,
        ResponseInterface $response
    ): array {
        if ($dataType === '\SplFileObject') {
            $content = $response->getBody(); //stream goes to serializer
        } else {
            $content = (string) $response->getBody();
            if ($dataType !== 'string') {
                try {
                    $content = json_decode($content, false, 512, JSON_THROW_ON_ERROR);
                } catch (\JsonException $exception) {
                    throw new ApiException(
                        sprintf(
                            'Error JSON decoding server response (%s)',
                            $request->getUri()
                        ),
                        $response->getStatusCode(),
                        $response->getHeaders(),
                        $content
                    );
                }
            }
        }

        return [
            ObjectSerializer::deserialize($content, $dataType, []),
            $response->getStatusCode(),
            $response->getHeaders()
        ];
    }

    private function responseWithinRangeCode(
        string $rangeCode,
        int $statusCode
    ): bool {
        $left = (int) ($rangeCode[0].'00');
        $right = (int) ($rangeCode[0].'99');

        return $statusCode >= $left && $statusCode <= $right;
    }
}
