<?php

// Code generated by OpenAPI Generator (https://openapi-generator.tech), manual changes will be lost - read more on https://github.com/algolia/api-clients-automation. DO NOT EDIT.

namespace Algolia\AlgoliaSearch\Api;

use Algolia\AlgoliaSearch\Algolia;
use Algolia\AlgoliaSearch\Configuration\AnalyticsConfig;
use Algolia\AlgoliaSearch\Model\Analytics\GetAddToCartRateResponse;
use Algolia\AlgoliaSearch\Model\Analytics\GetAverageClickPositionResponse;
use Algolia\AlgoliaSearch\Model\Analytics\GetClickPositionsResponse;
use Algolia\AlgoliaSearch\Model\Analytics\GetClickThroughRateResponse;
use Algolia\AlgoliaSearch\Model\Analytics\GetConversionRateResponse;
use Algolia\AlgoliaSearch\Model\Analytics\GetNoClickRateResponse;
use Algolia\AlgoliaSearch\Model\Analytics\GetNoResultsRateResponse;
use Algolia\AlgoliaSearch\Model\Analytics\GetPurchaseRateResponse;
use Algolia\AlgoliaSearch\Model\Analytics\GetRevenue;
use Algolia\AlgoliaSearch\Model\Analytics\GetSearchesCountResponse;
use Algolia\AlgoliaSearch\Model\Analytics\GetSearchesNoClicksResponse;
use Algolia\AlgoliaSearch\Model\Analytics\GetSearchesNoResultsResponse;
use Algolia\AlgoliaSearch\Model\Analytics\GetStatusResponse;
use Algolia\AlgoliaSearch\Model\Analytics\GetTopCountriesResponse;
use Algolia\AlgoliaSearch\Model\Analytics\GetTopFilterAttributesResponse;
use Algolia\AlgoliaSearch\Model\Analytics\GetTopFilterForAttributeResponse;
use Algolia\AlgoliaSearch\Model\Analytics\GetTopFiltersNoResultsResponse;
use Algolia\AlgoliaSearch\Model\Analytics\GetTopHitsResponse;
use Algolia\AlgoliaSearch\Model\Analytics\GetTopSearchesResponse;
use Algolia\AlgoliaSearch\Model\Analytics\GetUsersCountResponse;
use Algolia\AlgoliaSearch\ObjectSerializer;
use Algolia\AlgoliaSearch\RetryStrategy\ApiWrapper;
use Algolia\AlgoliaSearch\RetryStrategy\ApiWrapperInterface;
use Algolia\AlgoliaSearch\RetryStrategy\ClusterHosts;
use GuzzleHttp\Psr7\Query;

/**
 * AnalyticsClient Class Doc Comment.
 *
 * @category Class
 */
class AnalyticsClient
{
    public const VERSION = '4.21.0';

    /**
     * @var ApiWrapperInterface
     */
    protected $api;

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

    public function __construct(ApiWrapperInterface $apiWrapper, AnalyticsConfig $config)
    {
        $this->config = $config;
        $this->api = $apiWrapper;
    }

    /**
     * Instantiate the client with basic credentials and region.
     *
     * @param string $appId  Application ID
     * @param string $apiKey Algolia API Key
     * @param string $region Region
     */
    public static function create($appId = null, $apiKey = null, $region = null)
    {
        $config = AnalyticsConfig::create($appId, $apiKey, $region);

        return static::createWithConfig($config);
    }

    /**
     * Instantiate the client with configuration.
     *
     * @param AnalyticsConfig $config Configuration
     */
    public static function createWithConfig(AnalyticsConfig $config)
    {
        $config = clone $config;

        $apiWrapper = new ApiWrapper(
            Algolia::getHttpClient(),
            $config,
            self::getClusterHosts($config)
        );

        return new static($apiWrapper, $config);
    }

    /**
     * Gets the cluster hosts depending on the config.
     *
     * @return ClusterHosts
     */
    public static function getClusterHosts(AnalyticsConfig $config)
    {
        if ($hosts = $config->getHosts()) {
            // If a list of hosts was passed, we ignore the cache
            $clusterHosts = ClusterHosts::create($hosts);
        } else {
            $url = null !== $config->getRegion() && '' !== $config->getRegion() ?
                str_replace('{region}', $config->getRegion(), 'analytics.{region}.algolia.com') :
                'analytics.algolia.com';
            $clusterHosts = ClusterHosts::create($url);
        }

        return $clusterHosts;
    }

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

    /**
     * Stub method setting a new API key to authenticate requests.
     *
     * @param string $apiKey
     */
    public function setClientApiKey($apiKey)
    {
        $this->config->setClientApiKey($apiKey);
    }

    /**
     * This method lets you send requests to the Algolia REST API.
     *
     * @param string $path           Path of the endpoint, anything after \"/1\" must be specified. (required)
     * @param array  $parameters     Query parameters to apply to the current query. (optional)
     * @param array  $requestOptions the requestOptions to send along with the query, they will be merged with the transporter requestOptions
     *
     * @return array<string, mixed>|object
     */
    public function customDelete($path, $parameters = null, $requestOptions = [])
    {
        // verify the required parameter 'path' is set
        if (!isset($path)) {
            throw new \InvalidArgumentException(
                'Parameter `path` is required when calling `customDelete`.'
            );
        }

        $resourcePath = '/{path}';
        $queryParameters = [];
        $headers = [];
        $httpBody = null;

        if (null !== $parameters) {
            $queryParameters = $parameters;
        }

        // path params
        if (null !== $path) {
            $resourcePath = str_replace(
                '{path}',
                $path,
                $resourcePath
            );
        }

        return $this->sendRequest('DELETE', $resourcePath, $headers, $queryParameters, $httpBody, $requestOptions);
    }

    /**
     * This method lets you send requests to the Algolia REST API.
     *
     * @param string $path           Path of the endpoint, anything after \"/1\" must be specified. (required)
     * @param array  $parameters     Query parameters to apply to the current query. (optional)
     * @param array  $requestOptions the requestOptions to send along with the query, they will be merged with the transporter requestOptions
     *
     * @return array<string, mixed>|object
     */
    public function customGet($path, $parameters = null, $requestOptions = [])
    {
        // verify the required parameter 'path' is set
        if (!isset($path)) {
            throw new \InvalidArgumentException(
                'Parameter `path` is required when calling `customGet`.'
            );
        }

        $resourcePath = '/{path}';
        $queryParameters = [];
        $headers = [];
        $httpBody = null;

        if (null !== $parameters) {
            $queryParameters = $parameters;
        }

        // path params
        if (null !== $path) {
            $resourcePath = str_replace(
                '{path}',
                $path,
                $resourcePath
            );
        }

        return $this->sendRequest('GET', $resourcePath, $headers, $queryParameters, $httpBody, $requestOptions);
    }

