<?php
/**
 * SearchApi
 * 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.21.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;

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

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

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

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

    /** @var string[] $contentTypes **/
    public const contentTypes = [
        'search' => [
            '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 search
     *
     * Search for resources
     *
     * @param  string $type The entity type to search for. (required)
     * @param  string|null $order_by The attribute used to sort items returned in the response. (optional)
     * @param  string|null $order_direction Sorting direction. (optional)
     * @param  int|null $page_size The maximum number of objects to be included in the response, currently limited to 1000. Specifying more than 1000 will result in 1000 objects being returned. (optional)
     * @param  int|null $offset The number of objects to be \&quot;skipped\&quot; for the response. Used for pagination. (optional)
     * @param  string|null $_id The &#x60;id&#x60; of the object to be included in the response. (optional)
     * @param  string|null $__id The &#x60;id&#x60; of the object to be excluded from the response. (optional)
     * @param  bool|null $deleted Indicated whether deleted objects should be included in the response. (optional)
     * @param  string|null $status **SALES** Status of the sale to find. Can be used multiple times to search for objects with different values of this parameter. Deprecated, please use state and attributes instead. (optional) (deprecated)
     * @param  string|null $state **SALES** State of the sale to find. Can be used multiple times to search for objects with different values of this parameter. (optional)
     * @param  string[]|null $attributes **SALES** Attributes of the sale to find. Can be used multiple times to search for objects with different values of this parameter. (optional)
     * @param  string|null $invoice_number **SALES** Invoice number of the sale. (optional)
     * @param  string|null $customer_id **SALES** The &#x60;ID&#x60; of the customer associated with the sales. (optional)
     * @param  string|null $user_id **SALES** The &#x60;ID&#x60; of the user associated with the sales. (optional)
     * @param  string|null $outlet_id **SALES** The &#x60;ID&#x60; of the outlet associated with the sales. (optional)
     * @param  string|null $date_from **SALES** Lower limit for the sale date as UTC timestamp. Format: &#x60;2016-08-08T12:00:00Z&#x60;. (optional)
     * @param  string|null $date_to **SALES** Upper limit for the sale date as UTC timestamp. Format: &#x60;2016-08-08T12:00:00Z&#x60;. (optional)
     * @param  string|null $sku **PRODUCTS** The SKU of products to include in the search. Can be used multiple times to search for objects with different values of this parameter. (optional)
     * @param  string|null $_sku **PRODUCTS** The SKU of products to exclude from the search. Can be used multiple times to search for objects with different values of this parameter. (optional)
     * @param  string|null $supplier_id **PRODUCTS** The ID of the supplier associated with the product to include in the search. Can be used multiple times to search for objects with different values of this parameter. (optional)
     * @param  string|null $_supplier_id **PRODUCTS** The ID of the supplier associated with the product to exclude from the search. Can be used multiple times to search for objects with different values of this parameter. (optional)
     * @param  string|null $brand_id **PRODUCTS** The ID of the brand associated with the product to include in the search. Can be used multiple times to search for objects with different values of this parameter. (optional)
     * @param  string|null $_brand_id **PRODUCTS** The ID of the brand associated with the product to exclude from the search. Can be used multiple times to search for objects with different values of this parameter. (optional)
     * @param  string|null $tag_id **PRODUCTS** The ID of the tag associated with the product to include in the search. Can be used multiple times to search for objects with different values of this parameter. (optional)
     * @param  string|null $_tag_id **PRODUCTS** The ID of the brand associated with the product to exclude from the search. Can be used multiple times to search for objects with different values of this parameter. (optional)
     * @param  string|null $product_type_id **PRODUCTS** The ID of the product type associated with the product to include in the search. Can be used multiple times to search for objects with different values of this parameter. (optional)
     * @param  string|null $_product_type_id **PRODUCTS** The ID of the product type associated with the product to exclude from the search. Can be used multiple times to search for objects with different values of this parameter. (optional)
     * @param  string|null $variant_parent_id **PRODUCTS** The ID of the variant parent product associated with the product to include in the search. Can be used multiple times to search for objects with different values of this parameter. (optional)
     * @param  string|null $_variant_parent_id **PRODUCTS** The ID of the variant parent product associated with the product to exclude from the search. Can be used multiple times to search for objects with different values of this parameter. (optional)
     * @param  string|null $customer_code **CUSTOMERS** The &#x60;customer_code&#x60; associated with the customer to find. (optional)
     * @param  string|null $email **CUSTOMERS** The &#x60;email&#x60; address associated with the customer to find. (optional)
     * @param  string|null $first_name **CUSTOMERS** The &#x60;first_name&#x60; for the customers to find. (optional)
     * @param  string|null $last_name **CUSTOMERS** The &#x60;last_name&#x60; for the customers to find. (optional)
     * @param  string|null $company_name **CUSTOMERS** The &#x60;company_name&#x60; for the customers to find. (optional)
     * @param  string|null $mobile **CUSTOMERS** The &#x60;mobile number&#x60; for the customers to find. (optional)
     * @param  string|null $phone **CUSTOMERS** The &#x60;phone number&#x60; for the customers to find. (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['search'] 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\SearchResponse
     */
    public function search($type, $order_by = null, $order_direction = null, $page_size = null, $offset = null, $_id = null, $__id = null, $deleted = null, $status = null, $state = null, $attributes = null, $invoice_number = null, $customer_id = null, $user_id = null, $outlet_id = null, $date_from = null, $date_to = null, $sku = null, $_sku = null, $supplier_id = null, $_supplier_id = null, $brand_id = null, $_brand_id = null, $tag_id = null, $_tag_id = null, $product_type_id = null, $_product_type_id = null, $variant_parent_id = null, $_variant_parent_id = null, $customer_code = null, $email = null, $first_name = null, $last_name = null, $company_name = null, $mobile = null, $phone = null, string $contentType = self::contentTypes['search'][0])
    {
        list($response) = $this->searchWithHttpInfo($type, $order_by, $order_direction, $page_size, $offset, $_id, $__id, $deleted, $status, $state, $attributes, $invoice_number, $customer_id, $user_id, $outlet_id, $date_from, $date_to, $sku, $_sku, $supplier_id, $_supplier_id, $brand_id, $_brand_id, $tag_id, $_tag_id, $product_type_id, $_product_type_id, $variant_parent_id, $_variant_parent_id, $customer_code, $email, $first_name, $last_name, $company_name, $mobile, $phone, $contentType);
        return $response;
    }

    /**
     * Operation searchWithHttpInfo
     *
     * Search for resources
     *
     * @param  string $type The entity type to search for. (required)
     * @param  string|null $order_by The attribute used to sort items returned in the response. (optional)
     * @param  string|null $order_direction Sorting direction. (optional)
     * @param  int|null $page_size The maximum number of objects to be included in the response, currently limited to 1000. Specifying more than 1000 will result in 1000 objects being returned. (optional)
     * @param  int|null $offset The number of objects to be \&quot;skipped\&quot; for the response. Used for pagination. (optional)
     * @param  string|null $_id The &#x60;id&#x60; of the object to be included in the response. (optional)
     * @param  string|null $__id The &#x60;id&#x60; of the object to be excluded from the response. (optional)
     * @param  bool|null $deleted Indicated whether deleted objects should be included in the response. (optional)
     * @param  string|null $status **SALES** Status of the sale to find. Can be used multiple times to search for objects with different values of this parameter. Deprecated, please use state and attributes instead. (optional) (deprecated)
     * @param  string|null $state **SALES** State of the sale to find. Can be used multiple times to search for objects with different values of this parameter. (optional)
     * @param  string[]|null $attributes **SALES** Attributes of the sale to find. Can be used multiple times to search for objects with different values of this parameter. (optional)
     * @param  string|null $invoice_number **SALES** Invoice number of the sale. (optional)
     * @param  string|null $customer_id **SALES** The &#x60;ID&#x60; of the customer associated with the sales. (optional)
     * @param  string|null $user_id **SALES** The &#x60;ID&#x60; of the user associated with the sales. (optional)
     * @param  string|null $outlet_id **SALES** The &#x60;ID&#x60; of the outlet associated with the sales. (optional)
     * @param  string|null $date_from **SALES** Lower limit for the sale date as UTC timestamp. Format: &#x60;2016-08-08T12:00:00Z&#x60;. (optional)
     * @param  string|null $date_to **SALES** Upper limit for the sale date as UTC timestamp. Format: &#x60;2016-08-08T12:00:00Z&#x60;. (optional)
     * @param  string|null $sku **PRODUCTS** The SKU of products to include in the search. Can be used multiple times to search for objects with different values of this parameter. (optional)
     * @param  string|null $_sku **PRODUCTS** The SKU of products to exclude from the search. Can be used multiple times to search for objects with different values of this parameter. (optional)
     * @param  string|null $supplier_id **PRODUCTS** The ID of the supplier associated with the product to include in the search. Can be used multiple times to search for objects with different values of this parameter. (optional)
     * @param  string|null $_supplier_id **PRODUCTS** The ID of the supplier associated with the product to exclude from the search. Can be used multiple times to search for objects with different values of this parameter. (optional)
     * @param  string|null $brand_id **PRODUCTS** The ID of the brand associated with the product to include in the search. Can be used multiple times to search for objects with different values of this parameter. (optional)
     * @param  string|null $_brand_id **PRODUCTS** The ID of the brand associated with the product to exclude from the search. Can be used multiple times to search for objects with different values of this parameter. (optional)
     * @param  string|null $tag_id **PRODUCTS** The ID of the tag associated with the product to include in the search. Can be used multiple times to search for objects with different values of this parameter. (optional)
     * @param  string|null $_tag_id **PRODUCTS** The ID of the brand associated with the product to exclude from the search. Can be used multiple times to search for objects with different values of this parameter. (optional)
     * @param  string|null $product_type_id **PRODUCTS** The ID of the product type associated with the product to include in the search. Can be used multiple times to search for objects with different values of this parameter. (optional)
     * @param  string|null $_product_type_id **PRODUCTS** The ID of the product type associated with the product to exclude from the search. Can be used multiple times to search for objects with different values of this parameter. (optional)
     * @param  string|null $variant_parent_id **PRODUCTS** The ID of the variant parent product associated with the product to include in the search. Can be used multiple times to search for objects with different values of this parameter. (optional)
     * @param  string|null $_variant_parent_id **PRODUCTS** The ID of the variant parent product associated with the product to exclude from the search. Can be used multiple times to search for objects with different values of this parameter. (optional)
     * @param  string|null $customer_code **CUSTOMERS** The &#x60;customer_code&#x60; associated with the customer to find. (optional)
     * @param  string|null $email **CUSTOMERS** The &#x60;email&#x60; address associated with the customer to find. (optional)
     * @param  string|null $first_name **CUSTOMERS** The &#x60;first_name&#x60; for the customers to find. (optional)
     * @param  string|null $last_name **CUSTOMERS** The &#x60;last_name&#x60; for the customers to find. (optional)
     * @param  string|null $company_name **CUSTOMERS** The &#x60;company_name&#x60; for the customers to find. (optional)
     * @param  string|null $mobile **CUSTOMERS** The &#x60;mobile number&#x60; for the customers to find. (optional)
     * @param  string|null $phone **CUSTOMERS** The &#x60;phone number&#x60; for the customers to find. (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['search'] 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\SearchResponse, HTTP status code, HTTP response headers (array of strings)
     */
    public function searchWithHttpInfo($type, $order_by = null, $order_direction = null, $page_size = null, $offset = null, $_id = null, $__id = null, $deleted = null, $status = null, $state = null, $attributes = null, $invoice_number = null, $customer_id = null, $user_id = null, $outlet_id = null, $date_from = null, $date_to = null, $sku = null, $_sku = null, $supplier_id = null, $_supplier_id = null, $brand_id = null, $_brand_id = null, $tag_id = null, $_tag_id = null, $product_type_id = null, $_product_type_id = null, $variant_parent_id = null, $_variant_parent_id = null, $customer_code = null, $email = null, $first_name = null, $last_name = null, $company_name = null, $mobile = null, $phone = null, string $contentType = self::contentTypes['search'][0])
    {
        $request = $this->searchRequest($type, $order_by, $order_direction, $page_size, $offset, $_id, $__id, $deleted, $status, $state, $attributes, $invoice_number, $customer_id, $user_id, $outlet_id, $date_from, $date_to, $sku, $_sku, $supplier_id, $_supplier_id, $brand_id, $_brand_id, $tag_id, $_tag_id, $product_type_id, $_product_type_id, $variant_parent_id, $_variant_parent_id, $customer_code, $email, $first_name, $last_name, $company_name, $mobile, $phone, $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\SearchResponse',
                        $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\SearchResponse',
                $request,
                $response,
            );
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Vend202601\Model\SearchResponse',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    throw $e;
            }
        

            throw $e;
        }
    }

    /**
     * Operation searchAsync
     *
     * Search for resources
     *
     * @param  string $type The entity type to search for. (required)
     * @param  string|null $order_by The attribute used to sort items returned in the response. (optional)
     * @param  string|null $order_direction Sorting direction. (optional)
     * @param  int|null $page_size The maximum number of objects to be included in the response, currently limited to 1000. Specifying more than 1000 will result in 1000 objects being returned. (optional)
     * @param  int|null $offset The number of objects to be \&quot;skipped\&quot; for the response. Used for pagination. (optional)
     * @param  string|null $_id The &#x60;id&#x60; of the object to be included in the response. (optional)
     * @param  string|null $__id The &#x60;id&#x60; of the object to be excluded from the response. (optional)
     * @param  bool|null $deleted Indicated whether deleted objects should be included in the response. (optional)
     * @param  string|null $status **SALES** Status of the sale to find. Can be used multiple times to search for objects with different values of this parameter. Deprecated, please use state and attributes instead. (optional) (deprecated)
     * @param  string|null $state **SALES** State of the sale to find. Can be used multiple times to search for objects with different values of this parameter. (optional)
     * @param  string[]|null $attributes **SALES** Attributes of the sale to find. Can be used multiple times to search for objects with different values of this parameter. (optional)
     * @param  string|null $invoice_number **SALES** Invoice number of the sale. (optional)
     * @param  string|null $customer_id **SALES** The &#x60;ID&#x60; of the customer associated with the sales. (optional)
     * @param  string|null $user_id **SALES** The &#x60;ID&#x60; of the user associated with the sales. (optional)
     * @param  string|null $outlet_id **SALES** The &#x60;ID&#x60; of the outlet associated with the sales. (optional)
     * @param  string|null $date_from **SALES** Lower limit for the sale date as UTC timestamp. Format: &#x60;2016-08-08T12:00:00Z&#x60;. (optional)
     * @param  string|null $date_to **SALES** Upper limit for the sale date as UTC timestamp. Format: &#x60;2016-08-08T12:00:00Z&#x60;. (optional)
     * @param  string|null $sku **PRODUCTS** The SKU of products to include in the search. Can be used multiple times to search for objects with different values of this parameter. (optional)
     * @param  string|null $_sku **PRODUCTS** The SKU of products to exclude from the search. Can be used multiple times to search for objects with different values of this parameter. (optional)
     * @param  string|null $supplier_id **PRODUCTS** The ID of the supplier associated with the product to include in the search. Can be used multiple times to search for objects with different values of this parameter. (optional)
     * @param  string|null $_supplier_id **PRODUCTS** The ID of the supplier associated with the product to exclude from the search. Can be used multiple times to search for objects with different values of this parameter. (optional)
     * @param  string|null $brand_id **PRODUCTS** The ID of the brand associated with the product to include in the search. Can be used multiple times to search for objects with different values of this parameter. (optional)
     * @param  string|null $_brand_id **PRODUCTS** The ID of the brand associated with the product to exclude from the search. Can be used multiple times to search for objects with different values of this parameter. (optional)
     * @param  string|null $tag_id **PRODUCTS** The ID of the tag associated with the product to include in the search. Can be used multiple times to search for objects with different values of this parameter. (optional)
     * @param  string|null $_tag_id **PRODUCTS** The ID of the brand associated with the product to exclude from the search. Can be used multiple times to search for objects with different values of this parameter. (optional)
     * @param  string|null $product_type_id **PRODUCTS** The ID of the product type associated with the product to include in the search. Can be used multiple times to search for objects with different values of this parameter. (optional)
     * @param  string|null $_product_type_id **PRODUCTS** The ID of the product type associated with the product to exclude from the search. Can be used multiple times to search for objects with different values of this parameter. (optional)
     * @param  string|null $variant_parent_id **PRODUCTS** The ID of the variant parent product associated with the product to include in the search. Can be used multiple times to search for objects with different values of this parameter. (optional)
     * @param  string|null $_variant_parent_id **PRODUCTS** The ID of the variant parent product associated with the product to exclude from the search. Can be used multiple times to search for objects with different values of this parameter. (optional)
     * @param  string|null $customer_code **CUSTOMERS** The &#x60;customer_code&#x60; associated with the customer to find. (optional)
     * @param  string|null $email **CUSTOMERS** The &#x60;email&#x60; address associated with the customer to find. (optional)
     * @param  string|null $first_name **CUSTOMERS** The &#x60;first_name&#x60; for the customers to find. (optional)
     * @param  string|null $last_name **CUSTOMERS** The &#x60;last_name&#x60; for the customers to find. (optional)
     * @param  string|null $company_name **CUSTOMERS** The &#x60;company_name&#x60; for the customers to find. (optional)
     * @param  string|null $mobile **CUSTOMERS** The &#x60;mobile number&#x60; for the customers to find. (optional)
     * @param  string|null $phone **CUSTOMERS** The &#x60;phone number&#x60; for the customers to find. (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['search'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function searchAsync($type, $order_by = null, $order_direction = null, $page_size = null, $offset = null, $_id = null, $__id = null, $deleted = null, $status = null, $state = null, $attributes = null, $invoice_number = null, $customer_id = null, $user_id = null, $outlet_id = null, $date_from = null, $date_to = null, $sku = null, $_sku = null, $supplier_id = null, $_supplier_id = null, $brand_id = null, $_brand_id = null, $tag_id = null, $_tag_id = null, $product_type_id = null, $_product_type_id = null, $variant_parent_id = null, $_variant_parent_id = null, $customer_code = null, $email = null, $first_name = null, $last_name = null, $company_name = null, $mobile = null, $phone = null, string $contentType = self::contentTypes['search'][0])
    {
        return $this->searchAsyncWithHttpInfo($type, $order_by, $order_direction, $page_size, $offset, $_id, $__id, $deleted, $status, $state, $attributes, $invoice_number, $customer_id, $user_id, $outlet_id, $date_from, $date_to, $sku, $_sku, $supplier_id, $_supplier_id, $brand_id, $_brand_id, $tag_id, $_tag_id, $product_type_id, $_product_type_id, $variant_parent_id, $_variant_parent_id, $customer_code, $email, $first_name, $last_name, $company_name, $mobile, $phone, $contentType)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }

    /**
     * Operation searchAsyncWithHttpInfo
     *
     * Search for resources
     *
     * @param  string $type The entity type to search for. (required)
     * @param  string|null $order_by The attribute used to sort items returned in the response. (optional)
     * @param  string|null $order_direction Sorting direction. (optional)
     * @param  int|null $page_size The maximum number of objects to be included in the response, currently limited to 1000. Specifying more than 1000 will result in 1000 objects being returned. (optional)
     * @param  int|null $offset The number of objects to be \&quot;skipped\&quot; for the response. Used for pagination. (optional)
     * @param  string|null $_id The &#x60;id&#x60; of the object to be included in the response. (optional)
     * @param  string|null $__id The &#x60;id&#x60; of the object to be excluded from the response. (optional)
     * @param  bool|null $deleted Indicated whether deleted objects should be included in the response. (optional)
     * @param  string|null $status **SALES** Status of the sale to find. Can be used multiple times to search for objects with different values of this parameter. Deprecated, please use state and attributes instead. (optional) (deprecated)
     * @param  string|null $state **SALES** State of the sale to find. Can be used multiple times to search for objects with different values of this parameter. (optional)
     * @param  string[]|null $attributes **SALES** Attributes of the sale to find. Can be used multiple times to search for objects with different values of this parameter. (optional)
     * @param  string|null $invoice_number **SALES** Invoice number of the sale. (optional)
     * @param  string|null $customer_id **SALES** The &#x60;ID&#x60; of the customer associated with the sales. (optional)
     * @param  string|null $user_id **SALES** The &#x60;ID&#x60; of the user associated with the sales. (optional)
     * @param  string|null $outlet_id **SALES** The &#x60;ID&#x60; of the outlet associated with the sales. (optional)
     * @param  string|null $date_from **SALES** Lower limit for the sale date as UTC timestamp. Format: &#x60;2016-08-08T12:00:00Z&#x60;. (optional)
     * @param  string|null $date_to **SALES** Upper limit for the sale date as UTC timestamp. Format: &#x60;2016-08-08T12:00:00Z&#x60;. (optional)
     * @param  string|null $sku **PRODUCTS** The SKU of products to include in the search. Can be used multiple times to search for objects with different values of this parameter. (optional)
     * @param  string|null $_sku **PRODUCTS** The SKU of products to exclude from the search. Can be used multiple times to search for objects with different values of this parameter. (optional)
     * @param  string|null $supplier_id **PRODUCTS** The ID of the supplier associated with the product to include in the search. Can be used multiple times to search for objects with different values of this parameter. (optional)
     * @param  string|null $_supplier_id **PRODUCTS** The ID of the supplier associated with the product to exclude from the search. Can be used multiple times to search for objects with different values of this parameter. (optional)
     * @param  string|null $brand_id **PRODUCTS** The ID of the brand associated with the product to include in the search. Can be used multiple times to search for objects with different values of this parameter. (optional)
     * @param  string|null $_brand_id **PRODUCTS** The ID of the brand associated with the product to exclude from the search. Can be used multiple times to search for objects with different values of this parameter. (optional)
     * @param  string|null $tag_id **PRODUCTS** The ID of the tag associated with the product to include in the search. Can be used multiple times to search for objects with different values of this parameter. (optional)
     * @param  string|null $_tag_id **PRODUCTS** The ID of the brand associated with the product to exclude from the search. Can be used multiple times to search for objects with different values of this parameter. (optional)
     * @param  string|null $product_type_id **PRODUCTS** The ID of the product type associated with the product to include in the search. Can be used multiple times to search for objects with different values of this parameter. (optional)
     * @param  string|null $_product_type_id **PRODUCTS** The ID of the product type associated with the product to exclude from the search. Can be used multiple times to search for objects with different values of this parameter. (optional)
     * @param  string|null $variant_parent_id **PRODUCTS** The ID of the variant parent product associated with the product to include in the search. Can be used multiple times to search for objects with different values of this parameter. (optional)
     * @param  string|null $_variant_parent_id **PRODUCTS** The ID of the variant parent product associated with the product to exclude from the search. Can be used multiple times to search for objects with different values of this parameter. (optional)
     * @param  string|null $customer_code **CUSTOMERS** The &#x60;customer_code&#x60; associated with the customer to find. (optional)
     * @param  string|null $email **CUSTOMERS** The &#x60;email&#x60; address associated with the customer to find. (optional)
     * @param  string|null $first_name **CUSTOMERS** The &#x60;first_name&#x60; for the customers to find. (optional)
     * @param  string|null $last_name **CUSTOMERS** The &#x60;last_name&#x60; for the customers to find. (optional)
     * @param  string|null $company_name **CUSTOMERS** The &#x60;company_name&#x60; for the customers to find. (optional)
     * @param  string|null $mobile **CUSTOMERS** The &#x60;mobile number&#x60; for the customers to find. (optional)
     * @param  string|null $phone **CUSTOMERS** The &#x60;phone number&#x60; for the customers to find. (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['search'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function searchAsyncWithHttpInfo($type, $order_by = null, $order_direction = null, $page_size = null, $offset = null, $_id = null, $__id = null, $deleted = null, $status = null, $state = null, $attributes = null, $invoice_number = null, $customer_id = null, $user_id = null, $outlet_id = null, $date_from = null, $date_to = null, $sku = null, $_sku = null, $supplier_id = null, $_supplier_id = null, $brand_id = null, $_brand_id = null, $tag_id = null, $_tag_id = null, $product_type_id = null, $_product_type_id = null, $variant_parent_id = null, $_variant_parent_id = null, $customer_code = null, $email = null, $first_name = null, $last_name = null, $company_name = null, $mobile = null, $phone = null, string $contentType = self::contentTypes['search'][0])
    {
        $returnType = '\Vend202601\Model\SearchResponse';
        $request = $this->searchRequest($type, $order_by, $order_direction, $page_size, $offset, $_id, $__id, $deleted, $status, $state, $attributes, $invoice_number, $customer_id, $user_id, $outlet_id, $date_from, $date_to, $sku, $_sku, $supplier_id, $_supplier_id, $brand_id, $_brand_id, $tag_id, $_tag_id, $product_type_id, $_product_type_id, $variant_parent_id, $_variant_parent_id, $customer_code, $email, $first_name, $last_name, $company_name, $mobile, $phone, $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 'search'
     *
     * @param  string $type The entity type to search for. (required)
     * @param  string|null $order_by The attribute used to sort items returned in the response. (optional)
     * @param  string|null $order_direction Sorting direction. (optional)
     * @param  int|null $page_size The maximum number of objects to be included in the response, currently limited to 1000. Specifying more than 1000 will result in 1000 objects being returned. (optional)
     * @param  int|null $offset The number of objects to be \&quot;skipped\&quot; for the response. Used for pagination. (optional)
     * @param  string|null $_id The &#x60;id&#x60; of the object to be included in the response. (optional)
     * @param  string|null $__id The &#x60;id&#x60; of the object to be excluded from the response. (optional)
     * @param  bool|null $deleted Indicated whether deleted objects should be included in the response. (optional)
     * @param  string|null $status **SALES** Status of the sale to find. Can be used multiple times to search for objects with different values of this parameter. Deprecated, please use state and attributes instead. (optional) (deprecated)
     * @param  string|null $state **SALES** State of the sale to find. Can be used multiple times to search for objects with different values of this parameter. (optional)
     * @param  string[]|null $attributes **SALES** Attributes of the sale to find. Can be used multiple times to search for objects with different values of this parameter. (optional)
     * @param  string|null $invoice_number **SALES** Invoice number of the sale. (optional)
     * @param  string|null $customer_id **SALES** The &#x60;ID&#x60; of the customer associated with the sales. (optional)
     * @param  string|null $user_id **SALES** The &#x60;ID&#x60; of the user associated with the sales. (optional)
     * @param  string|null $outlet_id **SALES** The &#x60;ID&#x60; of the outlet associated with the sales. (optional)
     * @param  string|null $date_from **SALES** Lower limit for the sale date as UTC timestamp. Format: &#x60;2016-08-08T12:00:00Z&#x60;. (optional)
     * @param  string|null $date_to **SALES** Upper limit for the sale date as UTC timestamp. Format: &#x60;2016-08-08T12:00:00Z&#x60;. (optional)
     * @param  string|null $sku **PRODUCTS** The SKU of products to include in the search. Can be used multiple times to search for objects with different values of this parameter. (optional)
     * @param  string|null $_sku **PRODUCTS** The SKU of products to exclude from the search. Can be used multiple times to search for objects with different values of this parameter. (optional)
     * @param  string|null $supplier_id **PRODUCTS** The ID of the supplier associated with the product to include in the search. Can be used multiple times to search for objects with different values of this parameter. (optional)
     * @param  string|null $_supplier_id **PRODUCTS** The ID of the supplier associated with the product to exclude from the search. Can be used multiple times to search for objects with different values of this parameter. (optional)
     * @param  string|null $brand_id **PRODUCTS** The ID of the brand associated with the product to include in the search. Can be used multiple times to search for objects with different values of this parameter. (optional)
     * @param  string|null $_brand_id **PRODUCTS** The ID of the brand associated with the product to exclude from the search. Can be used multiple times to search for objects with different values of this parameter. (optional)
     * @param  string|null $tag_id **PRODUCTS** The ID of the tag associated with the product to include in the search. Can be used multiple times to search for objects with different values of this parameter. (optional)
     * @param  string|null $_tag_id **PRODUCTS** The ID of the brand associated with the product to exclude from the search. Can be used multiple times to search for objects with different values of this parameter. (optional)
     * @param  string|null $product_type_id **PRODUCTS** The ID of the product type associated with the product to include in the search. Can be used multiple times to search for objects with different values of this parameter. (optional)
     * @param  string|null $_product_type_id **PRODUCTS** The ID of the product type associated with the product to exclude from the search. Can be used multiple times to search for objects with different values of this parameter. (optional)
     * @param  string|null $variant_parent_id **PRODUCTS** The ID of the variant parent product associated with the product to include in the search. Can be used multiple times to search for objects with different values of this parameter. (optional)
     * @param  string|null $_variant_parent_id **PRODUCTS** The ID of the variant parent product associated with the product to exclude from the search. Can be used multiple times to search for objects with different values of this parameter. (optional)
     * @param  string|null $customer_code **CUSTOMERS** The &#x60;customer_code&#x60; associated with the customer to find. (optional)
     * @param  string|null $email **CUSTOMERS** The &#x60;email&#x60; address associated with the customer to find. (optional)
     * @param  string|null $first_name **CUSTOMERS** The &#x60;first_name&#x60; for the customers to find. (optional)
     * @param  string|null $last_name **CUSTOMERS** The &#x60;last_name&#x60; for the customers to find. (optional)
     * @param  string|null $company_name **CUSTOMERS** The &#x60;company_name&#x60; for the customers to find. (optional)
     * @param  string|null $mobile **CUSTOMERS** The &#x60;mobile number&#x60; for the customers to find. (optional)
     * @param  string|null $phone **CUSTOMERS** The &#x60;phone number&#x60; for the customers to find. (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['search'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request
     */
    public function searchRequest($type, $order_by = null, $order_direction = null, $page_size = null, $offset = null, $_id = null, $__id = null, $deleted = null, $status = null, $state = null, $attributes = null, $invoice_number = null, $customer_id = null, $user_id = null, $outlet_id = null, $date_from = null, $date_to = null, $sku = null, $_sku = null, $supplier_id = null, $_supplier_id = null, $brand_id = null, $_brand_id = null, $tag_id = null, $_tag_id = null, $product_type_id = null, $_product_type_id = null, $variant_parent_id = null, $_variant_parent_id = null, $customer_code = null, $email = null, $first_name = null, $last_name = null, $company_name = null, $mobile = null, $phone = null, string $contentType = self::contentTypes['search'][0])
    {

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





































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

        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $type,
            'type', // param base name
            'string', // openApiType
            'form', // style
            true, // explode
            true // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $order_by,
            'order_by', // param base name
            'string', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $order_direction,
            'order_direction', // param base name
            'string', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $page_size,
            'page_size', // param base name
            'integer', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $offset,
            'offset', // param base name
            'integer', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $_id,
            '_id', // param base name
            'string', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $__id,
            '-_id', // param base name
            'string', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $deleted,
            'deleted', // param base name
            'boolean', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $status,
            'status', // param base name
            'string', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $state,
            'state', // param base name
            'string', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $attributes,
            'attributes', // param base name
            'array', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $invoice_number,
            'invoice_number', // param base name
            'string', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $customer_id,
            'customer_id', // param base name
            'string', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $user_id,
            'user_id', // param base name
            'string', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $outlet_id,
            'outlet_id', // param base name
            'string', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $date_from,
            'date_from', // param base name
            'string', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $date_to,
            'date_to', // param base name
            'string', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $sku,
            'sku', // param base name
            'string', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $_sku,
            '-sku', // param base name
            'string', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $supplier_id,
            'supplier_id', // param base name
            'string', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $_supplier_id,
            '-supplier_id', // param base name
            'string', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $brand_id,
            'brand_id', // param base name
            'string', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $_brand_id,
            '-brand_id', // param base name
            'string', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $tag_id,
            'tag_id', // param base name
            'string', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $_tag_id,
            '-tag_id', // param base name
            'string', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $product_type_id,
            'product_type_id', // param base name
            'string', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $_product_type_id,
            '-product_type_id', // param base name
            'string', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $variant_parent_id,
            'variant_parent_id', // param base name
            'string', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $_variant_parent_id,
            '-variant_parent_id', // param base name
            'string', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $customer_code,
            'customer_code', // param base name
            'string', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $email,
            'email', // param base name
            'string', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $first_name,
            'first_name', // param base name
            'string', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $last_name,
            'last_name', // param base name
            'string', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $company_name,
            'company_name', // param base name
            'string', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $mobile,
            'mobile', // param base name
            'string', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $phone,
            'phone', // param base name
            'string', // 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;
    }
}
