import type SpatialReference from "../../geometry/SpatialReference.js";
import type TopFilter from "./TopFilter.js";
import type TimeExtent from "../../time/TimeExtent.js";
import type { JSONSupport } from "../../core/JSONSupport.js";
import type { GeometryUnion } from "../../geometry/types.js";
import type { ObjectId } from "../../views/types.js";
import type { MeshProperties } from "../../geometry/Mesh.js";
import type { PolylineProperties } from "../../geometry/Polyline.js";
import type { PolygonProperties } from "../../geometry/Polygon.js";
import type { PointProperties } from "../../geometry/Point.js";
import type { MultipointProperties } from "../../geometry/Multipoint.js";
import type { ExtentProperties } from "../../geometry/Extent.js";
import type { SpatialReferenceProperties } from "../../geometry/SpatialReference.js";
import type { TimeExtentProperties } from "../../time/TimeExtent.js";
import type { TopFilterProperties } from "./TopFilter.js";

export interface TopFeaturesQueryProperties extends Partial<Pick<TopFeaturesQuery, "cacheHint" | "distance" | "geometryPrecision" | "maxAllowableOffset" | "num" | "objectIds" | "orderByFields" | "outFields" | "returnGeometry" | "returnM" | "returnZ" | "spatialRelationship" | "start" | "units" | "where">> {
  /**
   * The geometry to apply to the spatial filter. The [Query.spatialRelationship](https://developers.arcgis.com/javascript/latest/api-reference/esri-rest-support-Query.html#spatialRelationship)
   * will indicate how the geometry should be used to query features.
   *
   * > [!WARNING]
   * >
   * > **Known Limitations**
   * >
   * > [Mesh](https://developers.arcgis.com/javascript/latest/api-reference/esri-geometry-Mesh.html) geometry types are currently not supported.
   */
  geometry?: ((ExtentProperties & { type: "extent" }) | (MultipointProperties & { type: "multipoint" }) | (PointProperties & { type: "point" }) | (PolygonProperties & { type: "polygon" }) | (PolylineProperties & { type: "polyline" }) | (MeshProperties & { type: "mesh" })) | null;
  /**
   * The spatial reference for the returned geometry. If not specified, the geometry is returned in the spatial
   * reference of the queried layer.
   */
  outSpatialReference?: SpatialReferenceProperties | null;
  /**
   * A time extent for a temporal query against [time-aware layers](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-FeatureLayer.html#timeInfo).
   * For example, it can be used to discover all crimes that occurred during the
   * night shift from 10 PM to 6 AM on a particular date.
   *
   * @example
   * let layer = new FeatureLayer( ... );
   * let timeExtent = new TimeExtent({
   *   start: new Date(1992, 0, 1),
   *   end: new Date(1992, 11, 31)
   * });
   * let timeQuery = new Query({
   *   timeExtent: timeExtent
   * });
   * layerView.queryFeatures(timeQuery).then(function(featureSet) { ... });
   */
  timeExtent?: TimeExtentProperties | null;
  /**
   * The `topFilter` parameter is used to set the [TopFilter.groupByFields](https://developers.arcgis.com/javascript/latest/api-reference/esri-rest-support-TopFilter.html#groupByFields), [TopFilter.orderByFields](https://developers.arcgis.com/javascript/latest/api-reference/esri-rest-support-TopFilter.html#orderByFields),
   * and [TopFilter.topCount](https://developers.arcgis.com/javascript/latest/api-reference/esri-rest-support-TopFilter.html#topCount) criteria used in generating the result.
   *
   * @example
   * // return top three most populous cities from each state
   * const query = new TopFeaturesQuery({
   *   topFilter: new TopFilter({
   *     topCount: 3,
   *     groupByFields: ["State"],
   *     orderByFields: ["Pop_total DESC"]
   *   })
   * });
   * layer.queryTopFeatures(query).then(function(featureSet) { ... });
   */
  topFilter?: TopFilterProperties;
}