    /**
     * This method lets you send requests to the Algolia REST API.
     *
     * @param string $path           Path of the endpoint, anything after \"/1\" must be specified. (required)
     * @param array  $parameters     Query parameters to apply to the current query. (optional)
     * @param array  $body           Parameters to send with the custom request. (optional)
     * @param array  $requestOptions the requestOptions to send along with the query, they will be merged with the transporter requestOptions
     *
     * @return array<string, mixed>|object
     */
    public function customPost($path, $parameters = null, $body = null, $requestOptions = [])
    {
        // verify the required parameter 'path' is set
        if (!isset($path)) {
            throw new \InvalidArgumentException(
                'Parameter `path` is required when calling `customPost`.'
            );
        }

        $resourcePath = '/{path}';
        $queryParameters = [];
        $headers = [];
        $httpBody = isset($body) ? $body : [];

        if (null !== $parameters) {
            $queryParameters = $parameters;
        }

        // path params
        if (null !== $path) {
            $resourcePath = str_replace(
                '{path}',
                $path,
                $resourcePath
            );
        }

        return $this->sendRequest('POST', $resourcePath, $headers, $queryParameters, $httpBody, $requestOptions);
    }

    /**
     * This method lets you send requests to the Algolia REST API.
     *
     * @param string $path           Path of the endpoint, anything after \"/1\" must be specified. (required)
     * @param array  $parameters     Query parameters to apply to the current query. (optional)
     * @param array  $body           Parameters to send with the custom request. (optional)
     * @param array  $requestOptions the requestOptions to send along with the query, they will be merged with the transporter requestOptions
     *
     * @return array<string, mixed>|object
     */
    public function customPut($path, $parameters = null, $body = null, $requestOptions = [])
    {
        // verify the required parameter 'path' is set
        if (!isset($path)) {
            throw new \InvalidArgumentException(
                'Parameter `path` is required when calling `customPut`.'
            );
        }

        $resourcePath = '/{path}';
        $queryParameters = [];
        $headers = [];
        $httpBody = isset($body) ? $body : [];

        if (null !== $parameters) {
            $queryParameters = $parameters;
        }

        // path params
        if (null !== $path) {
            $resourcePath = str_replace(
                '{path}',
                $path,
                $resourcePath
            );
        }

        return $this->sendRequest('PUT', $resourcePath, $headers, $queryParameters, $httpBody, $requestOptions);
    }

    /**
     * Retrieves the add-to-cart rate for all your searches with at least one add-to-cart event, including a daily breakdown.  By default, the analyzed period includes the last eight days including the current day.  The rate is the number of add-to-cart conversion events divided by the number of tracked searches. A search is tracked if it returns a queryID (`clickAnalytics` is `true`). This differs from the response's `count`, which shows the overall number of searches, including those where `clickAnalytics` is `false`.  **There's a difference between a 0 and null add-to-cart rate when `clickAnalytics` is enabled:**  - **Null** means there were no queries: since Algolia didn't receive any events, the add-to-cart rate is null. - **0** mean there _were_ queries but no [add-to-cart events](https://www.algolia.com/doc/guides/sending-events/getting-started/) were received.
     *
     * Required API Key ACLs:
     *  - analytics
     *
     * @param string $index          Index name. (required)
     * @param string $startDate      Start date of the period to analyze, in `YYYY-MM-DD` format. (optional)
     * @param string $endDate        End date of the period to analyze, in `YYYY-MM-DD` format. (optional)
     * @param string $tags           Tags by which to segment the analytics.  You can combine multiple tags with `OR` and `AND`. Tags must be URL-encoded. For more information, see [Segment your analytics data](https://www.algolia.com/doc/guides/search-analytics/guides/segments/). (optional)
     * @param array  $requestOptions the requestOptions to send along with the query, they will be merged with the transporter requestOptions
     *
     * @return array<string, mixed>|GetAddToCartRateResponse
     */
    public function getAddToCartRate($index, $startDate = null, $endDate = null, $tags = null, $requestOptions = [])
    {
        // verify the required parameter 'index' is set
        if (!isset($index)) {
            throw new \InvalidArgumentException(
                'Parameter `index` is required when calling `getAddToCartRate`.'
            );
        }

        $resourcePath = '/2/conversions/addToCartRate';
        $queryParameters = [];
        $headers = [];
        $httpBody = null;

        if (null !== $index) {
            $queryParameters['index'] = $index;
        }

        if (null !== $startDate) {
            $queryParameters['startDate'] = $startDate;
        }

        if (null !== $endDate) {
            $queryParameters['endDate'] = $endDate;
        }

        if (null !== $tags) {
            $queryParameters['tags'] = $tags;
        }

        return $this->sendRequest('GET', $resourcePath, $headers, $queryParameters, $httpBody, $requestOptions);
    }

    /**
     * Retrieves the average click position of your search results, including a daily breakdown.  The average click position is the average of all clicked search result positions. For example, if users only ever click on the first result for any search, the average click position is 1. By default, the analyzed period includes the last eight days including the current day.  An average of `null` when `clickAnalytics` is enabled means Algolia didn't receive any [click events](https://www.algolia.com/doc/guides/sending-events/getting-started/) for the queries. The average is `null` until Algolia receives at least one click event.
     *
     * Required API Key ACLs:
     *  - analytics
     *
     * @param string $index          Index name. (required)
     * @param string $startDate      Start date of the period to analyze, in `YYYY-MM-DD` format. (optional)
     * @param string $endDate        End date of the period to analyze, in `YYYY-MM-DD` format. (optional)
     * @param string $tags           Tags by which to segment the analytics.  You can combine multiple tags with `OR` and `AND`. Tags must be URL-encoded. For more information, see [Segment your analytics data](https://www.algolia.com/doc/guides/search-analytics/guides/segments/). (optional)
     * @param array  $requestOptions the requestOptions to send along with the query, they will be merged with the transporter requestOptions
     *
     * @return array<string, mixed>|GetAverageClickPositionResponse
     */
    public function getAverageClickPosition($index, $startDate = null, $endDate = null, $tags = null, $requestOptions = [])
    {
        // verify the required parameter 'index' is set
        if (!isset($index)) {
            throw new \InvalidArgumentException(
                'Parameter `index` is required when calling `getAverageClickPosition`.'
            );
        }

        $resourcePath = '/2/clicks/averageClickPosition';
        $queryParameters = [];
        $headers = [];
        $httpBody = null;

        if (null !== $index) {
            $queryParameters['index'] = $index;
        }

        if (null !== $startDate) {
            $queryParameters['startDate'] = $startDate;
        }

        if (null !== $endDate) {
            $queryParameters['endDate'] = $endDate;
        }

        if (null !== $tags) {
            $queryParameters['tags'] = $tags;
        }

        return $this->sendRequest('GET', $resourcePath, $headers, $queryParameters, $httpBody, $requestOptions);
    }

