import type Graphic from "../../Graphic.js";
import type SpatialReference from "../../geometry/SpatialReference.js";
import type Field from "../../layers/support/Field.js";
import type { JSONSupport } from "../../core/JSONSupport.js";
import type { GeometryType, GeometryWithoutMeshUnion } from "../../geometry/types.js";
import type { GraphicProperties } from "../../Graphic.js";
import type { FieldProperties } from "../../layers/support/Field.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";

export interface FeatureSetProperties extends Partial<Pick<FeatureSet, "displayFieldName" | "exceededTransferLimit" | "geometryType">> {
  /** The array of graphics returned from a task. */
  features?: GraphicProperties[];
  /** Information about each field. */
  fields?: FieldProperties[];
  /**
   * The [Query.geometry](https://developers.arcgis.com/javascript/latest/references/core/rest/support/Query/#geometry) used to query the features. It is useful for getting
   * the buffer geometry generated when querying features by [Query.distance](https://developers.arcgis.com/javascript/latest/references/core/rest/support/Query/#distance)
   * or getting the query geometry projected in the [Query.outSpatialReference](https://developers.arcgis.com/javascript/latest/references/core/rest/support/Query/#outSpatialReference) of the query.
   * The query geometry is returned only for [client-side queries](https://developers.arcgis.com/javascript/latest/references/core/views/layers/FeatureLayerView/#queryFeatures)
   * and [hosted feature services](https://doc.arcgis.com/en/arcgis-online/share-maps/hosted-web-layers.htm).
   * The query's [Query.returnQueryGeometry](https://developers.arcgis.com/javascript/latest/references/core/rest/support/Query/#returnQueryGeometry) must be set to `true` and
   * the layer's [capabilities.query.supportsQueryGeometry](https://developers.arcgis.com/javascript/latest/references/core/layers/FeatureLayer/#capabilities) has to be `true` for the query to return
   * query geometry.
   *
   * @see [Query.returnQueryGeometry](https://developers.arcgis.com/javascript/latest/references/core/rest/support/Query/#returnQueryGeometry)
   */
  queryGeometry?: ((ExtentProperties & { type: "extent" }) | (MultipointProperties & { type: "multipoint" }) | (PointProperties & { type: "point" }) | (PolygonProperties & { type: "polygon" }) | (PolylineProperties & { type: "polyline" })) | null;
  /**
   * When a FeatureSet is used as input to Geoprocessor, the spatial reference is set to the map's spatial reference by default.
   * This value can be changed. When a FeatureSet is returned from a task, the value is the result as returned from the server.
   */
  spatialReference?: SpatialReferenceProperties | null;
}

/**
 * A collection of features returned from ArcGIS Server or used as input to methods. Each
 * feature in the FeatureSet may contain geometry, attributes, and symbology. If the FeatureSet
 * does not contain geometry, and only contains attributes, the FeatureSet can be treated as a
 * table where each feature is a row object. Methods that return FeatureSet include [query](https://developers.arcgis.com/javascript/latest/references/core/rest/query/).
 *
 * @since 4.20
 * @see [query](https://developers.arcgis.com/javascript/latest/references/core/rest/query/)
 */
export default class FeatureSet extends JSONSupport {
  constructor(properties?: FeatureSetProperties);
  /**
   * The name of the layer's primary display field. The value of this property matches the name of one of the fields of
   * the feature. This is only applicable when the FeatureSet is returned from a task. It is ignored when the FeatureSet
   * is used as input to a geoprocessing task.
   */
  accessor displayFieldName: string;
  /**
   * Typically, a layer has a limit on the number of features (i.e., records) returned by the query operation. If `maxRecordCount`
   * is configured for a layer, `exceededTransferLimit` will be `true` if a query matches more than the `maxRecordCount`
   * features. It will be `false` otherwise. Supported by ArcGIS Server version 10.1 and later.
   *
   * @default false
   */
  accessor exceededTransferLimit: boolean;
  /** The array of graphics returned from a task. */
  get features(): Graphic[];
  set features(value: GraphicProperties[]);
  /** Information about each field. */
  get fields(): Field[];
  set fields(value: FieldProperties[]);
  /** The geometry type of features in the FeatureSet. All features's geometry must be of the same type. */
  accessor geometryType: GeometryType;
  /**
   * The [Query.geometry](https://developers.arcgis.com/javascript/latest/references/core/rest/support/Query/#geometry) used to query the features. It is useful for getting
   * the buffer geometry generated when querying features by [Query.distance](https://developers.arcgis.com/javascript/latest/references/core/rest/support/Query/#distance)
   * or getting the query geometry projected in the [Query.outSpatialReference](https://developers.arcgis.com/javascript/latest/references/core/rest/support/Query/#outSpatialReference) of the query.
   * The query geometry is returned only for [client-side queries](https://developers.arcgis.com/javascript/latest/references/core/views/layers/FeatureLayerView/#queryFeatures)
   * and [hosted feature services](https://doc.arcgis.com/en/arcgis-online/share-maps/hosted-web-layers.htm).
   * The query's [Query.returnQueryGeometry](https://developers.arcgis.com/javascript/latest/references/core/rest/support/Query/#returnQueryGeometry) must be set to `true` and
   * the layer's [capabilities.query.supportsQueryGeometry](https://developers.arcgis.com/javascript/latest/references/core/layers/FeatureLayer/#capabilities) has to be `true` for the query to return
   * query geometry.
   *
   * @see [Query.returnQueryGeometry](https://developers.arcgis.com/javascript/latest/references/core/rest/support/Query/#returnQueryGeometry)
   */
  get queryGeometry(): GeometryWithoutMeshUnion | null | undefined;
  set queryGeometry(value: ((ExtentProperties & { type: "extent" }) | (MultipointProperties & { type: "multipoint" }) | (PointProperties & { type: "point" }) | (PolygonProperties & { type: "polygon" }) | (PolylineProperties & { type: "polyline" })) | null | undefined);
  /**
   * When a FeatureSet is used as input to Geoprocessor, the spatial reference is set to the map's spatial reference by default.
   * This value can be changed. When a FeatureSet is returned from a task, the value is the result as returned from the server.
   */
  get spatialReference(): SpatialReference | null | undefined;
  set spatialReference(value: SpatialReferenceProperties | null | undefined);
}