/**
 * This class defines parameters for executing [top features queries](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-FeatureLayer.html#queryTopFeatures)
 * from a [FeatureLayer](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-FeatureLayer.html). Once a TopFeaturesQuery object's properties are defined, it can then be passed
 * into executable functions on a server-side [FeatureLayer](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-FeatureLayer.html), which can return a
 * [FeatureSet](https://developers.arcgis.com/javascript/latest/api-reference/esri-rest-support-FeatureSet.html) containing features within a group. For example, you can use FeatureLayer's
 * [FeatureLayer.queryTopFeatures()](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-FeatureLayer.html#queryTopFeatures) method to query
 * the most populous three counties in each state of the United States.
 *
 * This class has many of the same properties as [Query](https://developers.arcgis.com/javascript/latest/api-reference/esri-rest-support-Query.html) class. However, unlike the Query class,
 * this class does not support properties such as `outStatistics` and its related parameters or `returnDistinctValues`.
 *
 * ```js
 * // query the top three most populous counties from each state.
 * // Results will be ordered based the population of each county in descending order
 * // top query will run against all features available in the service
 * const query = new TopFeaturesQuery({
 *   outFields: ["State, Pop_total, County"],
 *   topFilter: new TopFilter({
 *     topCount: 3,
 *     groupByFields: ["State"],
 *     orderByFields: ["Pop_total DESC"]
 *   })
 * });
 * featureLayer.queryTopFeatures(query)
 *   .then(function(response){
 *      // returns a feature set with features containing the most populous
 *      // three counties in each state ordered by population.
 *      // The following attributes are returned as well: State, Pop_total, County
 *    });
 * ```
 *
 * There are three types of top features queries: attribute, spatial and temporal queries. You can query for features
 * in one of these categories or use elements of each in a single query. When running a top features query,
 * the [topFilter](https://developers.arcgis.com/javascript/latest/api-reference/esri-rest-support-TopFeaturesQuery.html#topFilter) parameter must always be set.
 *
 * <span id="attribute"></span>
 * ## Attribute queries
 *
 * To query top features based on attribute values, specify a SQL where clause in the [where](https://developers.arcgis.com/javascript/latest/api-reference/esri-rest-support-TopFeaturesQuery.html#where) property along with the [topFilter](https://developers.arcgis.com/javascript/latest/api-reference/esri-rest-support-TopFeaturesQuery.html#topFilter)
 * property. Setting the [outFields](https://developers.arcgis.com/javascript/latest/api-reference/esri-rest-support-TopFeaturesQuery.html#outFields) of the query will limit the attributes returned from the query. This can improve the speed of the query
 * if your app doesn't require all the attributes for each feature.
 *
 * For example, you can use [where](https://developers.arcgis.com/javascript/latest/api-reference/esri-rest-support-TopFeaturesQuery.html#where) and [topFilter](https://developers.arcgis.com/javascript/latest/api-reference/esri-rest-support-TopFeaturesQuery.html#topFilter) parameters to query the top three most populous cities in each country if the
 * population is over 1,000,000.
 *
 * ```js
 * const query = new TopFeaturesQuery({
 *   where: "Population >= 1000000",
 *   outFields: ["Country, Population, Name"],
 *   topFilter: new TopFilter({
 *     topCount: 3,
 *     groupByFields: ["Country"],
 *     orderByFields: [`Population DESC`]
 *   })
 * });
 * featureLayer.queryTopFeatures(query)
 *   .then(function(response){
 *      // returns a feature set with features containing the most populous three cities
 *      // in each country. The query will run only against cities where the population is
 *      // over one million.
 *    });
 * ```
 *
 * <span id="spatial"></span>
 * ## Spatial queries
 *
 * You can query top features by geometry/location. While [where](https://developers.arcgis.com/javascript/latest/api-reference/esri-rest-support-TopFeaturesQuery.html#where) is not required in this
 * workflow, you can use `where` as part of the query to get more refined results. The [topFilter](https://developers.arcgis.com/javascript/latest/api-reference/esri-rest-support-TopFeaturesQuery.html#topFilter) property
 * must be set in addition to [geometry](https://developers.arcgis.com/javascript/latest/api-reference/esri-rest-support-TopFeaturesQuery.html#geometry) property.
 * To execute a spatial query, you must set the [geometry](https://developers.arcgis.com/javascript/latest/api-reference/esri-rest-support-TopFeaturesQuery.html#geometry) parameter to a
 * [Geometry](https://developers.arcgis.com/javascript/latest/api-reference/esri-geometry-Geometry.html) object and specify a valid [spatialRelationship](https://developers.arcgis.com/javascript/latest/api-reference/esri-rest-support-TopFeaturesQuery.html#spatialRelationship).
 * You can optionally provide a query [distance](https://developers.arcgis.com/javascript/latest/api-reference/esri-rest-support-TopFeaturesQuery.html#distance) and [units](https://developers.arcgis.com/javascript/latest/api-reference/esri-rest-support-TopFeaturesQuery.html#units) to query features against a buffer
 * around the given geometry.
 *
 * For example, to query for the two tallest buildings in each zoning category within 10 miles of a mouse move, you would do the following:
 *
 * ```js
 * view.on("pointer-move", function(event){
 *   const query = new TopFeaturesQuery({
 *     outFields: ["Zoning, Floors, Year"],
 *     topFilter: new TopFilter({
 *       topCount: 2,
 *       groupByFields: ["Zoning"],
 *       orderByFields: ["Floors DESC"]
 *     }),
 *     geometry: view.toMap(event),
 *     spatialRelationship:  "intersects",
 *     units: "miles",
 *     distance: 10,
 *     returnGeometry: true
 *   });
 *   featureLayer.queryTopFeatures(query)
 *     .then(function(response){
 *        // returns two tallest buildings in zoning category within a given geometry
 *        // The following attributes are returned as well: Zoning, Floors, Year
 *      });
 * });
 * ```
 *
 * You could also use `where`, for example, to return the tallest buildings in a specific residential zoning districts within
 * the 10-mile buffer.
 *
 * <span id="temporal"></span>
 * ## Temporal queries
 *
 * You can query top features based on a given time range by specifying the [timeExtent](https://developers.arcgis.com/javascript/latest/api-reference/esri-rest-support-TopFeaturesQuery.html#timeExtent) property. The temporal query will return
 * results only if the feature service is published with [FeatureLayer.timeInfo](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-FeatureLayer.html#timeInfo) information. The temporal
 * query can also be combined with attribute and geometry queries.
 *
 * For example, you can use [timeExtent](https://developers.arcgis.com/javascript/latest/api-reference/esri-rest-support-TopFeaturesQuery.html#timeExtent) and [topFilter](https://developers.arcgis.com/javascript/latest/api-reference/esri-rest-support-TopFeaturesQuery.html#topFilter) parameters to query hurricane tracks with the highest wind speed,
 * grouped by the hurricane categories within a given time extent.
 *
 * ```js
 * // query hurricanes that took place in 1992 and
 * // return a hurricane track with the highest wind speed in each category
 * const query = new TopFeaturesQuery({
 *   outFields: ["STAGE, WINDSPEED, PRESSURE"],
 *   topFilter: new TopFilter({
 *     topCount: 1,
 *     groupByFields: ["STAGE"],
 *     orderByFields: ["WINDSPEED DESC"]
 *   }),
 *   timeExtent: {
 *     start: new Date(1992, 0, 1),
 *     end: new Date(1992, 11, 31)
 *   }
 * });
 * featureLayer.queryTopFeatures(query)
 *   .then(function(response){
 *      // returns a hurricane with the highest wind speed
 *      // in each stage... the query will only run against
 *     // hurricanes  that happened in 1992
 *    });
 * ```
 *
 * > [!WARNING]
 * >
 * > **Known Limitations**
 * >
 * > Currently, the `TopFeatureQuery` is only supported with server-side [FeatureLayer](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-FeatureLayer.html).
 *
 * @since 4.20
 * @see [TopFilter](https://developers.arcgis.com/javascript/latest/api-reference/esri-rest-support-TopFilter.html)
 * @see [FeatureLayer.queryTopFeatures()](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-FeatureLayer.html#queryTopFeatures)
 * @see [Query and filter guide](https://developers.arcgis.com/javascript/latest/query-filter/)
 * @see [Sample - Aggregate spatial statistics](https://developers.arcgis.com/javascript/latest/sample-code/featurelayer-query-aggregate/)
 */