    /**
     * Retrieves the positions in the search results and their associated number of clicks.  This lets you check how many clicks the first, second, or tenth search results receive.  An average of `0` when `clickAnalytics` is enabled means Algolia didn't receive any [click events](https://www.algolia.com/doc/guides/sending-events/getting-started/) for the queries.
     *
     * Required API Key ACLs:
     *  - analytics
     *
     * @param string $index          Index name. (required)
     * @param string $startDate      Start date of the period to analyze, in `YYYY-MM-DD` format. (optional)
     * @param string $endDate        End date of the period to analyze, in `YYYY-MM-DD` format. (optional)
     * @param string $tags           Tags by which to segment the analytics.  You can combine multiple tags with `OR` and `AND`. Tags must be URL-encoded. For more information, see [Segment your analytics data](https://www.algolia.com/doc/guides/search-analytics/guides/segments/). (optional)
     * @param array  $requestOptions the requestOptions to send along with the query, they will be merged with the transporter requestOptions
     *
     * @return array<string, mixed>|GetClickPositionsResponse
     */
    public function getClickPositions($index, $startDate = null, $endDate = null, $tags = null, $requestOptions = [])
    {
        // verify the required parameter 'index' is set
        if (!isset($index)) {
            throw new \InvalidArgumentException(
                'Parameter `index` is required when calling `getClickPositions`.'
            );
        }

        $resourcePath = '/2/clicks/positions';
        $queryParameters = [];
        $headers = [];
        $httpBody = null;

        if (null !== $index) {
            $queryParameters['index'] = $index;
        }

        if (null !== $startDate) {
            $queryParameters['startDate'] = $startDate;
        }

        if (null !== $endDate) {
            $queryParameters['endDate'] = $endDate;
        }

        if (null !== $tags) {
            $queryParameters['tags'] = $tags;
        }

        return $this->sendRequest('GET', $resourcePath, $headers, $queryParameters, $httpBody, $requestOptions);
    }

    /**
     * Retrieves the click-through rate (CTR) for all your searches with at least one click event, including a daily breakdown.  By default, the analyzed period includes the last eight days including the current day.  **There's a difference between a 0 and null CTR when `clickAnalytics` is enabled:**  - **Null** means there were no queries: since Algolia didn't receive any events, CTR is null. - **0** mean there _were_ queries but no [click events](https://www.algolia.com/doc/guides/sending-events/getting-started/) were received.
     *
     * Required API Key ACLs:
     *  - analytics
     *
     * @param string $index          Index name. (required)
     * @param string $startDate      Start date of the period to analyze, in `YYYY-MM-DD` format. (optional)
     * @param string $endDate        End date of the period to analyze, in `YYYY-MM-DD` format. (optional)
     * @param string $tags           Tags by which to segment the analytics.  You can combine multiple tags with `OR` and `AND`. Tags must be URL-encoded. For more information, see [Segment your analytics data](https://www.algolia.com/doc/guides/search-analytics/guides/segments/). (optional)
     * @param array  $requestOptions the requestOptions to send along with the query, they will be merged with the transporter requestOptions
     *
     * @return array<string, mixed>|GetClickThroughRateResponse
     */
    public function getClickThroughRate($index, $startDate = null, $endDate = null, $tags = null, $requestOptions = [])
    {
        // verify the required parameter 'index' is set
        if (!isset($index)) {
            throw new \InvalidArgumentException(
                'Parameter `index` is required when calling `getClickThroughRate`.'
            );
        }

        $resourcePath = '/2/clicks/clickThroughRate';
        $queryParameters = [];
        $headers = [];
        $httpBody = null;

        if (null !== $index) {
            $queryParameters['index'] = $index;
        }

        if (null !== $startDate) {
            $queryParameters['startDate'] = $startDate;
        }

        if (null !== $endDate) {
            $queryParameters['endDate'] = $endDate;
        }

        if (null !== $tags) {
            $queryParameters['tags'] = $tags;
        }

        return $this->sendRequest('GET', $resourcePath, $headers, $queryParameters, $httpBody, $requestOptions);
    }

    /**
     * Retrieves the conversion rate (CR) for all your searches with at least one conversion event, including a daily breakdown.  By default, the analyzed period includes the last eight days including the current day.  **There's a difference between a 0 and null CR when `clickAnalytics` is enabled:**  - **Null** means there were no queries: since Algolia didn't receive any events, CR is null. - **0** mean there _were_ queries but no [conversion events](https://www.algolia.com/doc/guides/sending-events/getting-started/) were received.
     *
     * Required API Key ACLs:
     *  - analytics
     *
     * @param string $index          Index name. (required)
     * @param string $startDate      Start date of the period to analyze, in `YYYY-MM-DD` format. (optional)
     * @param string $endDate        End date of the period to analyze, in `YYYY-MM-DD` format. (optional)
     * @param string $tags           Tags by which to segment the analytics.  You can combine multiple tags with `OR` and `AND`. Tags must be URL-encoded. For more information, see [Segment your analytics data](https://www.algolia.com/doc/guides/search-analytics/guides/segments/). (optional)
     * @param array  $requestOptions the requestOptions to send along with the query, they will be merged with the transporter requestOptions
     *
     * @return array<string, mixed>|GetConversionRateResponse
     */
    public function getConversionRate($index, $startDate = null, $endDate = null, $tags = null, $requestOptions = [])
    {
        // verify the required parameter 'index' is set
        if (!isset($index)) {
            throw new \InvalidArgumentException(
                'Parameter `index` is required when calling `getConversionRate`.'
            );
        }

        $resourcePath = '/2/conversions/conversionRate';
        $queryParameters = [];
        $headers = [];
        $httpBody = null;

        if (null !== $index) {
            $queryParameters['index'] = $index;
        }

        if (null !== $startDate) {
            $queryParameters['startDate'] = $startDate;
        }

        if (null !== $endDate) {
            $queryParameters['endDate'] = $endDate;
        }

        if (null !== $tags) {
            $queryParameters['tags'] = $tags;
        }

        return $this->sendRequest('GET', $resourcePath, $headers, $queryParameters, $httpBody, $requestOptions);
    }

    /**
     * Retrieves the fraction of searches that didn't lead to any click within a time range, including a daily breakdown. It also returns the number of tracked searches and tracked searches without clicks.  By default, the analyzed period includes the last eight days including the current day.
     *
     * Required API Key ACLs:
     *  - analytics
     *
     * @param string $index          Index name. (required)
     * @param string $startDate      Start date of the period to analyze, in `YYYY-MM-DD` format. (optional)
     * @param string $endDate        End date of the period to analyze, in `YYYY-MM-DD` format. (optional)
     * @param string $tags           Tags by which to segment the analytics.  You can combine multiple tags with `OR` and `AND`. Tags must be URL-encoded. For more information, see [Segment your analytics data](https://www.algolia.com/doc/guides/search-analytics/guides/segments/). (optional)
     * @param array  $requestOptions the requestOptions to send along with the query, they will be merged with the transporter requestOptions
     *
     * @return array<string, mixed>|GetNoClickRateResponse
     */
    public function getNoClickRate($index, $startDate = null, $endDate = null, $tags = null, $requestOptions = [])
    {
        // verify the required parameter 'index' is set
        if (!isset($index)) {
            throw new \InvalidArgumentException(
                'Parameter `index` is required when calling `getNoClickRate`.'
            );
        }

        $resourcePath = '/2/searches/noClickRate';
        $queryParameters = [];
        $headers = [];
        $httpBody = null;

        if (null !== $index) {
            $queryParameters['index'] = $index;
        }

        if (null !== $startDate) {
            $queryParameters['startDate'] = $startDate;
        }

        if (null !== $endDate) {
            $queryParameters['endDate'] = $endDate;
        }

        if (null !== $tags) {
            $queryParameters['tags'] = $tags;
        }

        return $this->sendRequest('GET', $resourcePath, $headers, $queryParameters, $httpBody, $requestOptions);
    }

    /**
     * Retrieves the fraction of searches that didn't return any results within a time range, including a daily breakdown. It also returns the count of searches and searches without results used to compute the rates.  By default, the analyzed period includes the last eight days including the current day.
     *
     * Required API Key ACLs:
     *  - analytics
     *
     * @param string $index          Index name. (required)
     * @param string $startDate      Start date of the period to analyze, in `YYYY-MM-DD` format. (optional)
     * @param string $endDate        End date of the period to analyze, in `YYYY-MM-DD` format. (optional)
     * @param string $tags           Tags by which to segment the analytics.  You can combine multiple tags with `OR` and `AND`. Tags must be URL-encoded. For more information, see [Segment your analytics data](https://www.algolia.com/doc/guides/search-analytics/guides/segments/). (optional)
     * @param array  $requestOptions the requestOptions to send along with the query, they will be merged with the transporter requestOptions
     *
     * @return array<string, mixed>|GetNoResultsRateResponse
     */
    public function getNoResultsRate($index, $startDate = null, $endDate = null, $tags = null, $requestOptions = [])
    {
        // verify the required parameter 'index' is set
        if (!isset($index)) {
            throw new \InvalidArgumentException(
                'Parameter `index` is required when calling `getNoResultsRate`.'
            );
        }

        $resourcePath = '/2/searches/noResultRate';
        $queryParameters = [];
        $headers = [];
        $httpBody = null;

        if (null !== $index) {
            $queryParameters['index'] = $index;
        }

        if (null !== $startDate) {
            $queryParameters['startDate'] = $startDate;
        }

        if (null !== $endDate) {
            $queryParameters['endDate'] = $endDate;
        }

        if (null !== $tags) {
            $queryParameters['tags'] = $tags;
        }

        return $this->sendRequest('GET', $resourcePath, $headers, $queryParameters, $httpBody, $requestOptions);
    }

    /**
     * Retrieves the purchase rate for all your searches with at least one purchase event, including a daily breakdown.  By default, the analyzed period includes the last eight days including the current day.  The rate is the number of purchase conversion events divided by the number of tracked searches. A search is tracked if it returns a query ID (`clickAnalytics` is `true`). This differs from the response's `count`, which shows the overall number of searches, including those where `clickAnalytics` is `false`.  **There's a difference between a 0 and null purchase rate when `clickAnalytics` is enabled:**  - **Null** means there were no queries: since Algolia didn't receive any events, the purchase rate is null. - **0** mean there _were_ queries but no [purchase conversion events](https://www.algolia.com/doc/guides/sending-events/getting-started/) were received.
     *
     * Required API Key ACLs:
     *  - analytics
     *
     * @param string $index          Index name. (required)
     * @param string $startDate      Start date of the period to analyze, in `YYYY-MM-DD` format. (optional)
     * @param string $endDate        End date of the period to analyze, in `YYYY-MM-DD` format. (optional)
     * @param string $tags           Tags by which to segment the analytics.  You can combine multiple tags with `OR` and `AND`. Tags must be URL-encoded. For more information, see [Segment your analytics data](https://www.algolia.com/doc/guides/search-analytics/guides/segments/). (optional)
     * @param array  $requestOptions the requestOptions to send along with the query, they will be merged with the transporter requestOptions
     *
     * @return array<string, mixed>|GetPurchaseRateResponse
     */
    public function getPurchaseRate($index, $startDate = null, $endDate = null, $tags = null, $requestOptions = [])
    {
        // verify the required parameter 'index' is set
        if (!isset($index)) {
            throw new \InvalidArgumentException(
                'Parameter `index` is required when calling `getPurchaseRate`.'
            );
        }

        $resourcePath = '/2/conversions/purchaseRate';
        $queryParameters = [];
        $headers = [];
        $httpBody = null;

        if (null !== $index) {
            $queryParameters['index'] = $index;
        }

        if (null !== $startDate) {
            $queryParameters['startDate'] = $startDate;
        }

        if (null !== $endDate) {
            $queryParameters['endDate'] = $endDate;
        }

        if (null !== $tags) {
            $queryParameters['tags'] = $tags;
        }

        return $this->sendRequest('GET', $resourcePath, $headers, $queryParameters, $httpBody, $requestOptions);
    }

    /**
     * Retrieves revenue-related metrics, such as the total revenue or the average order value.  To retrieve revenue-related metrics, send purchase events. By default, the analyzed period includes the last eight days including the current day.  Revenue is based on purchase conversion events (a conversion event with an `eventSubtype` attribute of `purchase`). The revenue is the `price` attribute multiplied by the `quantity` attribute for each object in the event's `objectData` array.
     *
     * Required API Key ACLs:
     *  - analytics
     *
     * @param string $index          Index name. (required)
     * @param string $startDate      Start date of the period to analyze, in `YYYY-MM-DD` format. (optional)
     * @param string $endDate        End date of the period to analyze, in `YYYY-MM-DD` format. (optional)
     * @param string $tags           Tags by which to segment the analytics.  You can combine multiple tags with `OR` and `AND`. Tags must be URL-encoded. For more information, see [Segment your analytics data](https://www.algolia.com/doc/guides/search-analytics/guides/segments/). (optional)
     * @param array  $requestOptions the requestOptions to send along with the query, they will be merged with the transporter requestOptions
     *
     * @return array<string, mixed>|GetRevenue
     */
    public function getRevenue($index, $startDate = null, $endDate = null, $tags = null, $requestOptions = [])
    {
        // verify the required parameter 'index' is set
        if (!isset($index)) {
            throw new \InvalidArgumentException(
                'Parameter `index` is required when calling `getRevenue`.'
            );
        }

        $resourcePath = '/2/conversions/revenue';
        $queryParameters = [];
        $headers = [];
        $httpBody = null;

        if (null !== $index) {
            $queryParameters['index'] = $index;
        }

        if (null !== $startDate) {
            $queryParameters['startDate'] = $startDate;
        }

        if (null !== $endDate) {
            $queryParameters['endDate'] = $endDate;
        }

        if (null !== $tags) {
            $queryParameters['tags'] = $tags;
        }

        return $this->sendRequest('GET', $resourcePath, $headers, $queryParameters, $httpBody, $requestOptions);
    }