export default class TopFeaturesQuery extends JSONSupport {
  constructor(properties?: TopFeaturesQueryProperties);
  /**
   * Indicates if the service should cache the query results. It only applies if the layer's
   * [capabilities.query.supportsCacheHint](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-FeatureLayer.html#capabilities) is set to `true`.
   * Use only for queries that have the same parameters every time the app is used.
   * Some examples of cacheable queries:
   * * Queries that fetch [statistics](https://developers.arcgis.com/javascript/latest/api-reference/esri-rest-support-Query.html#outStatistics) or [features](https://developers.arcgis.com/javascript/latest/api-reference/esri-rest-support-Query.html#returnGeometry) on app load.
   * * Queries based on [preset input](https://developers.arcgis.com/javascript/latest/api-reference/esri-rest-support-Query.html#where), for example, a drop-down list of US states.
   * * Queries based on [preset extents](https://developers.arcgis.com/javascript/latest/api-reference/esri-rest-support-Query.html#geometry), for example bookmarks, in web maps.
   */
  accessor cacheHint: boolean | null | undefined;
  /**
   * Specifies a search distance from a given [Query.geometry](https://developers.arcgis.com/javascript/latest/api-reference/esri-rest-support-Query.html#geometry) in a spatial query.
   * The [units property](https://developers.arcgis.com/javascript/latest/api-reference/esri-rest-support-Query.html#units) indicates the unit of measurement. In essence, setting this property
   * creates a buffer at the specified size around the input [Query.geometry](https://developers.arcgis.com/javascript/latest/api-reference/esri-rest-support-Query.html#geometry). The query will use that
   * buffer to return features in the layer or layer view that adhere to the to the indicated [spatial relationship](https://developers.arcgis.com/javascript/latest/api-reference/esri-rest-support-Query.html#spatialRelationship).
   *
   * If querying a feature service, the [supportsQueryWithDistance](https://developers.arcgis.com/rest/services-reference/query-feature-service-layer-.htm)
   * capability must be `true`.
   */
  accessor distance: number | null | undefined;
  /**
   * The geometry to apply to the spatial filter. The [Query.spatialRelationship](https://developers.arcgis.com/javascript/latest/api-reference/esri-rest-support-Query.html#spatialRelationship)
   * will indicate how the geometry should be used to query features.
   *
   * > [!WARNING]
   * >
   * > **Known Limitations**
   * >
   * > [Mesh](https://developers.arcgis.com/javascript/latest/api-reference/esri-geometry-Mesh.html) geometry types are currently not supported.
   */
  get geometry(): GeometryUnion | null | undefined;
  set geometry(value: ((ExtentProperties & { type: "extent" }) | (MultipointProperties & { type: "multipoint" }) | (PointProperties & { type: "point" }) | (PolygonProperties & { type: "polygon" }) | (PolylineProperties & { type: "polyline" }) | (MeshProperties & { type: "mesh" })) | null | undefined);
  /** Specifies the number of decimal places for geometries returned by the query operation. */
  accessor geometryPrecision: number;
  /**
   * The maximum distance in units of [outSpatialReference](https://developers.arcgis.com/javascript/latest/api-reference/esri-rest-support-TopFeaturesQuery.html#outSpatialReference) used for
   * generalizing geometries returned by the query operation. It limits how far any part of the
   * generalized geometry can be from the original geometry. If `outSpatialReference` is not defined,
   * the spatialReference of the data is used.
   */
  accessor maxAllowableOffset: number;
  /**
   * The number of features to retrieve. This option should be used in conjunction with the [start property](https://developers.arcgis.com/javascript/latest/api-reference/esri-rest-support-TopFeaturesQuery.html#start). Use this to
   * implement paging (i.e. to retrieve "pages" of results when querying).
   *
   * If not provided, but an instance of Query has a `start` property, then the default value of `num` is 10.
   * If neither `num` nor `start` properties are provided, then the default value of `num` is equal to the
   * `maxRecordCount` of the service, which can be found at the REST endpoint of the FeatureLayer.
   */
  accessor num: number | null | undefined;
  /** An array of ObjectIDs to be used to query for features in a layer. */
  accessor objectIds: ObjectId[] | null | undefined;
  /**
   * One or more field names used to order the query results. Specify `ASC` (ascending) or `DESC`
   * (descending) after the field name to control the order. The default order is `ASC`.
   *
   * @see [FeatureLayer.capabilities](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-FeatureLayer.html#capabilities)
   * @example query.orderByFields = ["STATE_NAME DESC"];
   */
  accessor orderByFields: string[] | null | undefined;
  /**
   * Attribute fields to include in the [FeatureSet](https://developers.arcgis.com/javascript/latest/api-reference/esri-rest-support-FeatureSet.html). Fields must exist in the service layer. You must list actual
   * field names rather than field aliases. You may, however, use field aliases when you display
   * the results of the query.
   *
   * When specifying the output fields, you should limit the fields to only those you expect to use in the
   * query or the results. The fewer fields you include, the smaller the payload size, and therefore the faster the response of the query.
   *
   * You can also specify SQL expressions as `outFields` to calculate new values server side for the query results. See the
   * example snippets below for an example of this.
   *
   * Each query must have access to the `Shape` and `ObjectId` fields for a layer. However, the list of outFields does
   * not need to include these two fields.
   *
   * > [!WARNING]
   * >
   * > **Known Limitations**
   * >
   * > If specifying outFields as expressions on a feature service-based [FeatureLayer](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-FeatureLayer.html), the service capabilities
   * > `advancedQueryCapabilities.supportsOutFieldSQLExpression` and `useStandardizedQueries` must both be true.
   *
   * @example
   * // query for field attributes
   * query.outFields = [ "NAME", "STATE_ABBR", "POP04" ];
   * @example
   * // query for data returned from an expressions and other fields as the following field names
   * // POP_CHANGE_2020, NAME, POP2020
   * // where POP_CHANGE_2020 represents the population change from 2010 - 2020
   * query.outFields = [ "( (POP2020 - POP2010) / POP2010 ) * 100 as POP_CHANGE_2020", "NAME", "POP2020" ]
   */
  accessor outFields: string[] | null | undefined;
  /**
   * The spatial reference for the returned geometry. If not specified, the geometry is returned in the spatial
   * reference of the queried layer.
   */
  get outSpatialReference(): SpatialReference | null;
  set outSpatialReference(value: SpatialReferenceProperties | null);
  /**
   * If `true`, each feature in the returned [FeatureSet](https://developers.arcgis.com/javascript/latest/api-reference/esri-rest-support-FeatureSet.html) includes the geometry.
   *
   * @default false
   */
  accessor returnGeometry: boolean;
  /** If `true`, and [returnGeometry](https://developers.arcgis.com/javascript/latest/api-reference/esri-rest-support-TopFeaturesQuery.html#returnGeometry) is `true`, then m-values are included in the geometry. */
  accessor returnM: boolean;
  /** If `true`, and [returnGeometry](https://developers.arcgis.com/javascript/latest/api-reference/esri-rest-support-TopFeaturesQuery.html#returnGeometry) is `true`, then z-values are included in the geometry. */
  accessor returnZ: boolean;
  /**
   * For spatial queries, this parameter defines the spatial relationship to query features in the layer or layer view against the input [Query.geometry](https://developers.arcgis.com/javascript/latest/api-reference/esri-rest-support-Query.html#geometry).
   * The spatial relationships discover how features are spatially related to each other.
   * For example, you may want to know if a polygon representing a county completely contains points representing settlements.
   *
   * The spatial relationship is determined by whether the boundaries or interiors of a geometry intersect.
   * * Boundary — The endpoints of all linear parts for line features, or the linear outline of a polygon. Only lines and polygons have boundaries.
   * * Interior — Points are entirely interior and have no boundary. For lines and polygons, the interior is any part of the geometry that is not part of the boundary.
   *
   * The possible values for this parameter are described below and the images highlight the geometries returned for the specified spatial
   * relationship for given geometries.
   *
   * The `intersects` spatial relationship returns features in the layer view that intersect the query [Query.geometry](https://developers.arcgis.com/javascript/latest/api-reference/esri-rest-support-Query.html#geometry).
   *
   * ![intersects](https://developers.arcgis.com/javascript/latest/assets/img/apiref/layers/spatialRelationships/intersects.png)
   *
   * The `contains` spatial relationship returns features in the layer view that are completely contained by the query [Query.geometry](https://developers.arcgis.com/javascript/latest/api-reference/esri-rest-support-Query.html#geometry).
   *
   * ![contains](https://developers.arcgis.com/javascript/latest/assets/img/apiref/layers/spatialRelationships/contains.png)
   *
   * The `crosses` spatial relationship returns features in the layer view when the interior of a query [Query.geometry](https://developers.arcgis.com/javascript/latest/api-reference/esri-rest-support-Query.html#geometry) comes into contact with
   * the interior or boundary of features in the layer view. In other words, the geometries share some interior area, but not all interior area.
   *
   * ![crosses](https://developers.arcgis.com/javascript/latest/assets/img/apiref/layers/spatialRelationships/crosses.png)
   *
   * The `envelope-intersects` spatial relationship returns features in the layer view that intersect the envelope (or extent)
   * of the filter [Query.geometry](https://developers.arcgis.com/javascript/latest/api-reference/esri-rest-support-Query.html#geometry).
   *
   * ![envelope-intersects](https://developers.arcgis.com/javascript/latest/assets/img/apiref/layers/spatialRelationships/envelope-intersects.png)
   *
   * The `overlaps` spatial relationship returns features in the layer view that overlap the query [Query.geometry](https://developers.arcgis.com/javascript/latest/api-reference/esri-rest-support-Query.html#geometry).
   * Only features of the same geometry can be compared.
   *
   * ![overlaps](https://developers.arcgis.com/javascript/latest/assets/img/apiref/layers/spatialRelationships/overlap.png)
   *
   * The `touches` spatial relationship returns features in the layer view that touch the query [Query.geometry](https://developers.arcgis.com/javascript/latest/api-reference/esri-rest-support-Query.html#geometry).
   * The boundaries of the geometries intersect, but not their interiors.
   *
   * ![touches](https://developers.arcgis.com/javascript/latest/assets/img/apiref/layers/spatialRelationships/touches.png)
   *
   * The `within` spatial relationship returns features in the layer view that completely contain the query [Query.geometry](https://developers.arcgis.com/javascript/latest/api-reference/esri-rest-support-Query.html#geometry).
   * In other words, the filter geometry is completely `within` the features in the layer view. It is opposite of
   * `contains`.
   *
   * ![within](https://developers.arcgis.com/javascript/latest/assets/img/apiref/layers/spatialRelationships/within.png)
   *
   * The `disjoint` spatial relationship returns features in the layer view that do not intersect the query [Query.geometry](https://developers.arcgis.com/javascript/latest/api-reference/esri-rest-support-Query.html#geometry) in anyway.
   * Opposite of `intersects`.
   *
   * ![disjoint](https://developers.arcgis.com/javascript/latest/assets/img/apiref/layers/spatialRelationships/disjoint.png)
   *
   * > [!WARNING]
   * >
   * > **Known Limitations**
   * >
   * > For spatial queries on 3D Object SceneLayers and BuildingSceneLayers the spatial relationship is evaluated based on the
   * > [Extent](https://developers.arcgis.com/javascript/latest/api-reference/esri-geometry-Extent.html) of the feature and not the footprint. This means that a feature might be
   * > returned from the query, even though its footprint is not in a spatial relationship with the [Query.geometry](https://developers.arcgis.com/javascript/latest/api-reference/esri-rest-support-Query.html#geometry).
   * > Currently only `intersects`, `contains`, and `disjoint` [spatialRelationships](https://developers.arcgis.com/javascript/latest/api-reference/esri-rest-support-Query.html#spatialRelationship) are supported on spatial
   * > [queries](https://developers.arcgis.com/javascript/latest/api-reference/esri-rest-support-Query.html) for 3D Object SceneLayers and BuildingSceneLayers.
   *
   * @default "intersects"
   * @default intersects
   * @example
   * let query = new Query({
   *   spatialRelationship: "contains"
   * });
   */
  accessor spatialRelationship: "intersects" | "contains" | "crosses" | "envelope-intersects" | "index-intersects" | "overlaps" | "touches" | "within";
  /**
   * The zero-based index indicating where to begin retrieving features. This property should be used in conjunction with [num](https://developers.arcgis.com/javascript/latest/api-reference/esri-rest-support-TopFeaturesQuery.html#num).
   * Use this to implement paging and retrieve "pages" of results when querying. Features are sorted ascending by
   * object ID by default.
   */
  accessor start: number | null | undefined;
  /**
   * A time extent for a temporal query against [time-aware layers](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-FeatureLayer.html#timeInfo).
   * For example, it can be used to discover all crimes that occurred during the
   * night shift from 10 PM to 6 AM on a particular date.
   *
   * @example
   * let layer = new FeatureLayer( ... );
   * let timeExtent = new TimeExtent({
   *   start: new Date(1992, 0, 1),
   *   end: new Date(1992, 11, 31)
   * });
   * let timeQuery = new Query({
   *   timeExtent: timeExtent
   * });
   * layerView.queryFeatures(timeQuery).then(function(featureSet) { ... });
   */
  get timeExtent(): TimeExtent | null | undefined;
  set timeExtent(value: TimeExtentProperties | null | undefined);
  /**
   * The `topFilter` parameter is used to set the [TopFilter.groupByFields](https://developers.arcgis.com/javascript/latest/api-reference/esri-rest-support-TopFilter.html#groupByFields), [TopFilter.orderByFields](https://developers.arcgis.com/javascript/latest/api-reference/esri-rest-support-TopFilter.html#orderByFields),
   * and [TopFilter.topCount](https://developers.arcgis.com/javascript/latest/api-reference/esri-rest-support-TopFilter.html#topCount) criteria used in generating the result.
   *
   * @example
   * // return top three most populous cities from each state
   * const query = new TopFeaturesQuery({
   *   topFilter: new TopFilter({
   *     topCount: 3,
   *     groupByFields: ["State"],
   *     orderByFields: ["Pop_total DESC"]
   *   })
   * });
   * layer.queryTopFeatures(query).then(function(featureSet) { ... });
   */
  get topFilter(): TopFilter;
  set topFilter(value: TopFilterProperties);
  /**
   * The unit for calculating the buffer distance when [Query.distance](https://developers.arcgis.com/javascript/latest/api-reference/esri-rest-support-Query.html#distance) is specified in spatial queries.
   * If `units` is not specified, the unit is derived from the geometry spatial reference.
   * If the geometry spatial reference is not specified, the unit is derived from the feature service data spatial reference.
   * For service-based queries, this parameter only applies if the layer's
   * [capabilities.query.supportsDistance](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-FeatureLayer.html#capabilities) is `true`.
   *
   * @example
   * // Query at a distance in pixels of the query geometry.
   * // Use the unit of the query geometry's spatial reference.
   * layerView.queryFeatures({
   *   geometry: event.mapPoint,
   *   distance: 2 * view.resolution,
   *   returnGeometry: true
   * }).then(processResults);
   */
  accessor units: "feet" | "miles" | "nautical-miles" | "us-nautical-miles" | "meters" | "kilometers" | null | undefined;
  /**
   * A where clause for the query. Any legal SQL where clause operating on the fields in the layer is allowed.
   * Be sure to have the correct sequence of single and double quotes when writing the where clause in JavaScript.
   *
   * @default "1=1"
   * @example query.where = "NAME = '" + stateName + "'";
   * @example query.where = "POP04 > " + population;
   */
  accessor where: string;
  /**
   * Creates a deep clone of TopFeaturesQuery object.
   *
   * @returns A new instance of a TopFeaturesQuery object equal to the object used to call `.clone()`.
   */
  clone(): TopFeaturesQuery;
}