    /**
     * Retrieves the number of searches within a time range, including a daily breakdown.  By default, the analyzed period includes the last eight days including the current day.
     *
     * Required API Key ACLs:
     *  - analytics
     *
     * @param string $index          Index name. (required)
     * @param string $startDate      Start date of the period to analyze, in `YYYY-MM-DD` format. (optional)
     * @param string $endDate        End date of the period to analyze, in `YYYY-MM-DD` format. (optional)
     * @param string $tags           Tags by which to segment the analytics.  You can combine multiple tags with `OR` and `AND`. Tags must be URL-encoded. For more information, see [Segment your analytics data](https://www.algolia.com/doc/guides/search-analytics/guides/segments/). (optional)
     * @param array  $requestOptions the requestOptions to send along with the query, they will be merged with the transporter requestOptions
     *
     * @return array<string, mixed>|GetSearchesCountResponse
     */
    public function getSearchesCount($index, $startDate = null, $endDate = null, $tags = null, $requestOptions = [])
    {
        // verify the required parameter 'index' is set
        if (!isset($index)) {
            throw new \InvalidArgumentException(
                'Parameter `index` is required when calling `getSearchesCount`.'
            );
        }

        $resourcePath = '/2/searches/count';
        $queryParameters = [];
        $headers = [];
        $httpBody = null;

        if (null !== $index) {
            $queryParameters['index'] = $index;
        }

        if (null !== $startDate) {
            $queryParameters['startDate'] = $startDate;
        }

        if (null !== $endDate) {
            $queryParameters['endDate'] = $endDate;
        }

        if (null !== $tags) {
            $queryParameters['tags'] = $tags;
        }

        return $this->sendRequest('GET', $resourcePath, $headers, $queryParameters, $httpBody, $requestOptions);
    }

    /**
     * Retrieves the most popular searches that didn't lead to any clicks, from the 1,000 most frequent searches.  For each search, it also returns the number of displayed search results that remained unclicked.
     *
     * Required API Key ACLs:
     *  - analytics
     *
     * @param string $index          Index name. (required)
     * @param string $startDate      Start date of the period to analyze, in `YYYY-MM-DD` format. (optional)
     * @param string $endDate        End date of the period to analyze, in `YYYY-MM-DD` format. (optional)
     * @param int    $limit          Number of items to return. (optional, default to 10)
     * @param int    $offset         Position of the first item to return. (optional, default to 0)
     * @param string $tags           Tags by which to segment the analytics.  You can combine multiple tags with `OR` and `AND`. Tags must be URL-encoded. For more information, see [Segment your analytics data](https://www.algolia.com/doc/guides/search-analytics/guides/segments/). (optional)
     * @param array  $requestOptions the requestOptions to send along with the query, they will be merged with the transporter requestOptions
     *
     * @return array<string, mixed>|GetSearchesNoClicksResponse
     */
    public function getSearchesNoClicks($index, $startDate = null, $endDate = null, $limit = null, $offset = null, $tags = null, $requestOptions = [])
    {
        // verify the required parameter 'index' is set
        if (!isset($index)) {
            throw new \InvalidArgumentException(
                'Parameter `index` is required when calling `getSearchesNoClicks`.'
            );
        }

        $resourcePath = '/2/searches/noClicks';
        $queryParameters = [];
        $headers = [];
        $httpBody = null;

        if (null !== $index) {
            $queryParameters['index'] = $index;
        }

        if (null !== $startDate) {
            $queryParameters['startDate'] = $startDate;
        }

        if (null !== $endDate) {
            $queryParameters['endDate'] = $endDate;
        }

        if (null !== $limit) {
            $queryParameters['limit'] = $limit;
        }

        if (null !== $offset) {
            $queryParameters['offset'] = $offset;
        }

        if (null !== $tags) {
            $queryParameters['tags'] = $tags;
        }

        return $this->sendRequest('GET', $resourcePath, $headers, $queryParameters, $httpBody, $requestOptions);
    }

    /**
     * Retrieves the 1,000 most frequent searches that produced zero results.
     *
     * Required API Key ACLs:
     *  - analytics
     *
     * @param string $index          Index name. (required)
     * @param string $startDate      Start date of the period to analyze, in `YYYY-MM-DD` format. (optional)
     * @param string $endDate        End date of the period to analyze, in `YYYY-MM-DD` format. (optional)
     * @param int    $limit          Number of items to return. (optional, default to 10)
     * @param int    $offset         Position of the first item to return. (optional, default to 0)
     * @param string $tags           Tags by which to segment the analytics.  You can combine multiple tags with `OR` and `AND`. Tags must be URL-encoded. For more information, see [Segment your analytics data](https://www.algolia.com/doc/guides/search-analytics/guides/segments/). (optional)
     * @param array  $requestOptions the requestOptions to send along with the query, they will be merged with the transporter requestOptions
     *
     * @return array<string, mixed>|GetSearchesNoResultsResponse
     */
    public function getSearchesNoResults($index, $startDate = null, $endDate = null, $limit = null, $offset = null, $tags = null, $requestOptions = [])
    {
        // verify the required parameter 'index' is set
        if (!isset($index)) {
            throw new \InvalidArgumentException(
                'Parameter `index` is required when calling `getSearchesNoResults`.'
            );
        }

        $resourcePath = '/2/searches/noResults';
        $queryParameters = [];
        $headers = [];
        $httpBody = null;

        if (null !== $index) {
            $queryParameters['index'] = $index;
        }

        if (null !== $startDate) {
            $queryParameters['startDate'] = $startDate;
        }

        if (null !== $endDate) {
            $queryParameters['endDate'] = $endDate;
        }

        if (null !== $limit) {
            $queryParameters['limit'] = $limit;
        }

        if (null !== $offset) {
            $queryParameters['offset'] = $offset;
        }

        if (null !== $tags) {
            $queryParameters['tags'] = $tags;
        }

        return $this->sendRequest('GET', $resourcePath, $headers, $queryParameters, $httpBody, $requestOptions);
    }

    /**
     * Retrieves the time when the Analytics data for the specified index was last updated.  If the index has been recently created or no search has been performed yet the updated time is `null`.  The Analytics data is updated every 5&nbsp;minutes.
     *
     * Required API Key ACLs:
     *  - analytics
     *
     * @param string $index          Index name. (required)
     * @param array  $requestOptions the requestOptions to send along with the query, they will be merged with the transporter requestOptions
     *
     * @return array<string, mixed>|GetStatusResponse
     */
    public function getStatus($index, $requestOptions = [])
    {
        // verify the required parameter 'index' is set
        if (!isset($index)) {
            throw new \InvalidArgumentException(
                'Parameter `index` is required when calling `getStatus`.'
            );
        }

        $resourcePath = '/2/status';
        $queryParameters = [];
        $headers = [];
        $httpBody = null;

        if (null !== $index) {
            $queryParameters['index'] = $index;
        }

        return $this->sendRequest('GET', $resourcePath, $headers, $queryParameters, $httpBody, $requestOptions);
    }

    /**
     * Retrieves the countries with the most searches in your index.
     *
     * Required API Key ACLs:
     *  - analytics
     *
     * @param string $index          Index name. (required)
     * @param string $startDate      Start date of the period to analyze, in `YYYY-MM-DD` format. (optional)
     * @param string $endDate        End date of the period to analyze, in `YYYY-MM-DD` format. (optional)
     * @param int    $limit          Number of items to return. (optional, default to 10)
     * @param int    $offset         Position of the first item to return. (optional, default to 0)
     * @param string $tags           Tags by which to segment the analytics.  You can combine multiple tags with `OR` and `AND`. Tags must be URL-encoded. For more information, see [Segment your analytics data](https://www.algolia.com/doc/guides/search-analytics/guides/segments/). (optional)
     * @param array  $requestOptions the requestOptions to send along with the query, they will be merged with the transporter requestOptions
     *
     * @return array<string, mixed>|GetTopCountriesResponse
     */
    public function getTopCountries($index, $startDate = null, $endDate = null, $limit = null, $offset = null, $tags = null, $requestOptions = [])
    {
        // verify the required parameter 'index' is set
        if (!isset($index)) {
            throw new \InvalidArgumentException(
                'Parameter `index` is required when calling `getTopCountries`.'
            );
        }

        $resourcePath = '/2/countries';
        $queryParameters = [];
        $headers = [];
        $httpBody = null;

        if (null !== $index) {
            $queryParameters['index'] = $index;
        }

        if (null !== $startDate) {
            $queryParameters['startDate'] = $startDate;
        }

        if (null !== $endDate) {
            $queryParameters['endDate'] = $endDate;
        }

        if (null !== $limit) {
            $queryParameters['limit'] = $limit;
        }

        if (null !== $offset) {
            $queryParameters['offset'] = $offset;
        }

        if (null !== $tags) {
            $queryParameters['tags'] = $tags;
        }

        return $this->sendRequest('GET', $resourcePath, $headers, $queryParameters, $httpBody, $requestOptions);
    }

    /**
     * Retrieves the 1,000 most frequently used filter attributes.  These are attributes of your records that you included in the `attributesForFaceting` setting.
     *
     * Required API Key ACLs:
     *  - analytics
     *
     * @param string $index          Index name. (required)
     * @param string $search         Search query. (optional)
     * @param string $startDate      Start date of the period to analyze, in `YYYY-MM-DD` format. (optional)
     * @param string $endDate        End date of the period to analyze, in `YYYY-MM-DD` format. (optional)
     * @param int    $limit          Number of items to return. (optional, default to 10)
     * @param int    $offset         Position of the first item to return. (optional, default to 0)
     * @param string $tags           Tags by which to segment the analytics.  You can combine multiple tags with `OR` and `AND`. Tags must be URL-encoded. For more information, see [Segment your analytics data](https://www.algolia.com/doc/guides/search-analytics/guides/segments/). (optional)
     * @param array  $requestOptions the requestOptions to send along with the query, they will be merged with the transporter requestOptions
     *
     * @return array<string, mixed>|GetTopFilterAttributesResponse
     */
    public function getTopFilterAttributes($index, $search = null, $startDate = null, $endDate = null, $limit = null, $offset = null, $tags = null, $requestOptions = [])
    {
        // verify the required parameter 'index' is set
        if (!isset($index)) {
            throw new \InvalidArgumentException(
                'Parameter `index` is required when calling `getTopFilterAttributes`.'
            );
        }

        $resourcePath = '/2/filters';
        $queryParameters = [];
        $headers = [];
        $httpBody = null;

        if (null !== $index) {
            $queryParameters['index'] = $index;
        }

        if (null !== $search) {
            $queryParameters['search'] = $search;
        }

        if (null !== $startDate) {
            $queryParameters['startDate'] = $startDate;
        }

        if (null !== $endDate) {
            $queryParameters['endDate'] = $endDate;
        }

        if (null !== $limit) {
            $queryParameters['limit'] = $limit;
        }

        if (null !== $offset) {
            $queryParameters['offset'] = $offset;
        }

        if (null !== $tags) {
            $queryParameters['tags'] = $tags;
        }

        return $this->sendRequest('GET', $resourcePath, $headers, $queryParameters, $httpBody, $requestOptions);
    }

    /**
     * Retrieves the 1,000 most frequent filter (facet) values for a filter attribute.  These are attributes of your records that you included in the `attributesForFaceting` setting.
     *
     * Required API Key ACLs:
     *  - analytics
     *
     * @param string $attribute      Attribute name. (required)
     * @param string $index          Index name. (required)
     * @param string $search         Search query. (optional)
     * @param string $startDate      Start date of the period to analyze, in `YYYY-MM-DD` format. (optional)
     * @param string $endDate        End date of the period to analyze, in `YYYY-MM-DD` format. (optional)
     * @param int    $limit          Number of items to return. (optional, default to 10)
     * @param int    $offset         Position of the first item to return. (optional, default to 0)
     * @param string $tags           Tags by which to segment the analytics.  You can combine multiple tags with `OR` and `AND`. Tags must be URL-encoded. For more information, see [Segment your analytics data](https://www.algolia.com/doc/guides/search-analytics/guides/segments/). (optional)
     * @param array  $requestOptions the requestOptions to send along with the query, they will be merged with the transporter requestOptions
     *
     * @return array<string, mixed>|GetTopFilterForAttributeResponse
     */
    public function getTopFilterForAttribute($attribute, $index, $search = null, $startDate = null, $endDate = null, $limit = null, $offset = null, $tags = null, $requestOptions = [])
    {
        // verify the required parameter 'attribute' is set
        if (!isset($attribute)) {
            throw new \InvalidArgumentException(
                'Parameter `attribute` is required when calling `getTopFilterForAttribute`.'
            );
        }
        // verify the required parameter 'index' is set
        if (!isset($index)) {
            throw new \InvalidArgumentException(
                'Parameter `index` is required when calling `getTopFilterForAttribute`.'
            );
        }

        $resourcePath = '/2/filters/{attribute}';
        $queryParameters = [];
        $headers = [];
        $httpBody = null;

        if (null !== $index) {
            $queryParameters['index'] = $index;
        }

        if (null !== $search) {
            $queryParameters['search'] = $search;
        }

        if (null !== $startDate) {
            $queryParameters['startDate'] = $startDate;
        }

        if (null !== $endDate) {
            $queryParameters['endDate'] = $endDate;
        }

        if (null !== $limit) {
            $queryParameters['limit'] = $limit;
        }

        if (null !== $offset) {
            $queryParameters['offset'] = $offset;
        }

        if (null !== $tags) {
            $queryParameters['tags'] = $tags;
        }

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

        return $this->sendRequest('GET', $resourcePath, $headers, $queryParameters, $httpBody, $requestOptions);
    }

    /**
     * Retrieves the 1,000 most frequently used filters for a search that didn't return any results.  To get the most frequent searches without results, use the [Retrieve searches without results](#tag/search/operation/getSearchesNoResults) operation.
     *
     * Required API Key ACLs:
     *  - analytics
     *
     * @param string $index          Index name. (required)
     * @param string $search         Search query. (optional)
     * @param string $startDate      Start date of the period to analyze, in `YYYY-MM-DD` format. (optional)
     * @param string $endDate        End date of the period to analyze, in `YYYY-MM-DD` format. (optional)
     * @param int    $limit          Number of items to return. (optional, default to 10)
     * @param int    $offset         Position of the first item to return. (optional, default to 0)
     * @param string $tags           Tags by which to segment the analytics.  You can combine multiple tags with `OR` and `AND`. Tags must be URL-encoded. For more information, see [Segment your analytics data](https://www.algolia.com/doc/guides/search-analytics/guides/segments/). (optional)
     * @param array  $requestOptions the requestOptions to send along with the query, they will be merged with the transporter requestOptions
     *
     * @return array<string, mixed>|GetTopFiltersNoResultsResponse
     */
    public function getTopFiltersNoResults($index, $search = null, $startDate = null, $endDate = null, $limit = null, $offset = null, $tags = null, $requestOptions = [])
    {
        // verify the required parameter 'index' is set
        if (!isset($index)) {
            throw new \InvalidArgumentException(
                'Parameter `index` is required when calling `getTopFiltersNoResults`.'
            );
        }

        $resourcePath = '/2/filters/noResults';
        $queryParameters = [];
        $headers = [];
        $httpBody = null;

        if (null !== $index) {
            $queryParameters['index'] = $index;
        }

        if (null !== $search) {
            $queryParameters['search'] = $search;
        }

        if (null !== $startDate) {
            $queryParameters['startDate'] = $startDate;
        }

        if (null !== $endDate) {
            $queryParameters['endDate'] = $endDate;
        }

        if (null !== $limit) {
            $queryParameters['limit'] = $limit;
        }

        if (null !== $offset) {
            $queryParameters['offset'] = $offset;
        }

        if (null !== $tags) {
            $queryParameters['tags'] = $tags;
        }

        return $this->sendRequest('GET', $resourcePath, $headers, $queryParameters, $httpBody, $requestOptions);
    }

    /**
     * Retrieves the object IDs of the 1,000 most frequent search results.  If you set the `clickAnalytics` query parameter to true, the response also includes:  - Tracked searches count. Tracked searches are Search API requests with the `clickAnalytics` parameter set to `true`. This differs from the response's `count`, which shows the overall number of searches, including those where `clickAnalytics` is `false`. - Click count - Click-through rate (CTR) - Conversion count - Conversion rate (CR) - Average click position  If you set the `revenueAnalytics` parameter to `true`, the response also includes:  - Add-to-cart count - Add-to-cart rate (ATCR) - Purchase count - Purchase rate - Revenue details for each currency  **There's a difference between 0% rates and null rates:**  - **Null** means there were no queries: since Algolia didn't receive any events, the rates (CTR, CR, ATCR, purchase rate) are null. - **0% rates** mean there _were_ queries but no [click or conversion events](https://www.algolia.com/doc/guides/sending-events/getting-started/) were received.
     *
     * Required API Key ACLs:
     *  - analytics
     *
     * @param string $index            Index name. (required)
     * @param string $search           Search query. (optional)
     * @param bool   $clickAnalytics   Whether to include metrics related to click and conversion events in the response. (optional, default to false)
     * @param bool   $revenueAnalytics Whether to include metrics related to revenue events in the response. (optional, default to false)
     * @param string $startDate        Start date of the period to analyze, in `YYYY-MM-DD` format. (optional)
     * @param string $endDate          End date of the period to analyze, in `YYYY-MM-DD` format. (optional)
     * @param int    $limit            Number of items to return. (optional, default to 10)
     * @param int    $offset           Position of the first item to return. (optional, default to 0)
     * @param string $tags             Tags by which to segment the analytics.  You can combine multiple tags with `OR` and `AND`. Tags must be URL-encoded. For more information, see [Segment your analytics data](https://www.algolia.com/doc/guides/search-analytics/guides/segments/). (optional)
     * @param array  $requestOptions   the requestOptions to send along with the query, they will be merged with the transporter requestOptions
     *
     * @return array<string, mixed>|GetTopHitsResponse
     */
    public function getTopHits($index, $search = null, $clickAnalytics = null, $revenueAnalytics = null, $startDate = null, $endDate = null, $limit = null, $offset = null, $tags = null, $requestOptions = [])
    {
        // verify the required parameter 'index' is set
        if (!isset($index)) {
            throw new \InvalidArgumentException(
                'Parameter `index` is required when calling `getTopHits`.'
            );
        }

        $resourcePath = '/2/hits';
        $queryParameters = [];
        $headers = [];
        $httpBody = null;

        if (null !== $index) {
            $queryParameters['index'] = $index;
        }

        if (null !== $search) {
            $queryParameters['search'] = $search;
        }

        if (null !== $clickAnalytics) {
            $queryParameters['clickAnalytics'] = $clickAnalytics;
        }

        if (null !== $revenueAnalytics) {
            $queryParameters['revenueAnalytics'] = $revenueAnalytics;
        }

        if (null !== $startDate) {
            $queryParameters['startDate'] = $startDate;
        }

        if (null !== $endDate) {
            $queryParameters['endDate'] = $endDate;
        }

        if (null !== $limit) {
            $queryParameters['limit'] = $limit;
        }

        if (null !== $offset) {
            $queryParameters['offset'] = $offset;
        }

        if (null !== $tags) {
            $queryParameters['tags'] = $tags;
        }

        return $this->sendRequest('GET', $resourcePath, $headers, $queryParameters, $httpBody, $requestOptions);
    }

    /**
     * Returns the most popular searches. For each search, it also includes the average number of hits.  If you set the `clickAnalytics` query parameter to `true`, the response also includes  - Tracked searches count. Tracked searches are Search API requests with the `clickAnalytics` parameter set to `true`. This differs from the response's `count`, which shows the overall number of searches, including those where `clickAnalytics` is `false`. - Click count - Click-through rate (CTR) - Conversion count - Conversion rate (CR) - Average click position  If you set the `revenueAnalytics` query parameter to `true`, the response also includes:  - Add-to-cart count - Add-to-cart rate (ATCR) - Purchase count - Purchase rate - Revenue details for each currency  **There's a difference between 0% rates and null rates:**  - **Null** means there were no queries: since Algolia didn't receive any events, the rates (CTR, CR, ATCR, purchase rate) are null. - **0% rates** mean there _were_ queries but no [click or conversion events](https://www.algolia.com/doc/guides/sending-events/getting-started/) were received.
     *
     * Required API Key ACLs:
     *  - analytics
     *
     * @param string $index            Index name. (required)
     * @param bool   $clickAnalytics   Whether to include metrics related to click and conversion events in the response. (optional, default to false)
     * @param bool   $revenueAnalytics Whether to include metrics related to revenue events in the response. (optional, default to false)
     * @param string $startDate        Start date of the period to analyze, in `YYYY-MM-DD` format. (optional)
     * @param string $endDate          End date of the period to analyze, in `YYYY-MM-DD` format. (optional)
     * @param array  $orderBy          Attribute by which to order the response items.  If the `clickAnalytics` parameter is false, only `searchCount` is available. (optional)
     * @param array  $direction        Sorting direction of the results: ascending or descending. (optional)
     * @param int    $limit            Number of items to return. (optional, default to 10)
     * @param int    $offset           Position of the first item to return. (optional, default to 0)
     * @param string $tags             Tags by which to segment the analytics.  You can combine multiple tags with `OR` and `AND`. Tags must be URL-encoded. For more information, see [Segment your analytics data](https://www.algolia.com/doc/guides/search-analytics/guides/segments/). (optional)
     * @param array  $requestOptions   the requestOptions to send along with the query, they will be merged with the transporter requestOptions
     *
     * @return array<string, mixed>|GetTopSearchesResponse
     */
    public function getTopSearches($index, $clickAnalytics = null, $revenueAnalytics = null, $startDate = null, $endDate = null, $orderBy = null, $direction = null, $limit = null, $offset = null, $tags = null, $requestOptions = [])
    {
        // verify the required parameter 'index' is set
        if (!isset($index)) {
            throw new \InvalidArgumentException(
                'Parameter `index` is required when calling `getTopSearches`.'
            );
        }

        $resourcePath = '/2/searches';
        $queryParameters = [];
        $headers = [];
        $httpBody = null;

        if (null !== $index) {
            $queryParameters['index'] = $index;
        }

        if (null !== $clickAnalytics) {
            $queryParameters['clickAnalytics'] = $clickAnalytics;
        }

        if (null !== $revenueAnalytics) {
            $queryParameters['revenueAnalytics'] = $revenueAnalytics;
        }

        if (null !== $startDate) {
            $queryParameters['startDate'] = $startDate;
        }

        if (null !== $endDate) {
            $queryParameters['endDate'] = $endDate;
        }

        if (null !== $orderBy) {
            $queryParameters['orderBy'] = $orderBy;
        }

        if (null !== $direction) {
            $queryParameters['direction'] = $direction;
        }

        if (null !== $limit) {
            $queryParameters['limit'] = $limit;
        }

        if (null !== $offset) {
            $queryParameters['offset'] = $offset;
        }

        if (null !== $tags) {
            $queryParameters['tags'] = $tags;
        }

        return $this->sendRequest('GET', $resourcePath, $headers, $queryParameters, $httpBody, $requestOptions);
    }

    /**
     * Retrieves the number of unique users within a time range, including a daily breakdown.  Since it returns the number of unique users, the sum of the daily values might be different from the total number.  By default:  - Algolia distinguishes search users by their IP address, _unless_ you include a pseudonymous user identifier in your search requests with the `userToken` API parameter or `x-algolia-usertoken` request header. - The analyzed period includes the last eight days including the current day.
     *
     * Required API Key ACLs:
     *  - analytics
     *
     * @param string $index          Index name. (required)
     * @param string $startDate      Start date of the period to analyze, in `YYYY-MM-DD` format. (optional)
     * @param string $endDate        End date of the period to analyze, in `YYYY-MM-DD` format. (optional)
     * @param string $tags           Tags by which to segment the analytics.  You can combine multiple tags with `OR` and `AND`. Tags must be URL-encoded. For more information, see [Segment your analytics data](https://www.algolia.com/doc/guides/search-analytics/guides/segments/). (optional)
     * @param array  $requestOptions the requestOptions to send along with the query, they will be merged with the transporter requestOptions
     *
     * @return array<string, mixed>|GetUsersCountResponse
     */
    public function getUsersCount($index, $startDate = null, $endDate = null, $tags = null, $requestOptions = [])
    {
        // verify the required parameter 'index' is set
        if (!isset($index)) {
            throw new \InvalidArgumentException(
                'Parameter `index` is required when calling `getUsersCount`.'
            );
        }

        $resourcePath = '/2/users/count';
        $queryParameters = [];
        $headers = [];
        $httpBody = null;

        if (null !== $index) {
            $queryParameters['index'] = $index;
        }

        if (null !== $startDate) {
            $queryParameters['startDate'] = $startDate;
        }

        if (null !== $endDate) {
            $queryParameters['endDate'] = $endDate;
        }

        if (null !== $tags) {
            $queryParameters['tags'] = $tags;
        }

        return $this->sendRequest('GET', $resourcePath, $headers, $queryParameters, $httpBody, $requestOptions);
    }

    private function sendRequest($method, $resourcePath, $headers, $queryParameters, $httpBody, $requestOptions, $useReadTransporter = false)
    {
        if (!isset($requestOptions['headers'])) {
            $requestOptions['headers'] = [];
        }
        if (!isset($requestOptions['queryParameters'])) {
            $requestOptions['queryParameters'] = [];
        }

        $requestOptions['headers'] = array_merge($headers, $requestOptions['headers']);
        $requestOptions['queryParameters'] = array_merge($queryParameters, $requestOptions['queryParameters']);
        $query = Query::build($requestOptions['queryParameters']);

        return $this->api->sendRequest(
            $method,
            $resourcePath.($query ? "?{$query}" : ''),
            $httpBody,
            $requestOptions,
            $useReadTransporter
        );
    }
}
